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