michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef Elfxx_h michael@0: #define Elfxx_h michael@0: michael@0: /** michael@0: * Android system headers have two different elf.h file. The one under linux/ michael@0: * is the most complete. michael@0: */ michael@0: #ifdef ANDROID michael@0: #include michael@0: #else michael@0: #include michael@0: #endif michael@0: #include michael@0: michael@0: #if defined(__ARM_EABI__) && !defined(PT_ARM_EXIDX) michael@0: #define PT_ARM_EXIDX 0x70000001 michael@0: #endif michael@0: michael@0: /** michael@0: * Generic ELF macros for the target system michael@0: */ michael@0: #ifdef __LP64__ michael@0: #define Elf_(type) Elf64_ ## type michael@0: #define ELFCLASS ELFCLASS64 michael@0: #define ELF_R_TYPE ELF64_R_TYPE michael@0: #define ELF_R_SYM ELF64_R_SYM michael@0: #ifndef ELF_ST_BIND michael@0: #define ELF_ST_BIND ELF64_ST_BIND michael@0: #endif michael@0: #else michael@0: #define Elf_(type) Elf32_ ## type michael@0: #define ELFCLASS ELFCLASS32 michael@0: #define ELF_R_TYPE ELF32_R_TYPE michael@0: #define ELF_R_SYM ELF32_R_SYM michael@0: #ifndef ELF_ST_BIND michael@0: #define ELF_ST_BIND ELF32_ST_BIND michael@0: #endif michael@0: #endif michael@0: michael@0: #ifndef __BYTE_ORDER michael@0: #error Cannot find endianness michael@0: #endif michael@0: michael@0: #if __BYTE_ORDER == __LITTLE_ENDIAN michael@0: #define ELFDATA ELFDATA2LSB michael@0: #elif __BYTE_ORDER == __BIG_ENDIAN michael@0: #define ELFDATA ELFDATA2MSB michael@0: #endif michael@0: michael@0: #ifdef __linux__ michael@0: #define ELFOSABI ELFOSABI_LINUX michael@0: #ifdef EI_ABIVERSION michael@0: #define ELFABIVERSION 0 michael@0: #endif michael@0: #else michael@0: #error Unknown ELF OSABI michael@0: #endif michael@0: michael@0: #if defined(__i386__) michael@0: #define ELFMACHINE EM_386 michael@0: michael@0: // Doing this way probably doesn't scale to other architectures michael@0: #define R_ABS R_386_32 michael@0: #define R_GLOB_DAT R_386_GLOB_DAT michael@0: #define R_JMP_SLOT R_386_JMP_SLOT michael@0: #define R_RELATIVE R_386_RELATIVE michael@0: #define RELOC(n) DT_REL ## n michael@0: #define UNSUPPORTED_RELOC(n) DT_RELA ## n michael@0: #define STR_RELOC(n) "DT_REL" # n michael@0: #define Reloc Rel michael@0: michael@0: #elif defined(__x86_64__) michael@0: #define ELFMACHINE EM_X86_64 michael@0: michael@0: #define R_ABS R_X86_64_64 michael@0: #define R_GLOB_DAT R_X86_64_GLOB_DAT michael@0: #define R_JMP_SLOT R_X86_64_JUMP_SLOT michael@0: #define R_RELATIVE R_X86_64_RELATIVE michael@0: #define RELOC(n) DT_RELA ## n michael@0: #define UNSUPPORTED_RELOC(n) DT_REL ## n michael@0: #define STR_RELOC(n) "DT_RELA" # n michael@0: #define Reloc Rela michael@0: michael@0: #elif defined(__arm__) michael@0: #define ELFMACHINE EM_ARM michael@0: michael@0: #ifndef R_ARM_ABS32 michael@0: #define R_ARM_ABS32 2 michael@0: #endif michael@0: #ifndef R_ARM_GLOB_DAT michael@0: #define R_ARM_GLOB_DAT 21 michael@0: #endif michael@0: #ifndef R_ARM_JUMP_SLOT michael@0: #define R_ARM_JUMP_SLOT 22 michael@0: #endif michael@0: #ifndef R_ARM_RELATIVE michael@0: #define R_ARM_RELATIVE 23 michael@0: #endif michael@0: michael@0: #define R_ABS R_ARM_ABS32 michael@0: #define R_GLOB_DAT R_ARM_GLOB_DAT michael@0: #define R_JMP_SLOT R_ARM_JUMP_SLOT michael@0: #define R_RELATIVE R_ARM_RELATIVE michael@0: #define RELOC(n) DT_REL ## n michael@0: #define UNSUPPORTED_RELOC(n) DT_RELA ## n michael@0: #define STR_RELOC(n) "DT_REL" # n michael@0: #define Reloc Rel michael@0: michael@0: #else michael@0: #error Unknown ELF machine type michael@0: #endif michael@0: michael@0: /** michael@0: * Android system headers don't have all definitions michael@0: */ michael@0: #ifndef STN_UNDEF michael@0: #define STN_UNDEF 0 michael@0: #endif michael@0: #ifndef DT_INIT_ARRAY michael@0: #define DT_INIT_ARRAY 25 michael@0: #endif michael@0: #ifndef DT_FINI_ARRAY michael@0: #define DT_FINI_ARRAY 26 michael@0: #endif michael@0: #ifndef DT_INIT_ARRAYSZ michael@0: #define DT_INIT_ARRAYSZ 27 michael@0: #endif michael@0: #ifndef DT_FINI_ARRAYSZ michael@0: #define DT_FINI_ARRAYSZ 28 michael@0: #endif michael@0: #ifndef DT_RELACOUNT michael@0: #define DT_RELACOUNT 0x6ffffff9 michael@0: #endif michael@0: #ifndef DT_RELCOUNT michael@0: #define DT_RELCOUNT 0x6ffffffa michael@0: #endif michael@0: #ifndef DT_VERSYM michael@0: #define DT_VERSYM 0x6ffffff0 michael@0: #endif michael@0: #ifndef DT_VERDEF michael@0: #define DT_VERDEF 0x6ffffffc michael@0: #endif michael@0: #ifndef DT_VERDEFNUM michael@0: #define DT_VERDEFNUM 0x6ffffffd michael@0: #endif michael@0: #ifndef DT_VERNEED michael@0: #define DT_VERNEED 0x6ffffffe michael@0: #endif michael@0: #ifndef DT_VERNEEDNUM michael@0: #define DT_VERNEEDNUM 0x6fffffff michael@0: #endif michael@0: #ifndef DT_FLAGS_1 michael@0: #define DT_FLAGS_1 0x6ffffffb michael@0: #endif michael@0: #ifndef DT_FLAGS michael@0: #define DT_FLAGS 30 michael@0: #endif michael@0: #ifndef DF_SYMBOLIC michael@0: #define DF_SYMBOLIC 0x00000002 michael@0: #endif michael@0: #ifndef DF_TEXTREL michael@0: #define DF_TEXTREL 0x00000004 michael@0: #endif michael@0: michael@0: namespace Elf { michael@0: michael@0: /** michael@0: * Define a few basic Elf Types michael@0: */ michael@0: typedef Elf_(Phdr) Phdr; michael@0: typedef Elf_(Dyn) Dyn; michael@0: typedef Elf_(Sym) Sym; michael@0: typedef Elf_(Addr) Addr; michael@0: typedef Elf_(Word) Word; michael@0: typedef Elf_(Half) Half; michael@0: michael@0: /** michael@0: * Helper class around the standard Elf header struct michael@0: */ michael@0: struct Ehdr: public Elf_(Ehdr) michael@0: { michael@0: /** michael@0: * Equivalent to reinterpret_cast(buf), but additionally michael@0: * checking that this is indeed an Elf header and that the Elf type michael@0: * corresponds to that of the system michael@0: */ michael@0: static const Ehdr *validate(const void *buf); michael@0: }; michael@0: michael@0: /** michael@0: * Elf String table michael@0: */ michael@0: class Strtab: public UnsizedArray michael@0: { michael@0: public: michael@0: /** michael@0: * Returns the string at the given index in the table michael@0: */ michael@0: const char *GetStringAt(off_t index) const michael@0: { michael@0: return &UnsizedArray::operator[](index); michael@0: } michael@0: }; michael@0: michael@0: /** michael@0: * Helper class around Elf relocation. michael@0: */ michael@0: struct Rel: public Elf_(Rel) michael@0: { michael@0: /** michael@0: * Returns the addend for the relocation, which is the value stored michael@0: * at r_offset. michael@0: */ michael@0: Addr GetAddend(void *base) const michael@0: { michael@0: return *(reinterpret_cast( michael@0: reinterpret_cast(base) + r_offset)); michael@0: } michael@0: }; michael@0: michael@0: /** michael@0: * Helper class around Elf relocation with addend. michael@0: */ michael@0: struct Rela: public Elf_(Rela) michael@0: { michael@0: /** michael@0: * Returns the addend for the relocation. michael@0: */ michael@0: Addr GetAddend(void *base) const michael@0: { michael@0: return r_addend; michael@0: } michael@0: }; michael@0: michael@0: } /* namespace Elf */ michael@0: michael@0: #endif /* Elfxx_h */