1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/unix/elfhack/elfxx.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,703 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "mozilla/NullPtr.h" 1.9 + 1.10 +#include <stdexcept> 1.11 +#include <list> 1.12 +#include <vector> 1.13 +#include <cstring> 1.14 +#include <iostream> 1.15 +#include <fstream> 1.16 +#include <algorithm> 1.17 +#include <elf.h> 1.18 +#include <asm/byteorder.h> 1.19 + 1.20 +// Technically, __*_to_cpu and __cpu_to* function are equivalent, 1.21 +// so swap can use either of both. 1.22 +#define def_swap(endian, type, bits) \ 1.23 +static inline type ## bits ## _t swap(type ## bits ## _t i) { \ 1.24 + return __ ## endian ## bits ## _to_cpu(i); \ 1.25 +} 1.26 + 1.27 +class little_endian { 1.28 +public: 1.29 +def_swap(le, uint, 16); 1.30 +def_swap(le, uint, 32); 1.31 +def_swap(le, uint, 64); 1.32 +def_swap(le, int, 16); 1.33 +def_swap(le, int, 32); 1.34 +def_swap(le, int, 64); 1.35 +}; 1.36 + 1.37 +class big_endian { 1.38 +public: 1.39 +def_swap(be, uint, 16); 1.40 +def_swap(be, uint, 32); 1.41 +def_swap(be, uint, 64); 1.42 +def_swap(be, int, 16); 1.43 +def_swap(be, int, 32); 1.44 +def_swap(be, int, 64); 1.45 +}; 1.46 + 1.47 +// forward declaration 1.48 +class ElfSection; 1.49 +class ElfSegment; 1.50 +// TODO: Rename Elf_* types 1.51 +class Elf_Ehdr; 1.52 +class Elf_Phdr; 1.53 +class Elf; 1.54 +class ElfDynamic_Section; 1.55 +class ElfStrtab_Section; 1.56 + 1.57 +class Elf_Ehdr_Traits { 1.58 +public: 1.59 + typedef Elf32_Ehdr Type32; 1.60 + typedef Elf64_Ehdr Type64; 1.61 + 1.62 + template <class endian, typename R, typename T> 1.63 + static void swap(T &t, R &r); 1.64 +}; 1.65 + 1.66 +class Elf_Phdr_Traits { 1.67 +public: 1.68 + typedef Elf32_Phdr Type32; 1.69 + typedef Elf64_Phdr Type64; 1.70 + 1.71 + template <class endian, typename R, typename T> 1.72 + static void swap(T &t, R &r); 1.73 +}; 1.74 + 1.75 +class Elf_Shdr_Traits { 1.76 +public: 1.77 + typedef Elf32_Shdr Type32; 1.78 + typedef Elf64_Shdr Type64; 1.79 + 1.80 + template <class endian, typename R, typename T> 1.81 + static void swap(T &t, R &r); 1.82 +}; 1.83 + 1.84 +class Elf_Dyn_Traits { 1.85 +public: 1.86 + typedef Elf32_Dyn Type32; 1.87 + typedef Elf64_Dyn Type64; 1.88 + 1.89 + template <class endian, typename R, typename T> 1.90 + static void swap(T &t, R &r); 1.91 +}; 1.92 + 1.93 +class Elf_Sym_Traits { 1.94 +public: 1.95 + typedef Elf32_Sym Type32; 1.96 + typedef Elf64_Sym Type64; 1.97 + 1.98 + template <class endian, typename R, typename T> 1.99 + static void swap(T &t, R &r); 1.100 +}; 1.101 + 1.102 +class Elf_Rel_Traits { 1.103 +public: 1.104 + typedef Elf32_Rel Type32; 1.105 + typedef Elf64_Rel Type64; 1.106 + 1.107 + template <class endian, typename R, typename T> 1.108 + static void swap(T &t, R &r); 1.109 +}; 1.110 + 1.111 +class Elf_Rela_Traits { 1.112 +public: 1.113 + typedef Elf32_Rela Type32; 1.114 + typedef Elf64_Rela Type64; 1.115 + 1.116 + template <class endian, typename R, typename T> 1.117 + static void swap(T &t, R &r); 1.118 +}; 1.119 + 1.120 +class ElfValue { 1.121 +public: 1.122 + virtual unsigned int getValue() { return 0; } 1.123 + virtual ElfSection *getSection() { return nullptr; } 1.124 +}; 1.125 + 1.126 +class ElfPlainValue: public ElfValue { 1.127 + unsigned int value; 1.128 +public: 1.129 + ElfPlainValue(unsigned int val): value(val) {}; 1.130 + unsigned int getValue() { return value; } 1.131 +}; 1.132 + 1.133 +class ElfLocation: public ElfValue { 1.134 + ElfSection *section; 1.135 + unsigned int offset; 1.136 +public: 1.137 + enum position { ABSOLUTE, RELATIVE }; 1.138 + ElfLocation(): section(nullptr), offset(0) {}; 1.139 + ElfLocation(ElfSection *section, unsigned int off, enum position pos = RELATIVE); 1.140 + ElfLocation(unsigned int location, Elf *elf); 1.141 + unsigned int getValue(); 1.142 + ElfSection *getSection() { return section; } 1.143 + const char *getBuffer(); 1.144 +}; 1.145 + 1.146 +class ElfSize: public ElfValue { 1.147 + ElfSection *section; 1.148 +public: 1.149 + ElfSize(ElfSection *s): section(s) {}; 1.150 + unsigned int getValue(); 1.151 + ElfSection *getSection() { return section; } 1.152 +}; 1.153 + 1.154 +class ElfEntSize: public ElfValue { 1.155 + ElfSection *section; 1.156 +public: 1.157 + ElfEntSize(ElfSection *s): section(s) {}; 1.158 + unsigned int getValue(); 1.159 + ElfSection *getSection() { return section; } 1.160 +}; 1.161 + 1.162 +template <typename T> 1.163 +class serializable: public T::Type32 { 1.164 +public: 1.165 + serializable() {}; 1.166 + serializable(const typename T::Type32 &p): T::Type32(p) {}; 1.167 + 1.168 +private: 1.169 + template <typename R> 1.170 + void init(const char *buf, size_t len, char ei_data) 1.171 + { 1.172 + R e; 1.173 + assert(len >= sizeof(e)); 1.174 + memcpy(&e, buf, sizeof(e)); 1.175 + if (ei_data == ELFDATA2LSB) { 1.176 + T::template swap<little_endian>(e, *this); 1.177 + return; 1.178 + } else if (ei_data == ELFDATA2MSB) { 1.179 + T::template swap<big_endian>(e, *this); 1.180 + return; 1.181 + } 1.182 + throw std::runtime_error("Unsupported ELF data encoding"); 1.183 + } 1.184 + 1.185 + template <typename R> 1.186 + void serialize(const char *buf, size_t len, char ei_data) 1.187 + { 1.188 + assert(len >= sizeof(R)); 1.189 + if (ei_data == ELFDATA2LSB) { 1.190 + T::template swap<little_endian>(*this, *(R *)buf); 1.191 + return; 1.192 + } else if (ei_data == ELFDATA2MSB) { 1.193 + T::template swap<big_endian>(*this, *(R *)buf); 1.194 + return; 1.195 + } 1.196 + throw std::runtime_error("Unsupported ELF data encoding"); 1.197 + } 1.198 + 1.199 +public: 1.200 + serializable(const char *buf, size_t len, char ei_class, char ei_data) 1.201 + { 1.202 + if (ei_class == ELFCLASS32) { 1.203 + init<typename T::Type32>(buf, len, ei_data); 1.204 + return; 1.205 + } else if (ei_class == ELFCLASS64) { 1.206 + init<typename T::Type64>(buf, len, ei_data); 1.207 + return; 1.208 + } 1.209 + throw std::runtime_error("Unsupported ELF class"); 1.210 + } 1.211 + 1.212 + serializable(std::ifstream &file, char ei_class, char ei_data) 1.213 + { 1.214 + if (ei_class == ELFCLASS32) { 1.215 + typename T::Type32 e; 1.216 + file.read((char *)&e, sizeof(e)); 1.217 + init<typename T::Type32>((char *)&e, sizeof(e), ei_data); 1.218 + return; 1.219 + } else if (ei_class == ELFCLASS64) { 1.220 + typename T::Type64 e; 1.221 + file.read((char *)&e, sizeof(e)); 1.222 + init<typename T::Type64>((char *)&e, sizeof(e), ei_data); 1.223 + return; 1.224 + } 1.225 + throw std::runtime_error("Unsupported ELF class or data encoding"); 1.226 + } 1.227 + 1.228 + void serialize(std::ofstream &file, char ei_class, char ei_data) 1.229 + { 1.230 + if (ei_class == ELFCLASS32) { 1.231 + typename T::Type32 e; 1.232 + serialize<typename T::Type32>((char *)&e, sizeof(e), ei_data); 1.233 + file.write((char *)&e, sizeof(e)); 1.234 + return; 1.235 + } else if (ei_class == ELFCLASS64) { 1.236 + typename T::Type64 e; 1.237 + serialize<typename T::Type64>((char *)&e, sizeof(e), ei_data); 1.238 + file.write((char *)&e, sizeof(e)); 1.239 + return; 1.240 + } 1.241 + throw std::runtime_error("Unsupported ELF class or data encoding"); 1.242 + } 1.243 + 1.244 + void serialize(char *buf, size_t len, char ei_class, char ei_data) 1.245 + { 1.246 + if (ei_class == ELFCLASS32) { 1.247 + serialize<typename T::Type32>(buf, len, ei_data); 1.248 + return; 1.249 + } else if (ei_class == ELFCLASS64) { 1.250 + serialize<typename T::Type64>(buf, len, ei_data); 1.251 + return; 1.252 + } 1.253 + throw std::runtime_error("Unsupported ELF class"); 1.254 + } 1.255 + 1.256 + static inline unsigned int size(char ei_class) 1.257 + { 1.258 + if (ei_class == ELFCLASS32) 1.259 + return sizeof(typename T::Type32); 1.260 + else if (ei_class == ELFCLASS64) 1.261 + return sizeof(typename T::Type64); 1.262 + return 0; 1.263 + } 1.264 +}; 1.265 + 1.266 +typedef serializable<Elf_Shdr_Traits> Elf_Shdr; 1.267 + 1.268 +class Elf { 1.269 +public: 1.270 + Elf(std::ifstream &file); 1.271 + ~Elf(); 1.272 + 1.273 + /* index == -1 is treated as index == ehdr.e_shstrndx */ 1.274 + ElfSection *getSection(int index); 1.275 + 1.276 + ElfSection *getSectionAt(unsigned int offset); 1.277 + 1.278 + ElfSegment *getSegmentByType(unsigned int type, ElfSegment *last = nullptr); 1.279 + 1.280 + ElfDynamic_Section *getDynSection(); 1.281 + 1.282 + void normalize(); 1.283 + void write(std::ofstream &file); 1.284 + 1.285 + char getClass(); 1.286 + char getData(); 1.287 + char getType(); 1.288 + char getMachine(); 1.289 + unsigned int getSize(); 1.290 + 1.291 + void insertSegmentAfter(ElfSegment *previous, ElfSegment *segment) { 1.292 + std::vector<ElfSegment *>::iterator prev = std::find(segments.begin(), segments.end(), previous); 1.293 + segments.insert(prev + 1, segment); 1.294 + } 1.295 + 1.296 + void removeSegment(ElfSegment *segment); 1.297 + 1.298 +private: 1.299 + Elf_Ehdr *ehdr; 1.300 + ElfLocation eh_entry; 1.301 + ElfStrtab_Section *eh_shstrndx; 1.302 + ElfSection **sections; 1.303 + std::vector<ElfSegment *> segments; 1.304 + ElfSection *shdr_section, *phdr_section; 1.305 + /* Values used only during initialization */ 1.306 + Elf_Shdr **tmp_shdr; 1.307 + std::ifstream *tmp_file; 1.308 +}; 1.309 + 1.310 +class ElfSection { 1.311 +public: 1.312 + typedef union { 1.313 + ElfSection *section; 1.314 + int index; 1.315 + } SectionInfo; 1.316 + 1.317 + ElfSection(Elf_Shdr &s, std::ifstream *file, Elf *parent); 1.318 + 1.319 + virtual ~ElfSection() { 1.320 + delete[] data; 1.321 + } 1.322 + 1.323 + const char *getName() { return name; } 1.324 + unsigned int getType() { return shdr.sh_type; } 1.325 + unsigned int getFlags() { return shdr.sh_flags; } 1.326 + unsigned int getAddr(); 1.327 + unsigned int getSize() { return shdr.sh_size; } 1.328 + unsigned int getAddrAlign() { return shdr.sh_addralign; } 1.329 + unsigned int getEntSize() { return shdr.sh_entsize; } 1.330 + const char *getData() { return data; } 1.331 + ElfSection *getLink() { return link; } 1.332 + SectionInfo getInfo() { return info; } 1.333 + 1.334 + void shrink(unsigned int newsize) { 1.335 + if (newsize < shdr.sh_size) 1.336 + shdr.sh_size = newsize; 1.337 + } 1.338 + 1.339 + unsigned int getOffset(); 1.340 + int getIndex(); 1.341 + Elf_Shdr &getShdr(); 1.342 + 1.343 + ElfSection *getNext() { return next; } 1.344 + ElfSection *getPrevious() { return previous; } 1.345 + 1.346 + virtual bool isRelocatable() { 1.347 + return ((getType() == SHT_SYMTAB) || 1.348 + (getType() == SHT_STRTAB) || 1.349 + (getType() == SHT_RELA) || 1.350 + (getType() == SHT_HASH) || 1.351 + (getType() == SHT_NOTE) || 1.352 + (getType() == SHT_REL) || 1.353 + (getType() == SHT_DYNSYM) || 1.354 + (getType() == SHT_GNU_HASH) || 1.355 + (getType() == SHT_GNU_verdef) || 1.356 + (getType() == SHT_GNU_verneed) || 1.357 + (getType() == SHT_GNU_versym) || 1.358 + getSegmentByType(PT_INTERP)) && 1.359 + (getFlags() & SHF_ALLOC); 1.360 + } 1.361 + 1.362 + void insertAfter(ElfSection *section, bool dirty = true) { 1.363 + if (previous != nullptr) 1.364 + previous->next = next; 1.365 + if (next != nullptr) 1.366 + next->previous = previous; 1.367 + previous = section; 1.368 + if (section != nullptr) { 1.369 + next = section->next; 1.370 + section->next = this; 1.371 + } else 1.372 + next = nullptr; 1.373 + if (next != nullptr) 1.374 + next->previous = this; 1.375 + if (dirty) 1.376 + markDirty(); 1.377 + insertInSegments(section->segments); 1.378 + } 1.379 + 1.380 + void insertBefore(ElfSection *section, bool dirty = true) { 1.381 + if (previous != nullptr) 1.382 + previous->next = next; 1.383 + if (next != nullptr) 1.384 + next->previous = previous; 1.385 + next = section; 1.386 + if (section != nullptr) { 1.387 + previous = section->previous; 1.388 + section->previous = this; 1.389 + } else 1.390 + previous = nullptr; 1.391 + if (previous != nullptr) 1.392 + previous->next = this; 1.393 + if (dirty) 1.394 + markDirty(); 1.395 + insertInSegments(section->segments); 1.396 + } 1.397 + 1.398 + void markDirty() { 1.399 + if (link != nullptr) 1.400 + shdr.sh_link = -1; 1.401 + if (info.index) 1.402 + shdr.sh_info = -1; 1.403 + shdr.sh_offset = -1; 1.404 + if (isRelocatable()) 1.405 + shdr.sh_addr = -1; 1.406 + if (next) 1.407 + next->markDirty(); 1.408 + } 1.409 + 1.410 + virtual void serialize(std::ofstream &file, char ei_class, char ei_data) 1.411 + { 1.412 + if (getType() == SHT_NOBITS) 1.413 + return; 1.414 + file.seekp(getOffset()); 1.415 + file.write(data, getSize()); 1.416 + } 1.417 + 1.418 +private: 1.419 + friend class ElfSegment; 1.420 + 1.421 + void addToSegment(ElfSegment *segment) { 1.422 + segments.push_back(segment); 1.423 + } 1.424 + 1.425 + void removeFromSegment(ElfSegment *segment) { 1.426 + std::vector<ElfSegment *>::iterator i = std::find(segments.begin(), segments.end(), segment); 1.427 + segments.erase(i, i + 1); 1.428 + } 1.429 + 1.430 + ElfSegment *getSegmentByType(unsigned int type); 1.431 + 1.432 + void insertInSegments(std::vector<ElfSegment *> &segs); 1.433 + 1.434 +protected: 1.435 + Elf_Shdr shdr; 1.436 + char *data; 1.437 + const char *name; 1.438 +private: 1.439 + ElfSection *link; 1.440 + SectionInfo info; 1.441 + ElfSection *next, *previous; 1.442 + int index; 1.443 + std::vector<ElfSegment *> segments; 1.444 +}; 1.445 + 1.446 +class ElfSegment { 1.447 +public: 1.448 + ElfSegment(Elf_Phdr *phdr); 1.449 + 1.450 + unsigned int getType() { return type; } 1.451 + unsigned int getFlags() { return flags; } 1.452 + unsigned int getAlign() { return align; } 1.453 + 1.454 + ElfSection *getFirstSection() { return sections.empty() ? nullptr : sections.front(); } 1.455 + int getVPDiff() { return v_p_diff; } 1.456 + unsigned int getFileSize(); 1.457 + unsigned int getMemSize(); 1.458 + unsigned int getOffset(); 1.459 + unsigned int getAddr(); 1.460 + 1.461 + void addSection(ElfSection *section); 1.462 + void removeSection(ElfSection *section); 1.463 + 1.464 + std::list<ElfSection *>::iterator begin() { return sections.begin(); } 1.465 + std::list<ElfSection *>::iterator end() { return sections.end(); } 1.466 + 1.467 + void clear(); 1.468 + 1.469 + bool isElfHackFillerSegment() { 1.470 + return type == PT_LOAD && flags == 0; 1.471 + } 1.472 +private: 1.473 + unsigned int type; 1.474 + int v_p_diff; // Difference between physical and virtual address 1.475 + unsigned int flags; 1.476 + unsigned int align; 1.477 + std::list<ElfSection *> sections; 1.478 + // The following are only really used for PT_GNU_RELRO until something 1.479 + // better is found. 1.480 + unsigned int vaddr; 1.481 + unsigned int filesz, memsz; 1.482 +}; 1.483 + 1.484 +class Elf_Ehdr: public serializable<Elf_Ehdr_Traits>, public ElfSection { 1.485 +public: 1.486 + Elf_Ehdr(std::ifstream &file, char ei_class, char ei_data); 1.487 + void serialize(std::ofstream &file, char ei_class, char ei_data) 1.488 + { 1.489 + serializable<Elf_Ehdr_Traits>::serialize(file, ei_class, ei_data); 1.490 + } 1.491 +}; 1.492 + 1.493 +class Elf_Phdr: public serializable<Elf_Phdr_Traits> { 1.494 +public: 1.495 + Elf_Phdr() {}; 1.496 + Elf_Phdr(std::ifstream &file, char ei_class, char ei_data) 1.497 + : serializable<Elf_Phdr_Traits>(file, ei_class, ei_data) {}; 1.498 + bool contains(ElfSection *section) 1.499 + { 1.500 + unsigned int size = section->getSize(); 1.501 + unsigned int addr = section->getAddr(); 1.502 + // This may be biased, but should work in most cases 1.503 + if ((section->getFlags() & SHF_ALLOC) == 0) 1.504 + return false; 1.505 + // Special case for PT_DYNAMIC. Eventually, this should 1.506 + // be better handled than special cases 1.507 + if ((p_type == PT_DYNAMIC) && (section->getType() != SHT_DYNAMIC)) 1.508 + return false; 1.509 + // Special case for PT_TLS. 1.510 + if ((p_type == PT_TLS) && !(section->getFlags() & SHF_TLS)) 1.511 + return false; 1.512 + return (addr >= p_vaddr) && 1.513 + (addr + size <= p_vaddr + p_memsz); 1.514 + 1.515 + } 1.516 +}; 1.517 + 1.518 +typedef serializable<Elf_Dyn_Traits> Elf_Dyn; 1.519 + 1.520 +struct Elf_DynValue { 1.521 + unsigned int tag; 1.522 + ElfValue *value; 1.523 +}; 1.524 + 1.525 +class ElfDynamic_Section: public ElfSection { 1.526 +public: 1.527 + ElfDynamic_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent); 1.528 + ~ElfDynamic_Section(); 1.529 + 1.530 + void serialize(std::ofstream &file, char ei_class, char ei_data); 1.531 + 1.532 + ElfValue *getValueForType(unsigned int tag); 1.533 + ElfSection *getSectionForType(unsigned int tag); 1.534 + bool setValueForType(unsigned int tag, ElfValue *val); 1.535 +private: 1.536 + std::vector<Elf_DynValue> dyns; 1.537 +}; 1.538 + 1.539 +typedef serializable<Elf_Sym_Traits> Elf_Sym; 1.540 + 1.541 +struct Elf_SymValue { 1.542 + const char *name; 1.543 + unsigned char info; 1.544 + unsigned char other; 1.545 + ElfLocation value; 1.546 + unsigned int size; 1.547 + bool defined; 1.548 +}; 1.549 + 1.550 +#define STT(type) (1 << STT_ ##type) 1.551 + 1.552 +class ElfSymtab_Section: public ElfSection { 1.553 +public: 1.554 + ElfSymtab_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent); 1.555 + 1.556 + void serialize(std::ofstream &file, char ei_class, char ei_data); 1.557 + 1.558 + Elf_SymValue *lookup(const char *name, unsigned int type_filter = STT(OBJECT) | STT(FUNC)); 1.559 + 1.560 +//private: // Until we have a real API 1.561 + std::vector<Elf_SymValue> syms; 1.562 +}; 1.563 + 1.564 +class Elf_Rel: public serializable<Elf_Rel_Traits> { 1.565 +public: 1.566 + Elf_Rel(std::ifstream &file, char ei_class, char ei_data) 1.567 + : serializable<Elf_Rel_Traits>(file, ei_class, ei_data) {}; 1.568 + 1.569 + static const unsigned int sh_type = SHT_REL; 1.570 + static const unsigned int d_tag = DT_REL; 1.571 + static const unsigned int d_tag_count = DT_RELCOUNT; 1.572 +}; 1.573 + 1.574 +class Elf_Rela: public serializable<Elf_Rela_Traits> { 1.575 +public: 1.576 + Elf_Rela(std::ifstream &file, char ei_class, char ei_data) 1.577 + : serializable<Elf_Rela_Traits>(file, ei_class, ei_data) {}; 1.578 + 1.579 + static const unsigned int sh_type = SHT_RELA; 1.580 + static const unsigned int d_tag = DT_RELA; 1.581 + static const unsigned int d_tag_count = DT_RELACOUNT; 1.582 +}; 1.583 + 1.584 +template <class Rel> 1.585 +class ElfRel_Section: public ElfSection { 1.586 +public: 1.587 + ElfRel_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent) 1.588 + : ElfSection(s, file, parent) 1.589 + { 1.590 + int pos = file->tellg(); 1.591 + file->seekg(shdr.sh_offset); 1.592 + for (unsigned int i = 0; i < s.sh_size / s.sh_entsize; i++) { 1.593 + Rel r(*file, parent->getClass(), parent->getData()); 1.594 + rels.push_back(r); 1.595 + } 1.596 + file->seekg(pos); 1.597 + } 1.598 + 1.599 + void serialize(std::ofstream &file, char ei_class, char ei_data) 1.600 + { 1.601 + for (typename std::vector<Rel>::iterator i = rels.begin(); 1.602 + i != rels.end(); ++i) 1.603 + (*i).serialize(file, ei_class, ei_data); 1.604 + } 1.605 +//private: // Until we have a real API 1.606 + std::vector<Rel> rels; 1.607 +}; 1.608 + 1.609 +class ElfStrtab_Section: public ElfSection { 1.610 +public: 1.611 + ElfStrtab_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent) 1.612 + : ElfSection(s, file, parent) 1.613 + { 1.614 + table.push_back(table_storage(data, shdr.sh_size)); 1.615 + } 1.616 + 1.617 + ~ElfStrtab_Section() 1.618 + { 1.619 + for (std::vector<table_storage>::iterator t = table.begin() + 1; 1.620 + t != table.end(); t++) 1.621 + delete[] t->buf; 1.622 + } 1.623 + 1.624 + const char *getStr(unsigned int index); 1.625 + 1.626 + const char *getStr(const char *string); 1.627 + 1.628 + unsigned int getStrIndex(const char *string); 1.629 + 1.630 + void serialize(std::ofstream &file, char ei_class, char ei_data); 1.631 +private: 1.632 + struct table_storage { 1.633 + unsigned int size, used; 1.634 + char *buf; 1.635 + 1.636 + table_storage(): size(4096), used(0), buf(new char[4096]) {} 1.637 + table_storage(const char *data, unsigned int sz) 1.638 + : size(sz), used(sz), buf(const_cast<char *>(data)) {} 1.639 + }; 1.640 + std::vector<table_storage> table; 1.641 +}; 1.642 + 1.643 +inline char Elf::getClass() { 1.644 + return ehdr->e_ident[EI_CLASS]; 1.645 +} 1.646 + 1.647 +inline char Elf::getData() { 1.648 + return ehdr->e_ident[EI_DATA]; 1.649 +} 1.650 + 1.651 +inline char Elf::getType() { 1.652 + return ehdr->e_type; 1.653 +} 1.654 + 1.655 +inline char Elf::getMachine() { 1.656 + return ehdr->e_machine; 1.657 +} 1.658 + 1.659 +inline unsigned int Elf::getSize() { 1.660 + ElfSection *section; 1.661 + for (section = shdr_section /* It's usually not far from the end */; 1.662 + section->getNext() != nullptr; section = section->getNext()); 1.663 + return section->getOffset() + section->getSize(); 1.664 +} 1.665 + 1.666 +inline ElfSegment *ElfSection::getSegmentByType(unsigned int type) { 1.667 + for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++) 1.668 + if ((*seg)->getType() == type) 1.669 + return *seg; 1.670 + return nullptr; 1.671 +} 1.672 + 1.673 +inline void ElfSection::insertInSegments(std::vector<ElfSegment *> &segs) { 1.674 + for (std::vector<ElfSegment *>::iterator it = segs.begin(); it != segs.end(); ++it) { 1.675 + (*it)->addSection(this); 1.676 + } 1.677 +} 1.678 + 1.679 +inline ElfLocation::ElfLocation(ElfSection *section, unsigned int off, enum position pos) 1.680 +: section(section) { 1.681 + if ((pos == ABSOLUTE) && section) 1.682 + offset = off - section->getAddr(); 1.683 + else 1.684 + offset = off; 1.685 +} 1.686 + 1.687 +inline ElfLocation::ElfLocation(unsigned int location, Elf *elf) { 1.688 + section = elf->getSectionAt(location); 1.689 + offset = location - (section ? section->getAddr() : 0); 1.690 +} 1.691 + 1.692 +inline unsigned int ElfLocation::getValue() { 1.693 + return (section ? section->getAddr() : 0) + offset; 1.694 +} 1.695 + 1.696 +inline const char *ElfLocation::getBuffer() { 1.697 + return section ? section->getData() + offset : nullptr; 1.698 +} 1.699 + 1.700 +inline unsigned int ElfSize::getValue() { 1.701 + return section->getSize(); 1.702 +} 1.703 + 1.704 +inline unsigned int ElfEntSize::getValue() { 1.705 + return section->getEntSize(); 1.706 +}