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 <[email protected]> 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) Section(endianness)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. Add(const string & s)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 { ElfSectionElfSection141 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: Notes(Endianness endianness)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_ 197