1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mozglue/linker/Elfxx.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,241 @@ 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 file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef Elfxx_h 1.9 +#define Elfxx_h 1.10 + 1.11 +/** 1.12 + * Android system headers have two different elf.h file. The one under linux/ 1.13 + * is the most complete. 1.14 + */ 1.15 +#ifdef ANDROID 1.16 +#include <linux/elf.h> 1.17 +#else 1.18 +#include <elf.h> 1.19 +#endif 1.20 +#include <endian.h> 1.21 + 1.22 +#if defined(__ARM_EABI__) && !defined(PT_ARM_EXIDX) 1.23 +#define PT_ARM_EXIDX 0x70000001 1.24 +#endif 1.25 + 1.26 +/** 1.27 + * Generic ELF macros for the target system 1.28 + */ 1.29 +#ifdef __LP64__ 1.30 +#define Elf_(type) Elf64_ ## type 1.31 +#define ELFCLASS ELFCLASS64 1.32 +#define ELF_R_TYPE ELF64_R_TYPE 1.33 +#define ELF_R_SYM ELF64_R_SYM 1.34 +#ifndef ELF_ST_BIND 1.35 +#define ELF_ST_BIND ELF64_ST_BIND 1.36 +#endif 1.37 +#else 1.38 +#define Elf_(type) Elf32_ ## type 1.39 +#define ELFCLASS ELFCLASS32 1.40 +#define ELF_R_TYPE ELF32_R_TYPE 1.41 +#define ELF_R_SYM ELF32_R_SYM 1.42 +#ifndef ELF_ST_BIND 1.43 +#define ELF_ST_BIND ELF32_ST_BIND 1.44 +#endif 1.45 +#endif 1.46 + 1.47 +#ifndef __BYTE_ORDER 1.48 +#error Cannot find endianness 1.49 +#endif 1.50 + 1.51 +#if __BYTE_ORDER == __LITTLE_ENDIAN 1.52 +#define ELFDATA ELFDATA2LSB 1.53 +#elif __BYTE_ORDER == __BIG_ENDIAN 1.54 +#define ELFDATA ELFDATA2MSB 1.55 +#endif 1.56 + 1.57 +#ifdef __linux__ 1.58 +#define ELFOSABI ELFOSABI_LINUX 1.59 +#ifdef EI_ABIVERSION 1.60 +#define ELFABIVERSION 0 1.61 +#endif 1.62 +#else 1.63 +#error Unknown ELF OSABI 1.64 +#endif 1.65 + 1.66 +#if defined(__i386__) 1.67 +#define ELFMACHINE EM_386 1.68 + 1.69 +// Doing this way probably doesn't scale to other architectures 1.70 +#define R_ABS R_386_32 1.71 +#define R_GLOB_DAT R_386_GLOB_DAT 1.72 +#define R_JMP_SLOT R_386_JMP_SLOT 1.73 +#define R_RELATIVE R_386_RELATIVE 1.74 +#define RELOC(n) DT_REL ## n 1.75 +#define UNSUPPORTED_RELOC(n) DT_RELA ## n 1.76 +#define STR_RELOC(n) "DT_REL" # n 1.77 +#define Reloc Rel 1.78 + 1.79 +#elif defined(__x86_64__) 1.80 +#define ELFMACHINE EM_X86_64 1.81 + 1.82 +#define R_ABS R_X86_64_64 1.83 +#define R_GLOB_DAT R_X86_64_GLOB_DAT 1.84 +#define R_JMP_SLOT R_X86_64_JUMP_SLOT 1.85 +#define R_RELATIVE R_X86_64_RELATIVE 1.86 +#define RELOC(n) DT_RELA ## n 1.87 +#define UNSUPPORTED_RELOC(n) DT_REL ## n 1.88 +#define STR_RELOC(n) "DT_RELA" # n 1.89 +#define Reloc Rela 1.90 + 1.91 +#elif defined(__arm__) 1.92 +#define ELFMACHINE EM_ARM 1.93 + 1.94 +#ifndef R_ARM_ABS32 1.95 +#define R_ARM_ABS32 2 1.96 +#endif 1.97 +#ifndef R_ARM_GLOB_DAT 1.98 +#define R_ARM_GLOB_DAT 21 1.99 +#endif 1.100 +#ifndef R_ARM_JUMP_SLOT 1.101 +#define R_ARM_JUMP_SLOT 22 1.102 +#endif 1.103 +#ifndef R_ARM_RELATIVE 1.104 +#define R_ARM_RELATIVE 23 1.105 +#endif 1.106 + 1.107 +#define R_ABS R_ARM_ABS32 1.108 +#define R_GLOB_DAT R_ARM_GLOB_DAT 1.109 +#define R_JMP_SLOT R_ARM_JUMP_SLOT 1.110 +#define R_RELATIVE R_ARM_RELATIVE 1.111 +#define RELOC(n) DT_REL ## n 1.112 +#define UNSUPPORTED_RELOC(n) DT_RELA ## n 1.113 +#define STR_RELOC(n) "DT_REL" # n 1.114 +#define Reloc Rel 1.115 + 1.116 +#else 1.117 +#error Unknown ELF machine type 1.118 +#endif 1.119 + 1.120 +/** 1.121 + * Android system headers don't have all definitions 1.122 + */ 1.123 +#ifndef STN_UNDEF 1.124 +#define STN_UNDEF 0 1.125 +#endif 1.126 +#ifndef DT_INIT_ARRAY 1.127 +#define DT_INIT_ARRAY 25 1.128 +#endif 1.129 +#ifndef DT_FINI_ARRAY 1.130 +#define DT_FINI_ARRAY 26 1.131 +#endif 1.132 +#ifndef DT_INIT_ARRAYSZ 1.133 +#define DT_INIT_ARRAYSZ 27 1.134 +#endif 1.135 +#ifndef DT_FINI_ARRAYSZ 1.136 +#define DT_FINI_ARRAYSZ 28 1.137 +#endif 1.138 +#ifndef DT_RELACOUNT 1.139 +#define DT_RELACOUNT 0x6ffffff9 1.140 +#endif 1.141 +#ifndef DT_RELCOUNT 1.142 +#define DT_RELCOUNT 0x6ffffffa 1.143 +#endif 1.144 +#ifndef DT_VERSYM 1.145 +#define DT_VERSYM 0x6ffffff0 1.146 +#endif 1.147 +#ifndef DT_VERDEF 1.148 +#define DT_VERDEF 0x6ffffffc 1.149 +#endif 1.150 +#ifndef DT_VERDEFNUM 1.151 +#define DT_VERDEFNUM 0x6ffffffd 1.152 +#endif 1.153 +#ifndef DT_VERNEED 1.154 +#define DT_VERNEED 0x6ffffffe 1.155 +#endif 1.156 +#ifndef DT_VERNEEDNUM 1.157 +#define DT_VERNEEDNUM 0x6fffffff 1.158 +#endif 1.159 +#ifndef DT_FLAGS_1 1.160 +#define DT_FLAGS_1 0x6ffffffb 1.161 +#endif 1.162 +#ifndef DT_FLAGS 1.163 +#define DT_FLAGS 30 1.164 +#endif 1.165 +#ifndef DF_SYMBOLIC 1.166 +#define DF_SYMBOLIC 0x00000002 1.167 +#endif 1.168 +#ifndef DF_TEXTREL 1.169 +#define DF_TEXTREL 0x00000004 1.170 +#endif 1.171 + 1.172 +namespace Elf { 1.173 + 1.174 +/** 1.175 + * Define a few basic Elf Types 1.176 + */ 1.177 +typedef Elf_(Phdr) Phdr; 1.178 +typedef Elf_(Dyn) Dyn; 1.179 +typedef Elf_(Sym) Sym; 1.180 +typedef Elf_(Addr) Addr; 1.181 +typedef Elf_(Word) Word; 1.182 +typedef Elf_(Half) Half; 1.183 + 1.184 +/** 1.185 + * Helper class around the standard Elf header struct 1.186 + */ 1.187 +struct Ehdr: public Elf_(Ehdr) 1.188 +{ 1.189 + /** 1.190 + * Equivalent to reinterpret_cast<const Ehdr *>(buf), but additionally 1.191 + * checking that this is indeed an Elf header and that the Elf type 1.192 + * corresponds to that of the system 1.193 + */ 1.194 + static const Ehdr *validate(const void *buf); 1.195 +}; 1.196 + 1.197 +/** 1.198 + * Elf String table 1.199 + */ 1.200 +class Strtab: public UnsizedArray<const char> 1.201 +{ 1.202 +public: 1.203 + /** 1.204 + * Returns the string at the given index in the table 1.205 + */ 1.206 + const char *GetStringAt(off_t index) const 1.207 + { 1.208 + return &UnsizedArray<const char>::operator[](index); 1.209 + } 1.210 +}; 1.211 + 1.212 +/** 1.213 + * Helper class around Elf relocation. 1.214 + */ 1.215 +struct Rel: public Elf_(Rel) 1.216 +{ 1.217 + /** 1.218 + * Returns the addend for the relocation, which is the value stored 1.219 + * at r_offset. 1.220 + */ 1.221 + Addr GetAddend(void *base) const 1.222 + { 1.223 + return *(reinterpret_cast<const Addr *>( 1.224 + reinterpret_cast<const char *>(base) + r_offset)); 1.225 + } 1.226 +}; 1.227 + 1.228 +/** 1.229 + * Helper class around Elf relocation with addend. 1.230 + */ 1.231 +struct Rela: public Elf_(Rela) 1.232 +{ 1.233 + /** 1.234 + * Returns the addend for the relocation. 1.235 + */ 1.236 + Addr GetAddend(void *base) const 1.237 + { 1.238 + return r_addend; 1.239 + } 1.240 +}; 1.241 + 1.242 +} /* namespace Elf */ 1.243 + 1.244 +#endif /* Elfxx_h */