LCOV - app.info - build/unix/elfhack/elfxx.h

LCOV - code coverage report
| Current view: | directory - build/unix/elfhack - elfxx.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 256 | 187 | 73.0 %
| Date: | 2012-04-07 | Functions: | 123 | 95 | 77.2 %

           1                 : /* ***** BEGIN LICENSE BLOCK *****
           2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           3                 :  *
           4                 :  * The contents of this file are subject to the Mozilla Public License Version
           5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           6                 :  * the License. You may obtain a copy of the License at
           7                 :  * http://www.mozilla.org/MPL/
           8                 :  *
           9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          11                 :  * for the specific language governing rights and limitations under the
          12                 :  * License.
          13                 :  *
          14                 :  * The Original Code is elfhack.
          15                 :  *
          16                 :  * The Initial Developer of the Original Code is
          17                 :  * Mozilla Foundation.
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2010
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *   Mike Hommey <mh@glandium.org>
          23                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : #include <stdexcept>
          39                 : #include <list>
          40                 : #include <vector>
          41                 : #include <cstring>
          42                 : #include <iostream>
          43                 : #include <fstream>
          44                 : #include <algorithm>
          45                 : #include <elf.h>
          46                 : #include <asm/byteorder.h>
          47                 :
          48                 : // Technically, __*_to_cpu and __cpu_to* function are equivalent,
          49                 : // so swap can use either of both.
          50                 : #define def_swap(endian, type, bits) \
          51                 : static inline type ## bits ## _t swap(type ## bits ## _t i) { \
          52                 :     return __ ## endian ## bits ## _to_cpu(i); \
          53                 : }
          54                 :
          55                 : class little_endian {
          56                 : public:
          57          808601 : def_swap(le, uint, 16);
          58         3216838 : def_swap(le, uint, 32);
          59               0 : def_swap(le, uint, 64);
          60                 : def_swap(le, int, 16);
          61             895 : def_swap(le, int, 32);
          62               0 : def_swap(le, int, 64);
          63                 : };
          64                 :
          65                 : class big_endian {
          66                 : public:
          67               0 : def_swap(be, uint, 16);
          68               0 : def_swap(be, uint, 32);
          69               0 : def_swap(be, uint, 64);
          70                 : def_swap(be, int, 16);
          71               0 : def_swap(be, int, 32);
          72               0 : def_swap(be, int, 64);
          73                 : };
          74                 :
          75                 : // forward declaration
          76                 : class ElfSection;
          77                 : class ElfSegment;
          78                 : // TODO: Rename Elf_* types
          79                 : class Elf_Ehdr;
          80                 : class Elf_Phdr;
          81                 : class Elf;
          82                 : class ElfDynamic_Section;
          83                 : class ElfStrtab_Section;
          84                 :
          85                 : class Elf_Ehdr_Traits {
          86                 : public:
          87                 :     typedef Elf32_Ehdr Type32;
          88                 :     typedef Elf64_Ehdr Type64;
          89                 :
          90                 :     template <class endian, typename R, typename T>
          91                 :     static void swap(T &t, R &r);
          92                 : };
          93                 :
          94                 : class Elf_Phdr_Traits {
          95                 : public:
          96                 :     typedef Elf32_Phdr Type32;
          97                 :     typedef Elf64_Phdr Type64;
          98                 :
          99                 :     template <class endian, typename R, typename T>
         100                 :     static void swap(T &t, R &r);
         101                 : };
         102                 :
         103                 : class Elf_Shdr_Traits {
         104                 : public:
         105                 :     typedef Elf32_Shdr Type32;
         106                 :     typedef Elf64_Shdr Type64;
         107                 :
         108                 :     template <class endian, typename R, typename T>
         109                 :     static void swap(T &t, R &r);
         110                 : };
         111                 :
         112                 : class Elf_Dyn_Traits {
         113                 : public:
         114                 :     typedef Elf32_Dyn Type32;
         115                 :     typedef Elf64_Dyn Type64;
         116                 :
         117                 :     template <class endian, typename R, typename T>
         118                 :     static void swap(T &t, R &r);
         119                 : };
         120                 :
         121                 : class Elf_Sym_Traits {
         122                 : public:
         123                 :     typedef Elf32_Sym Type32;
         124                 :     typedef Elf64_Sym Type64;
         125                 :
         126                 :     template <class endian, typename R, typename T>
         127                 :     static void swap(T &t, R &r);
         128                 : };
         129                 :
         130                 : class Elf_Rel_Traits {
         131                 : public:
         132                 :     typedef Elf32_Rel Type32;
         133                 :     typedef Elf64_Rel Type64;
         134                 :
         135                 :     template <class endian, typename R, typename T>
         136                 :     static void swap(T &t, R &r);
         137                 : };
         138                 :
         139                 : class Elf_Rela_Traits {
         140                 : public:
         141                 :     typedef Elf32_Rela Type32;
         142                 :     typedef Elf64_Rela Type64;
         143                 :
         144                 :     template <class endian, typename R, typename T>
         145                 :     static void swap(T &t, R &r);
         146                 : };
         147                 :
         148          833108 : class ElfValue {
         149                 : public:
         150              20 :     virtual unsigned int getValue() { return 0; }
         151               0 :     virtual ElfSection *getSection() { return NULL; }
         152                 : };
         153                 :
         154                 : class ElfPlainValue: public ElfValue {
         155                 :     unsigned int value;
         156                 : public:
         157             338 :     ElfPlainValue(unsigned int val): value(val) {};
         158              65 :     unsigned int getValue() { return value; }
         159                 : };
         160                 :
         161          416095 : class ElfLocation: public ElfValue {
         162                 :     ElfSection *section;
         163                 :     unsigned int offset;
         164                 : public:
         165                 :     enum position { ABSOLUTE, RELATIVE };
         166             105 :     ElfLocation(): section(NULL), offset(0) {};
         167                 :     ElfLocation(ElfSection *section, unsigned int off, enum position pos = RELATIVE);
         168                 :     ElfLocation(unsigned int location, Elf *elf);
         169                 :     unsigned int getValue();
         170          392334 :     ElfSection *getSection() { return section; }
         171                 : };
         172                 :
         173                 : class ElfSize: public ElfValue {
         174                 :     ElfSection *section;
         175                 : public:
         176              63 :     ElfSize(ElfSection *s): section(s) {};
         177                 :     unsigned int getValue();
         178               0 :     ElfSection *getSection() { return section; }
         179                 : };
         180                 :
         181                 : class ElfEntSize: public ElfValue {
         182                 :     ElfSection *section;
         183                 : public:
         184              42 :     ElfEntSize(ElfSection *s): section(s) {};
         185                 :     unsigned int getValue();
         186               0 :     ElfSection *getSection() { return section; }
         187                 : };
         188                 :
         189                 : template <typename T>
         190               0 : class serializable: public T::Type32 {
         191                 : public:
         192          392375 :     serializable() {};
         193              44 :     serializable(const typename T::Type32 &p): T::Type32(p) {};
         194                 :
         195                 : private:
         196                 :     template <typename R>
         197               0 :     void init(const char *buf, size_t len, char ei_data)
         198                 :     {
         199                 :         R e;
         200               0 :         assert(len <= sizeof(e));
         201               0 :         memcpy(&e, buf, sizeof(e));
         202               0 :         if (ei_data == ELFDATA2LSB) {
         203               0 :             T::template swap<little_endian>(e, *this);
         204               0 :             return;
         205               0 :         } else if (ei_data == ELFDATA2MSB) {
         206               0 :             T::template swap<big_endian>(e, *this);
         207               0 :             return;
         208                 :         }
         209               0 :         throw std::runtime_error("Unsupported ELF data encoding");
         210                 :     }
         211                 :
         212                 : public:
         213               0 :     serializable(const char *buf, size_t len, char ei_class, char ei_data)
         214               0 :     {
         215               0 :         if (ei_class == ELFCLASS32) {
         216               0 :             init<typename T::Type32>(buf, len, ei_data);
         217               0 :             return;
         218               0 :         } else if (ei_class == ELFCLASS64) {
         219               0 :             init<typename T::Type64>(buf, len, ei_data);
         220               0 :             return;
         221                 :         }
         222               0 :         throw std::runtime_error("Unsupported ELF class");
         223                 :     }
         224                 :
         225          755138 :     serializable(std::ifstream &file, char ei_class, char ei_data)
         226          755138 :     {
         227          755138 :         if (ei_class == ELFCLASS32) {
         228                 :             typename T::Type32 e;
         229          755138 :             file.read((char *)&e, sizeof(e));
         230          755138 :             if (ei_data == ELFDATA2LSB) {
         231          755138 :                 T::template swap<little_endian>(e, *this);
         232          755138 :                 return;
         233               0 :             } else if (ei_data == ELFDATA2MSB) {
         234               0 :                 T::template swap<big_endian>(e, *this);
         235               0 :                 return;
         236                 :             }
         237               0 :         } else if (ei_class == ELFCLASS64) {
         238                 :             typename T::Type64 e;
         239               0 :             file.read((char *)&e, sizeof(e));
         240               0 :             if (ei_data == ELFDATA2LSB) {
         241               0 :                 T::template swap<little_endian>(e, *this);
         242               0 :                 return;
         243               0 :             } else if (ei_data == ELFDATA2MSB) {
         244               0 :                 T::template swap<big_endian>(e, *this);
         245               0 :                 return;
         246                 :             }
         247                 :         }
         248               0 :         throw std::runtime_error("Unsupported ELF class or data encoding");
         249                 :     }
         250                 :
         251          444482 :     void serialize(std::ofstream &file, char ei_class, char ei_data)
         252                 :     {
         253          444482 :         if (ei_class == ELFCLASS32) {
         254                 :             typename T::Type32 e;
         255          444482 :             if (ei_data == ELFDATA2LSB) {
         256          444482 :                 T::template swap<little_endian>(*this, e);
         257          444482 :                 file.write((char *)&e, sizeof(e));
         258          444482 :                 return;
         259               0 :             } else if (ei_data == ELFDATA2MSB) {
         260               0 :                 T::template swap<big_endian>(*this, e);
         261               0 :                 file.write((char *)&e, sizeof(e));
         262               0 :                 return;
         263                 :             }
         264               0 :         } else if (ei_class == ELFCLASS64) {
         265                 :             typename T::Type64 e;
         266               0 :             if (ei_data == ELFDATA2LSB) {
         267               0 :                 T::template swap<little_endian>(*this, e);
         268               0 :                 file.write((char *)&e, sizeof(e));
         269               0 :                 return;
         270               0 :             } else if (ei_data == ELFDATA2MSB) {
         271               0 :                 T::template swap<big_endian>(*this, e);
         272               0 :                 file.write((char *)&e, sizeof(e));
         273               0 :                 return;
         274                 :             }
         275                 :         }
         276               0 :         throw std::runtime_error("Unsupported ELF class or data encoding");
         277                 :     }
         278                 :
         279             281 :     static inline unsigned int size(char ei_class)
         280                 :     {
         281             281 :         if (ei_class == ELFCLASS32)
         282             281 :             return sizeof(typename T::Type32);
         283               0 :         else if (ei_class == ELFCLASS64)
         284               0 :             return sizeof(typename T::Type64);
         285               0 :         return 0;
         286                 :     }
         287                 : };
         288                 :
         289                 : typedef serializable<Elf_Shdr_Traits> Elf_Shdr;
         290                 :
         291                 : class Elf {
         292                 : public:
         293                 :     Elf(std::ifstream &file);
         294                 :     ~Elf();
         295                 :
         296                 :     /* index == -1 is treated as index == ehdr.e_shstrndx */
         297                 :     ElfSection *getSection(int index);
         298                 :
         299                 :     ElfSection *getSectionAt(unsigned int offset);
         300                 :
         301                 :     ElfSegment *getSegmentByType(unsigned int type);
         302                 :
         303                 :     ElfDynamic_Section *getDynSection();
         304                 :
         305                 :     void write(std::ofstream &file);
         306                 :
         307                 :     char getClass();
         308                 :     char getData();
         309                 :     char getType();
         310                 :     char getMachine();
         311                 :     unsigned int getSize();
         312                 : private:
         313                 :     Elf_Ehdr *ehdr;
         314                 :     ElfLocation eh_entry;
         315                 :     ElfStrtab_Section *eh_shstrndx;
         316                 :     ElfSection **sections;
         317                 :     std::vector<ElfSegment *> segments;
         318                 :     ElfSection *shdr_section, *phdr_section;
         319                 :     /* Values used only during initialization */
         320                 :     Elf_Shdr **tmp_shdr;
         321                 :     std::ifstream *tmp_file;
         322                 : };
         323                 :
         324                 : class ElfSection {
         325                 : public:
         326                 :     typedef union {
         327                 :         ElfSection *section;
         328                 :         int index;
         329                 :     } SectionInfo;
         330                 :
         331                 :     ElfSection(Elf_Shdr &s, std::ifstream *file, Elf *parent);
         332                 :
         333            3126 :     virtual ~ElfSection() {
         334            1154 :         delete[] data;
         335            1972 :     }
         336                 :
         337            1678 :     const char *getName() { return name; }
         338           28268 :     unsigned int getType() { return shdr.sh_type; }
         339        13362444 :     unsigned int getFlags() { return shdr.sh_flags; }
         340                 :     unsigned int getAddr();
         341         6230534 :     unsigned int getSize() { return shdr.sh_size; }
         342            1141 :     unsigned int getAddrAlign() { return shdr.sh_addralign; }
         343              33 :     unsigned int getEntSize() { return shdr.sh_entsize; }
         344           34552 :     const char *getData() { return data; }
         345             184 :     ElfSection *getLink() { return link; }
         346              36 :     SectionInfo getInfo() { return info; }
         347                 :
         348              21 :     void shrink(unsigned int newsize) {
         349              21 :         if (newsize < shdr.sh_size) {
         350              21 :             shdr.sh_size = newsize;
         351              21 :             if (next)
         352              21 :                 next->markDirty();
         353                 :         }
         354              21 :     }
         355                 :
         356                 :     unsigned int getOffset();
         357                 :     int getIndex();
         358                 :     Elf_Shdr &getShdr();
         359                 :
         360            2929 :     ElfSection *getNext() { return next; }
         361            1069 :     ElfSection *getPrevious() { return previous; }
         362                 :
         363            2326 :     virtual bool isRelocatable() {
         364            2326 :         return ((getType() == SHT_SYMTAB) ||
         365            2247 :                 (getType() == SHT_STRTAB) ||
         366            2073 :                 (getType() == SHT_RELA) ||
         367            2073 :                 (getType() == SHT_HASH) ||
         368            2057 :                 (getType() == SHT_NOTE) ||
         369            2057 :                 (getType() == SHT_REL) ||
         370            1944 :                 (getType() == SHT_DYNSYM) ||
         371            1928 :                 (getType() == SHT_GNU_HASH) ||
         372            1928 :                 (getType() == SHT_GNU_verdef) ||
         373            1928 :                 (getType() == SHT_GNU_verneed) ||
         374            1912 :                 (getType() == SHT_GNU_versym) ||
         375            1896 :                 isInSegmentType(PT_INTERP)) &&
         376           24369 :                 (getFlags() & SHF_ALLOC);
         377                 :     }
         378                 :
         379            1112 :     void insertAfter(ElfSection *section, bool dirty = true) {
         380            1112 :         if (previous != NULL)
         381               0 :             previous->next = next;
         382            1112 :         if (next != NULL)
         383               0 :             next->previous = previous;
         384            1112 :         previous = section;
         385            1112 :         if (section != NULL) {
         386            1112 :             next = section->next;
         387            1112 :             section->next = this;
         388                 :         } else
         389               0 :             next = NULL;
         390            1112 :         if (next != NULL)
         391              42 :             next->previous = this;
         392            1112 :         if (dirty)
         393              42 :             markDirty();
         394            1112 :     }
         395                 :
         396            2352 :     void markDirty() {
         397            2352 :         if (link != NULL)
         398             261 :             shdr.sh_link = -1;
         399            2352 :         if (info.index)
         400             166 :             shdr.sh_info = -1;
         401            2352 :         shdr.sh_offset = -1;
         402            2352 :         if (isRelocatable())
         403             219 :             shdr.sh_addr = -1;
         404            2352 :         if (next)
         405            2273 :             next->markDirty();
         406            2352 :     }
         407                 :
         408             111 :     virtual void serialize(std::ofstream &file, char ei_class, char ei_data)
         409                 :     {
         410             111 :         if (getType() == SHT_NOBITS)
         411               6 :             return;
         412             105 :         file.seekp(getOffset());
         413             105 :         file.write(data, getSize());
         414                 :     }
         415                 :
         416                 : private:
         417                 :     friend class ElfSegment;
         418                 :
         419             569 :     void addToSegment(ElfSegment *segment) {
         420             569 :         segments.push_back(segment);
         421             569 :     }
         422                 :
         423              28 :     void removeFromSegment(ElfSegment *segment) {
         424              28 :         std::vector<ElfSegment *>::iterator i = std::find(segments.begin(), segments.end(), segment);
         425              28 :         segments.erase(i, i + 1);
         426              28 :     }
         427                 :
         428                 :     bool isInSegmentType(unsigned int type);
         429                 : protected:
         430                 :     Elf_Shdr shdr;
         431                 :     char *data;
         432                 :     const char *name;
         433                 : private:
         434                 :     ElfSection *link;
         435                 :     SectionInfo info;
         436                 :     ElfSection *next, *previous;
         437                 :     int index;
         438                 :     std::vector<ElfSegment *> segments;
         439                 : };
         440                 :
         441              94 : class ElfSegment {
         442                 : public:
         443                 :     ElfSegment(Elf_Phdr *phdr);
         444                 :
         445            1452 :     unsigned int getType() { return type; }
         446              25 :     unsigned int getFlags() { return flags; }
         447             547 :     unsigned int getAlign() { return align; }
         448                 :
         449             126 :     ElfSection *getFirstSection() { return sections.empty() ? NULL : sections.front(); }
         450              25 :     int getVPDiff() { return v_p_diff; }
         451                 :     unsigned int getFileSize();
         452                 :     unsigned int getMemSize();
         453                 :     unsigned int getOffset();
         454                 :     unsigned int getAddr();
         455                 :
         456                 :     void addSection(ElfSection *section);
         457                 :
         458              12 :     std::list<ElfSection *>::iterator begin() { return sections.begin(); }
         459             100 :     std::list<ElfSection *>::iterator end() { return sections.end(); }
         460                 :
         461                 :     ElfSegment *splitBefore(ElfSection *section);
         462                 : private:
         463                 :     unsigned int type;
         464                 :     int v_p_diff; // Difference between physical and virtual address
         465                 :     unsigned int flags;
         466                 :     unsigned int align;
         467                 :     std::list<ElfSection *> sections;
         468                 :     // The following are only really used for PT_GNU_RELRO until something
         469                 :     // better is found.
         470                 :     unsigned int vaddr;
         471                 :     unsigned int filesz, memsz;
         472                 : };
         473                 :
         474              84 : class Elf_Ehdr: public serializable<Elf_Ehdr_Traits>, public ElfSection {
         475                 : public:
         476                 :     Elf_Ehdr(std::ifstream &file, char ei_class, char ei_data);
         477               4 :     void serialize(std::ofstream &file, char ei_class, char ei_data)
         478                 :     {
         479               4 :         serializable<Elf_Ehdr_Traits>::serialize(file, ei_class, ei_data);
         480               4 :     }
         481                 : };
         482                 :
         483                 : class Elf_Phdr: public serializable<Elf_Phdr_Traits> {
         484                 : public:
         485              29 :     Elf_Phdr() {};
         486              90 :     Elf_Phdr(std::ifstream &file, char ei_class, char ei_data)
         487              90 :     : serializable<Elf_Phdr_Traits>(file, ei_class, ei_data) {};
         488            3236 :     bool contains(ElfSection *section)
         489                 :     {
         490            3236 :         unsigned int size = section->getSize();
         491            3236 :         unsigned int addr = section->getAddr();
         492                 :         // This may be biased, but should work in most cases
         493            3236 :         if ((section->getFlags() & SHF_ALLOC) == 0)
         494            1202 :             return false;
         495                 :         // Special case for PT_DYNAMIC. Eventually, this should
         496                 :         // be better handled than special cases
         497            2034 :         if ((p_type == PT_DYNAMIC) && (section->getType() != SHT_DYNAMIC))
         498             452 :             return false;
         499                 :         // Special case for PT_TLS.
         500            1582 :         if ((p_type == PT_TLS) && !(section->getFlags() & SHF_TLS))
         501              45 :             return false;
         502                 :         return (addr >= p_vaddr) &&
         503            1537 :                (addr + size <= p_vaddr + p_memsz);
         504                 :
         505                 :     }
         506                 : };
         507                 :
         508                 : typedef serializable<Elf_Dyn_Traits> Elf_Dyn;
         509                 :
         510               0 : struct Elf_DynValue {
         511                 :     unsigned int tag;
         512                 :     ElfValue *value;
         513                 : };
         514                 :
         515                 : class ElfDynamic_Section: public ElfSection {
         516                 : public:
         517                 :     ElfDynamic_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent);
         518                 :     ~ElfDynamic_Section();
         519                 :
         520                 :     void serialize(std::ofstream &file, char ei_class, char ei_data);
         521                 :
         522                 :     ElfValue *getValueForType(unsigned int tag);
         523                 :     ElfSection *getSectionForType(unsigned int tag);
         524                 :     void setValueForType(unsigned int tag, ElfValue *val);
         525                 : private:
         526                 :     std::vector<Elf_DynValue> dyns;
         527                 : };
         528                 :
         529                 : typedef serializable<Elf_Sym_Traits> Elf_Sym;
         530                 :
         531          416158 : struct Elf_SymValue {
         532                 :     const char *name;
         533                 :     unsigned char info;
         534                 :     unsigned char other;
         535                 :     ElfLocation value;
         536                 :     unsigned int size;
         537                 :     bool defined;
         538                 : };
         539                 :
         540                 : #define STT(type) (1 << STT_ ##type)
         541                 :
         542             126 : class ElfSymtab_Section: public ElfSection {
         543                 : public:
         544                 :     ElfSymtab_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent);
         545                 :
         546                 :     void serialize(std::ofstream &file, char ei_class, char ei_data);
         547                 :
         548                 :     Elf_SymValue *lookup(const char *name, unsigned int type_filter = STT(OBJECT) | STT(FUNC));
         549                 :
         550                 : //private: // Until we have a real API
         551                 :     std::vector<Elf_SymValue> syms;
         552                 : };
         553                 :
         554               0 : class Elf_Rel: public serializable<Elf_Rel_Traits> {
         555                 : public:
         556          337133 :     Elf_Rel(std::ifstream &file, char ei_class, char ei_data)
         557          337133 :     : serializable<Elf_Rel_Traits>(file, ei_class, ei_data) {};
         558                 :
         559                 :     static const unsigned int sh_type = SHT_REL;
         560                 :     static const unsigned int d_tag = DT_REL;
         561                 :     static const unsigned int d_tag_count = DT_RELCOUNT;
         562                 : };
         563                 :
         564               0 : class Elf_Rela: public serializable<Elf_Rela_Traits> {
         565                 : public:
         566               0 :     Elf_Rela(std::ifstream &file, char ei_class, char ei_data)
         567               0 :     : serializable<Elf_Rela_Traits>(file, ei_class, ei_data) {};
         568                 :
         569                 :     static const unsigned int sh_type = SHT_RELA;
         570                 :     static const unsigned int d_tag = DT_RELA;
         571                 :     static const unsigned int d_tag_count = DT_RELACOUNT;
         572                 : };
         573                 :
         574                 : template <class Rel>
         575             126 : class ElfRel_Section: public ElfSection {
         576                 : public:
         577              63 :     ElfRel_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent)
         578              63 :     : ElfSection(s, file, parent)
         579                 :     {
         580              63 :         int pos = file->tellg();
         581              63 :         file->seekg(shdr.sh_offset);
         582          337196 :         for (unsigned int i = 0; i < s.sh_size / s.sh_entsize; i++) {
         583          337133 :             Rel r(*file, parent->getClass(), parent->getData());
         584          337133 :             rels.push_back(r);
         585                 :         }
         586              63 :         file->seekg(pos);
         587              63 :     }
         588                 :
         589               8 :     void serialize(std::ofstream &file, char ei_class, char ei_data)
         590                 :     {
         591           15693 :         for (typename std::vector<Rel>::iterator i = rels.begin();
         592                 :              i != rels.end(); ++i)
         593           15685 :             (*i).serialize(file, ei_class, ei_data);
         594               8 :     }
         595                 : //private: // Until we have a real API
         596                 :     std::vector<Rel> rels;
         597                 : };
         598                 :
         599                 : class ElfStrtab_Section: public ElfSection {
         600                 : public:
         601             105 :     ElfStrtab_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent)
         602             105 :     : ElfSection(s, file, parent)
         603                 :     {
         604             105 :         table.push_back(table_storage(data, shdr.sh_size));
         605             105 :     }
         606                 :
         607             210 :     ~ElfStrtab_Section()
         608             210 :     {
         609             218 :         for (std::vector<table_storage>::iterator t = table.begin() + 1;
         610             109 :              t != table.end(); t++)
         611               4 :             delete[] t->buf;
         612             210 :     }
         613                 :
         614                 :     const char *getStr(unsigned int index);
         615                 :
         616                 :     const char *getStr(const char *string);
         617                 :
         618                 :     unsigned int getStrIndex(const char *string);
         619                 :
         620                 :     void serialize(std::ofstream &file, char ei_class, char ei_data);
         621                 : private:
         622               0 :     struct table_storage {
         623                 :         unsigned int size, used;
         624                 :         char *buf;
         625                 :
         626               4 :         table_storage(): size(4096), used(0), buf(new char[4096]) {}
         627             105 :         table_storage(const char *data, unsigned int sz)
         628             105 :         : size(sz), used(sz), buf(const_cast<char *>(data)) {}
         629                 :     };
         630                 :     std::vector<table_storage> table;
         631                 : };
         632                 :
         633          754041 : inline char Elf::getClass() {
         634          754041 :     return ehdr->e_ident[EI_CLASS];
         635                 : }
         636                 :
         637          753978 : inline char Elf::getData() {
         638          753978 :     return ehdr->e_ident[EI_DATA];
         639                 : }
         640                 :
         641              42 : inline char Elf::getType() {
         642              42 :     return ehdr->e_type;
         643                 : }
         644                 :
         645             108 : inline char Elf::getMachine() {
         646             108 :     return ehdr->e_machine;
         647                 : }
         648                 :
         649              42 : inline unsigned int Elf::getSize() {
         650                 :     ElfSection *section;
         651             168 :     for (section = shdr_section /* It's usually not far from the end */;
         652             126 :         section->getNext() != NULL; section = section->getNext());
         653              42 :     return section->getOffset() + section->getSize();
         654                 : }
         655                 :
         656            1896 : inline bool ElfSection::isInSegmentType(unsigned int type) {
         657            3082 :     for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
         658            1186 :         if ((*seg)->getType() == type)
         659               0 :             return true;
         660            1896 :     return false;
         661                 : }
         662                 :
         663          416116 : inline ElfLocation::ElfLocation(ElfSection *section, unsigned int off, enum position pos)
         664          416116 : : section(section) {
         665          416116 :     if ((pos == ABSOLUTE) && section)
         666          402944 :         offset = off - section->getAddr();
         667                 :     else
         668           13172 :         offset = off;
         669          416116 : }
         670                 :
         671             239 : inline ElfLocation::ElfLocation(unsigned int location, Elf *elf) {
         672             239 :     section = elf->getSectionAt(location);
         673             239 :     offset = location - (section ? section->getAddr() : 0);
         674             239 : }
         675                 :
         676          392207 : inline unsigned int ElfLocation::getValue() {
         677          392207 :     return (section ? section->getAddr() : 0) + offset;
         678                 : }
         679                 :
         680              12 : inline unsigned int ElfSize::getValue() {
         681              12 :     return section->getSize();
         682                 : }
         683                 :
         684               8 : inline unsigned int ElfEntSize::getValue() {
         685               8 :     return section->getEntSize();
         686                 : }

Generated by: LCOV version 1.7