/ src / common / linux / synth_elf.h
synth_elf.h
  1  // -*- mode: C++ -*-
  2  
  3  // Copyright 2011 Google LLC
  4  //
  5  // Redistribution and use in source and binary forms, with or without
  6  // modification, are permitted provided that the following conditions are
  7  // met:
  8  //
  9  //     * Redistributions of source code must retain the above copyright
 10  // notice, this list of conditions and the following disclaimer.
 11  //     * Redistributions in binary form must reproduce the above
 12  // copyright notice, this list of conditions and the following disclaimer
 13  // in the documentation and/or other materials provided with the
 14  // distribution.
 15  //     * Neither the name of Google LLC nor the names of its
 16  // contributors may be used to endorse or promote products derived from
 17  // this software without specific prior written permission.
 18  //
 19  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 20  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 21  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 22  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 23  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 24  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 25  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 26  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 27  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 28  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 29  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 30  
 31  // Original author: Ted Mielczarek <ted.mielczarek@gmail.com>
 32  
 33  // synth_elf.h: Interface to synth_elf::ELF: fake ELF generator.
 34  
 35  #ifndef COMMON_LINUX_SYNTH_ELF_H_
 36  #define COMMON_LINUX_SYNTH_ELF_H_
 37  
 38  #include "common/test_assembler.h"
 39  
 40  #include <list>
 41  #include <vector>
 42  #include <map>
 43  #include <string>
 44  #include <utility>
 45  
 46  #include "common/using_std_string.h"
 47  
 48  namespace google_breakpad {
 49  namespace synth_elf {
 50  
 51  using std::list;
 52  using std::vector;
 53  using std::map;
 54  using std::pair;
 55  using test_assembler::Endianness;
 56  using test_assembler::kLittleEndian;
 57  using test_assembler::kUnsetEndian;
 58  using test_assembler::Label;
 59  using test_assembler::Section;
 60  
 61  // String tables are common in ELF headers, so subclass Section
 62  // to make them easy to generate.
 63  class StringTable : public Section {
 64  public:
 65    StringTable(Endianness endianness = kUnsetEndian)
 66    : Section(endianness) {
 67      start() = 0;
 68      empty_string = Add("");
 69    }
 70  
 71    // Add the string s to the string table, and return
 72    // a label containing the offset into the string table
 73    // at which it was added.
 74    Label Add(const string& s) {
 75      if (strings_.find(s) != strings_.end())
 76        return strings_[s];
 77  
 78      Label string_label(Here());
 79      AppendCString(s);
 80      strings_[s] = string_label;
 81      return string_label;
 82    }
 83  
 84    // All StringTables contain an empty string as their first
 85    // entry.
 86    Label empty_string;
 87  
 88    // Avoid inserting duplicate strings.
 89    map<string,Label> strings_;
 90  };
 91  
 92  // A Section representing an entire ELF file.
 93  class ELF : public Section {
 94   public:
 95    ELF(uint16_t machine,    // EM_386, etc
 96        uint8_t file_class,  // ELFCLASS{32,64}
 97        Endianness endianness = kLittleEndian);
 98  
 99    // Add the Section section to the section header table and append it
100    // to the file. Returns the index of the section in the section
101    // header table.
102    int AddSection(const string& name, const Section& section,
103                   uint32_t type, uint32_t flags = 0, uint64_t addr = 0,
104                   uint32_t link = 0, uint64_t entsize = 0, uint64_t offset = 0);
105                    
106    // Add a segment containing from section index start to section index end.
107    // The indexes must have been gotten from AddSection.
108    void AddSegment(int start, int end, uint32_t type, uint32_t flags = 0);
109  
110    // Write out all data. GetContents may be used after this.
111    void Finish();
112  
113   private:
114    // Size of an address, in bytes.
115    const size_t addr_size_;
116  
117    // Offset to the program header table.
118    Label program_header_label_;
119    // Number of entries in the program header table.
120    int program_count_;
121    Label program_count_label_;
122    // The program header table itself.
123    Section program_header_table_;
124  
125    // Offset to the section header table.
126    Label section_header_label_;
127    // Number of entries in the section header table.
128    int section_count_;
129    Label section_count_label_;
130    // The section header table itself.
131    Section section_header_table_;
132  
133    // Index of the section header string table in the section
134    // header table.
135    Label section_header_string_index_;
136    // Section containing the names of section header table entries.
137    StringTable section_header_strings_;
138  
139    // Record of an added section
140    struct ElfSection : public Section {
141      ElfSection(const Section& section, uint32_t type, uint32_t addr,
142                 uint32_t offset, Label offset_label, uint32_t size)
143      : Section(section), type_(type), addr_(addr), offset_(offset)
144      , offset_label_(offset_label), size_(size) {
145      }
146  
147      uint32_t type_;
148      uint32_t addr_;
149      uint32_t offset_;
150      Label offset_label_;
151      uint32_t size_;
152    };
153  
154    vector<ElfSection> sections_;
155  
156    void AppendSection(ElfSection& section);
157  };
158  
159  // A class to build .symtab or .dynsym sections.
160  class SymbolTable : public Section {
161   public:
162    // table is the StringTable that contains symbol names. The caller
163    // must ensure that it remains alive for the life of the
164    // SymbolTable.
165    SymbolTable(Endianness endianness, size_t addr_size, StringTable& table);
166  
167    // Add an Elf32_Sym.
168    void AddSymbol(const string& name, uint32_t value,
169                   uint32_t size, unsigned info, uint16_t shndx);
170    // Add an Elf64_Sym.
171    void AddSymbol(const string& name, uint64_t value,
172                   uint64_t size, unsigned info, uint16_t shndx);
173  
174   private:
175  #ifndef NDEBUG
176    size_t addr_size_;
177  #endif
178    StringTable& table_;
179  };
180  
181  // A class for note sections
182  class Notes : public Section {
183  public:
184    Notes(Endianness endianness)
185    : Section(endianness) {
186    }
187  
188    // Add a note.
189    void AddNote(int type, const string& name, const uint8_t* desc_bytes,
190                 size_t desc_size);
191  };
192  
193  }  // namespace synth_elf
194  }  // namespace google_breakpad
195  
196  #endif  // COMMON_LINUX_SYNTH_ELF_H_