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