1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef BaseElf_h 6 #define BaseElf_h 7 8 #include "ElfLoader.h" 9 #include "Elfxx.h" 10 11 /** 12 * Base class for ELF libraries. This class includes things that will be 13 * common between SystemElfs and CustomElfs. 14 */ 15 class BaseElf : public LibHandle { 16 public: 17 /** 18 * Hash function for symbol lookup, as defined in ELF standard for System V. 19 */ 20 static unsigned long Hash(const char* symbol); 21 22 /** 23 * Returns the address corresponding to the given symbol name (with a 24 * pre-computed hash). 25 */ 26 void* GetSymbolPtr(const char* symbol, unsigned long hash) const; 27 28 /** 29 * Returns a pointer to the Elf Symbol in the Dynamic Symbol table 30 * corresponding to the given symbol name (with a pre-computed hash). 31 */ 32 const Elf::Sym* GetSymbol(const char* symbol, unsigned long hash) const; 33 34 explicit BaseElf(const char* path, Mappable* mappable = nullptr) LibHandle(path)35 : LibHandle(path), mappable(mappable) {} 36 37 protected: 38 /** 39 * Inherited from LibHandle. Those are temporary and are not supposed to 40 * be used. 41 */ 42 virtual void* GetSymbolPtr(const char* symbol) const; 43 virtual bool Contains(void* addr) const; GetBase()44 virtual void* GetBase() const { return GetPtr(0); } 45 46 #ifdef __ARM_EABI__ 47 virtual const void* FindExidx(int* pcount) const; 48 #endif 49 GetMappable()50 virtual Mappable* GetMappable() const { return NULL; }; 51 52 public: 53 /* private: */ 54 /** 55 * Returns a pointer relative to the base address where the library is 56 * loaded. 57 */ GetPtr(const Elf::Addr offset)58 void* GetPtr(const Elf::Addr offset) const { 59 if (reinterpret_cast<void*>(offset) > base) 60 return reinterpret_cast<void*>(offset); 61 return base + offset; 62 } 63 64 /** 65 * Like the above, but returns a typed (const) pointer 66 */ 67 template <typename T> GetPtr(const Elf::Addr offset)68 const T* GetPtr(const Elf::Addr offset) const { 69 if (reinterpret_cast<void*>(offset) > base) 70 return reinterpret_cast<const T*>(offset); 71 return reinterpret_cast<const T*>(base + offset); 72 } 73 74 /* Appropriated Mappable */ 75 /* /!\ we rely on this being nullptr for BaseElf instances, but not 76 * CustomElf instances. */ 77 RefPtr<Mappable> mappable; 78 79 /* Base address where the library is loaded */ 80 MappedPtr base; 81 82 /* Buckets and chains for the System V symbol hash table */ 83 Array<Elf::Word> buckets; 84 UnsizedArray<Elf::Word> chains; 85 86 /* protected: */ 87 /* String table */ 88 Elf::Strtab strtab; 89 90 /* Symbol table */ 91 UnsizedArray<Elf::Sym> symtab; 92 93 #ifdef __ARM_EABI__ 94 /* ARM.exidx information used by FindExidx */ 95 Array<uint32_t[2]> arm_exidx; 96 #endif 97 }; 98 99 /** 100 * Class for ELF libraries that already loaded in memory. 101 */ 102 class LoadedElf : public BaseElf { 103 public: 104 /** 105 * Returns a LoadedElf corresponding to the already loaded ELF 106 * at the given base address. 107 */ 108 static already_AddRefed<LibHandle> Create(const char* path, void* base_addr); 109 110 private: LoadedElf(const char * path)111 explicit LoadedElf(const char* path) : BaseElf(path) {} 112 ~LoadedElf()113 ~LoadedElf() { 114 /* Avoid base's destructor unmapping something that doesn't actually 115 * belong to it. */ 116 base.release(); 117 ElfLoader::Singleton.Forget(this); 118 } 119 120 /** 121 * Initializes the library according to information found in the given 122 * PT_DYNAMIC header. 123 * Returns whether this succeeded or failed. 124 */ 125 bool InitDyn(const Elf::Phdr* pt_dyn); 126 }; 127 128 #endif /* BaseElf_h */ 129