Home | History | Annotate | Download | only in linux
      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 (at) 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)
     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.
     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 {
    142     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 &section);
    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   size_t addr_size_;
    177   StringTable& table_;
    178 };
    179 
    180 // A class for note sections
    181 class Notes : public Section {
    182 public:
    183   Notes(Endianness endianness)
    184   : Section(endianness) {
    185   }
    186 
    187   // Add a note.
    188   void AddNote(int type, const string &name, const uint8_t* desc_bytes,
    189                size_t desc_size);
    190 };
    191 
    192 }  // namespace synth_elf
    193 }  // namespace google_breakpad
    194 
    195 #endif  // COMMON_LINUX_SYNTH_ELF_H_
    196