1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,195 @@ 1.4 +// -*- mode: C++ -*- 1.5 + 1.6 +// Copyright (c) 2011, Google Inc. 1.7 +// All rights reserved. 1.8 +// 1.9 +// Redistribution and use in source and binary forms, with or without 1.10 +// modification, are permitted provided that the following conditions are 1.11 +// met: 1.12 +// 1.13 +// * Redistributions of source code must retain the above copyright 1.14 +// notice, this list of conditions and the following disclaimer. 1.15 +// * Redistributions in binary form must reproduce the above 1.16 +// copyright notice, this list of conditions and the following disclaimer 1.17 +// in the documentation and/or other materials provided with the 1.18 +// distribution. 1.19 +// * Neither the name of Google Inc. nor the names of its 1.20 +// contributors may be used to endorse or promote products derived from 1.21 +// this software without specific prior written permission. 1.22 +// 1.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.26 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.27 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.28 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.29 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.30 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.31 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.32 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.33 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.34 + 1.35 +// Original author: Ted Mielczarek <ted.mielczarek@gmail.com> 1.36 + 1.37 +// synth_elf.h: Interface to synth_elf::ELF: fake ELF generator. 1.38 + 1.39 +#ifndef COMMON_LINUX_SYNTH_ELF_H_ 1.40 +#define COMMON_LINUX_SYNTH_ELF_H_ 1.41 + 1.42 +#include "common/test_assembler.h" 1.43 + 1.44 +#include <list> 1.45 +#include <vector> 1.46 +#include <map> 1.47 +#include <string> 1.48 +#include <utility> 1.49 + 1.50 +#include "common/using_std_string.h" 1.51 + 1.52 +namespace google_breakpad { 1.53 +namespace synth_elf { 1.54 + 1.55 +using std::list; 1.56 +using std::vector; 1.57 +using std::map; 1.58 +using std::pair; 1.59 +using test_assembler::Endianness; 1.60 +using test_assembler::kLittleEndian; 1.61 +using test_assembler::kUnsetEndian; 1.62 +using test_assembler::Label; 1.63 +using test_assembler::Section; 1.64 + 1.65 +// String tables are common in ELF headers, so subclass Section 1.66 +// to make them easy to generate. 1.67 +class StringTable : public Section { 1.68 +public: 1.69 + StringTable(Endianness endianness = kUnsetEndian) 1.70 + : Section(endianness) { 1.71 + start() = 0; 1.72 + empty_string = Add(""); 1.73 + } 1.74 + 1.75 + // Add the string s to the string table, and return 1.76 + // a label containing the offset into the string table 1.77 + // at which it was added. 1.78 + Label Add(const string& s) { 1.79 + if (strings_.find(s) != strings_.end()) 1.80 + return strings_[s]; 1.81 + 1.82 + Label string_label(Here()); 1.83 + AppendCString(s); 1.84 + strings_[s] = string_label; 1.85 + return string_label; 1.86 + } 1.87 + 1.88 + // All StringTables contain an empty string as their first 1.89 + // entry. 1.90 + Label empty_string; 1.91 + 1.92 + // Avoid inserting duplicate strings. 1.93 + map<string,Label> strings_; 1.94 +}; 1.95 + 1.96 +// A Section representing an entire ELF file. 1.97 +class ELF : public Section { 1.98 + public: 1.99 + ELF(uint16_t machine, // EM_386, etc 1.100 + uint8_t file_class, // ELFCLASS{32,64} 1.101 + Endianness endianness = kLittleEndian); 1.102 + 1.103 + // Add the Section section to the section header table and append it 1.104 + // to the file. Returns the index of the section in the section 1.105 + // header table. 1.106 + int AddSection(const string& name, const Section& section, 1.107 + uint32_t type, uint32_t flags = 0, uint64_t addr = 0, 1.108 + uint32_t link = 0, uint64_t entsize = 0, uint64_t offset = 0); 1.109 + 1.110 + // Add a segment containing from section index start to section index end. 1.111 + // The indexes must have been gotten from AddSection. 1.112 + void AddSegment(int start, int end, uint32_t type, uint32_t flags = 0); 1.113 + 1.114 + // Write out all data. GetContents may be used after this. 1.115 + void Finish(); 1.116 + 1.117 + private: 1.118 + // Size of an address, in bytes. 1.119 + const size_t addr_size_; 1.120 + 1.121 + // Offset to the program header table. 1.122 + Label program_header_label_; 1.123 + // Number of entries in the program header table. 1.124 + int program_count_; 1.125 + Label program_count_label_; 1.126 + // The program header table itself. 1.127 + Section program_header_table_; 1.128 + 1.129 + // Offset to the section header table. 1.130 + Label section_header_label_; 1.131 + // Number of entries in the section header table. 1.132 + int section_count_; 1.133 + Label section_count_label_; 1.134 + // The section header table itself. 1.135 + Section section_header_table_; 1.136 + 1.137 + // Index of the section header string table in the section 1.138 + // header table. 1.139 + Label section_header_string_index_; 1.140 + // Section containing the names of section header table entries. 1.141 + StringTable section_header_strings_; 1.142 + 1.143 + // Record of an added section 1.144 + struct ElfSection : public Section { 1.145 + ElfSection(const Section& section, uint32_t type, uint32_t addr, 1.146 + uint32_t offset, Label offset_label, uint32_t size) 1.147 + : Section(section), type_(type), addr_(addr), offset_(offset) 1.148 + , offset_label_(offset_label), size_(size) { 1.149 + } 1.150 + 1.151 + uint32_t type_; 1.152 + uint32_t addr_; 1.153 + uint32_t offset_; 1.154 + Label offset_label_; 1.155 + uint32_t size_; 1.156 + }; 1.157 + 1.158 + vector<ElfSection> sections_; 1.159 + 1.160 + void AppendSection(ElfSection §ion); 1.161 +}; 1.162 + 1.163 +// A class to build .symtab or .dynsym sections. 1.164 +class SymbolTable : public Section { 1.165 + public: 1.166 + // table is the StringTable that contains symbol names. The caller 1.167 + // must ensure that it remains alive for the life of the 1.168 + // SymbolTable. 1.169 + SymbolTable(Endianness endianness, size_t addr_size, StringTable& table); 1.170 + 1.171 + // Add an Elf32_Sym. 1.172 + void AddSymbol(const string& name, uint32_t value, 1.173 + uint32_t size, unsigned info, uint16_t shndx); 1.174 + // Add an Elf64_Sym. 1.175 + void AddSymbol(const string& name, uint64_t value, 1.176 + uint64_t size, unsigned info, uint16_t shndx); 1.177 + 1.178 + private: 1.179 + size_t addr_size_; 1.180 + StringTable& table_; 1.181 +}; 1.182 + 1.183 +// A class for note sections 1.184 +class Notes : public Section { 1.185 +public: 1.186 + Notes(Endianness endianness) 1.187 + : Section(endianness) { 1.188 + } 1.189 + 1.190 + // Add a note. 1.191 + void AddNote(int type, const string &name, const uint8_t* desc_bytes, 1.192 + size_t desc_size); 1.193 +}; 1.194 + 1.195 +} // namespace synth_elf 1.196 +} // namespace google_breakpad 1.197 + 1.198 +#endif // COMMON_LINUX_SYNTH_ELF_H_