1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mozglue/linker/CustomElf.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,209 @@ 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 CustomElf_h 1.9 +#define CustomElf_h 1.10 + 1.11 +#include "ElfLoader.h" 1.12 +#include "Logging.h" 1.13 +#include "Elfxx.h" 1.14 + 1.15 +/** 1.16 + * Library Handle class for ELF libraries we don't let the system linker 1.17 + * handle. 1.18 + */ 1.19 +class CustomElf: public LibHandle, private ElfLoader::link_map 1.20 +{ 1.21 + friend class ElfLoader; 1.22 + friend class SEGVHandler; 1.23 +public: 1.24 + /** 1.25 + * Returns a new CustomElf using the given file descriptor to map ELF 1.26 + * content. The file descriptor ownership is stolen, and it will be closed 1.27 + * in CustomElf's destructor if an instance is created, or by the Load 1.28 + * method otherwise. The path corresponds to the file descriptor, and flags 1.29 + * are the same kind of flags that would be given to dlopen(), though 1.30 + * currently, none are supported and the behaviour is more or less that of 1.31 + * RTLD_GLOBAL | RTLD_BIND_NOW. 1.32 + */ 1.33 + static mozilla::TemporaryRef<LibHandle> Load(Mappable *mappable, 1.34 + const char *path, int flags); 1.35 + 1.36 + /** 1.37 + * Inherited from LibHandle 1.38 + */ 1.39 + virtual ~CustomElf(); 1.40 + virtual void *GetSymbolPtr(const char *symbol) const; 1.41 + virtual bool Contains(void *addr) const; 1.42 + 1.43 +#ifdef __ARM_EABI__ 1.44 + virtual const void *FindExidx(int *pcount) const; 1.45 +#endif 1.46 + 1.47 +protected: 1.48 + virtual Mappable *GetMappable() const; 1.49 + 1.50 +public: 1.51 + /** 1.52 + * Shows some stats about the Mappable instance. The when argument is to be 1.53 + * used by the caller to give an identifier of the when the stats call is 1.54 + * made. 1.55 + */ 1.56 + void stats(const char *when) const; 1.57 + 1.58 +private: 1.59 + /** 1.60 + * Returns a pointer to the Elf Symbol in the Dynamic Symbol table 1.61 + * corresponding to the given symbol name (with a pre-computed hash). 1.62 + */ 1.63 + const Elf::Sym *GetSymbol(const char *symbol, unsigned long hash) const; 1.64 + 1.65 + /** 1.66 + * Returns the address corresponding to the given symbol name (with a 1.67 + * pre-computed hash). 1.68 + */ 1.69 + void *GetSymbolPtr(const char *symbol, unsigned long hash) const; 1.70 + 1.71 + /** 1.72 + * Scan dependent libraries to find the address corresponding to the 1.73 + * given symbol name. This is used to find symbols that are undefined 1.74 + * in the Elf object. 1.75 + */ 1.76 + void *GetSymbolPtrInDeps(const char *symbol) const; 1.77 + 1.78 + /** 1.79 + * Private constructor 1.80 + */ 1.81 + CustomElf(Mappable *mappable, const char *path) 1.82 + : LibHandle(path) 1.83 + , mappable(mappable) 1.84 + , init(0) 1.85 + , fini(0) 1.86 + , initialized(false) 1.87 + , has_text_relocs(false) 1.88 + { } 1.89 + 1.90 + /** 1.91 + * Returns a pointer relative to the base address where the library is 1.92 + * loaded. 1.93 + */ 1.94 + void *GetPtr(const Elf::Addr offset) const 1.95 + { 1.96 + return base + offset; 1.97 + } 1.98 + 1.99 + /** 1.100 + * Like the above, but returns a typed (const) pointer 1.101 + */ 1.102 + template <typename T> 1.103 + const T *GetPtr(const Elf::Addr offset) const 1.104 + { 1.105 + return reinterpret_cast<const T *>(base + offset); 1.106 + } 1.107 + 1.108 + /** 1.109 + * Loads an Elf segment defined by the given PT_LOAD header. 1.110 + * Returns whether this succeeded or failed. 1.111 + */ 1.112 + bool LoadSegment(const Elf::Phdr *pt_load) const; 1.113 + 1.114 + /** 1.115 + * Initializes the library according to information found in the given 1.116 + * PT_DYNAMIC header. 1.117 + * Returns whether this succeeded or failed. 1.118 + */ 1.119 + bool InitDyn(const Elf::Phdr *pt_dyn); 1.120 + 1.121 + /** 1.122 + * Apply .rel.dyn/.rela.dyn relocations. 1.123 + * Returns whether this succeeded or failed. 1.124 + */ 1.125 + bool Relocate(); 1.126 + 1.127 + /** 1.128 + * Apply .rel.plt/.rela.plt relocations. 1.129 + * Returns whether this succeeded or failed. 1.130 + */ 1.131 + bool RelocateJumps(); 1.132 + 1.133 + /** 1.134 + * Call initialization functions (.init/.init_array) 1.135 + * Returns true; 1.136 + */ 1.137 + bool CallInit(); 1.138 + 1.139 + /** 1.140 + * Call destructor functions (.fini_array/.fini) 1.141 + * Returns whether this succeeded or failed. 1.142 + */ 1.143 + void CallFini(); 1.144 + 1.145 + /** 1.146 + * Call a function given a pointer to its location. 1.147 + */ 1.148 + void CallFunction(void *ptr) const 1.149 + { 1.150 + /* C++ doesn't allow direct conversion between pointer-to-object 1.151 + * and pointer-to-function. */ 1.152 + union { 1.153 + void *ptr; 1.154 + void (*func)(void); 1.155 + } f; 1.156 + f.ptr = ptr; 1.157 + DEBUG_LOG("%s: Calling function @%p", GetPath(), ptr); 1.158 + f.func(); 1.159 + } 1.160 + 1.161 + /** 1.162 + * Call a function given a an address relative to the library base 1.163 + */ 1.164 + void CallFunction(Elf::Addr addr) const 1.165 + { 1.166 + return CallFunction(GetPtr(addr)); 1.167 + } 1.168 + 1.169 + /* Appropriated Mappable */ 1.170 + mozilla::RefPtr<Mappable> mappable; 1.171 + 1.172 + /* Base address where the library is loaded */ 1.173 + MappedPtr base; 1.174 + 1.175 + /* String table */ 1.176 + Elf::Strtab strtab; 1.177 + 1.178 + /* Symbol table */ 1.179 + UnsizedArray<Elf::Sym> symtab; 1.180 + 1.181 + /* Buckets and chains for the System V symbol hash table */ 1.182 + Array<Elf::Word> buckets; 1.183 + UnsizedArray<Elf::Word> chains; 1.184 + 1.185 + /* List of dependent libraries */ 1.186 + std::vector<mozilla::RefPtr<LibHandle> > dependencies; 1.187 + 1.188 + /* List of .rel.dyn/.rela.dyn relocations */ 1.189 + Array<Elf::Reloc> relocations; 1.190 + 1.191 + /* List of .rel.plt/.rela.plt relocation */ 1.192 + Array<Elf::Reloc> jumprels; 1.193 + 1.194 + /* Relative address of the initialization and destruction functions 1.195 + * (.init/.fini) */ 1.196 + Elf::Addr init, fini; 1.197 + 1.198 + /* List of initialization and destruction functions 1.199 + * (.init_array/.fini_array) */ 1.200 + Array<void *> init_array, fini_array; 1.201 + 1.202 + bool initialized; 1.203 + 1.204 + bool has_text_relocs; 1.205 + 1.206 +#ifdef __ARM_EABI__ 1.207 + /* ARM.exidx information used by FindExidx */ 1.208 + Array<uint32_t[2]> arm_exidx; 1.209 +#endif 1.210 +}; 1.211 + 1.212 +#endif /* CustomElf_h */