CustomElf.h (3858B)
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 CustomElf_h 6 #define CustomElf_h 7 8 #include "ElfLoader.h" 9 #include "BaseElf.h" 10 #include "Logging.h" 11 #include "Elfxx.h" 12 13 /** 14 * Library Handle class for ELF libraries we don't let the system linker 15 * handle. 16 */ 17 class CustomElf : public BaseElf, private ElfLoader::link_map { 18 friend class ElfLoader; 19 friend class SEGVHandler; 20 21 public: 22 /** 23 * Returns a new CustomElf using the given file descriptor to map ELF 24 * content. The file descriptor ownership is stolen, and it will be closed 25 * in CustomElf's destructor if an instance is created, or by the Load 26 * method otherwise. The path corresponds to the file descriptor, and flags 27 * are the same kind of flags that would be given to dlopen(), though 28 * currently, none are supported and the behaviour is more or less that of 29 * RTLD_GLOBAL | RTLD_BIND_NOW. 30 */ 31 static already_AddRefed<LibHandle> Load(Mappable* mappable, const char* path, 32 int flags); 33 34 /** 35 * Inherited from LibHandle/BaseElf 36 */ 37 virtual ~CustomElf(); 38 39 public: 40 /** 41 * Returns the instance, casted as BaseElf. (short of a better way to do 42 * this without RTTI) 43 */ 44 virtual BaseElf* AsBaseElf() { return this; } 45 46 private: 47 /** 48 * Scan dependent libraries to find the address corresponding to the 49 * given symbol name. This is used to find symbols that are undefined 50 * in the Elf object. 51 */ 52 void* GetSymbolPtrInDeps(const char* symbol) const; 53 54 /** 55 * Private constructor 56 */ 57 CustomElf(Mappable* mappable, const char* path) 58 : BaseElf(path, mappable), 59 link_map(), 60 init(0), 61 fini(0), 62 initialized(false), 63 has_text_relocs(false) {} 64 65 /** 66 * Loads an Elf segment defined by the given PT_LOAD header. 67 * Returns whether this succeeded or failed. 68 */ 69 bool LoadSegment(const Elf::Phdr* pt_load) const; 70 71 /** 72 * Initializes the library according to information found in the given 73 * PT_DYNAMIC header. 74 * Returns whether this succeeded or failed. 75 */ 76 bool InitDyn(const Elf::Phdr* pt_dyn); 77 78 /** 79 * Apply .rel.dyn/.rela.dyn relocations. 80 * Returns whether this succeeded or failed. 81 */ 82 bool Relocate(); 83 84 /** 85 * Apply .rel.plt/.rela.plt relocations. 86 * Returns whether this succeeded or failed. 87 */ 88 bool RelocateJumps(); 89 90 /** 91 * Call initialization functions (.init/.init_array) 92 * Returns true; 93 */ 94 bool CallInit(); 95 96 /** 97 * Call destructor functions (.fini_array/.fini) 98 * Returns whether this succeeded or failed. 99 */ 100 void CallFini(); 101 102 /** 103 * Call a function given a pointer to its location. 104 */ 105 void CallFunction(void* ptr) const { 106 /* C++ doesn't allow direct conversion between pointer-to-object 107 * and pointer-to-function. */ 108 union { 109 void* ptr; 110 void (*func)(void); 111 } f; 112 f.ptr = ptr; 113 DEBUG_LOG("%s: Calling function @%p", GetPath(), ptr); 114 f.func(); 115 } 116 117 /** 118 * Call a function given a an address relative to the library base 119 */ 120 void CallFunction(Elf::Addr addr) const { return CallFunction(GetPtr(addr)); } 121 122 /* List of dependent libraries */ 123 std::vector<RefPtr<LibHandle> > dependencies; 124 125 /* List of .rel.dyn/.rela.dyn relocations */ 126 Array<Elf::Reloc> relocations; 127 128 /* List of .rel.plt/.rela.plt relocation */ 129 Array<Elf::Reloc> jumprels; 130 131 /* Relative address of the initialization and destruction functions 132 * (.init/.fini) */ 133 Elf::Addr init, fini; 134 135 /* List of initialization and destruction functions 136 * (.init_array/.fini_array) */ 137 Array<void*> init_array, fini_array; 138 139 bool initialized; 140 141 bool has_text_relocs; 142 }; 143 144 #endif /* CustomElf_h */