mozglue/linker/CustomElf.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef CustomElf_h
michael@0 6 #define CustomElf_h
michael@0 7
michael@0 8 #include "ElfLoader.h"
michael@0 9 #include "Logging.h"
michael@0 10 #include "Elfxx.h"
michael@0 11
michael@0 12 /**
michael@0 13 * Library Handle class for ELF libraries we don't let the system linker
michael@0 14 * handle.
michael@0 15 */
michael@0 16 class CustomElf: public LibHandle, private ElfLoader::link_map
michael@0 17 {
michael@0 18 friend class ElfLoader;
michael@0 19 friend class SEGVHandler;
michael@0 20 public:
michael@0 21 /**
michael@0 22 * Returns a new CustomElf using the given file descriptor to map ELF
michael@0 23 * content. The file descriptor ownership is stolen, and it will be closed
michael@0 24 * in CustomElf's destructor if an instance is created, or by the Load
michael@0 25 * method otherwise. The path corresponds to the file descriptor, and flags
michael@0 26 * are the same kind of flags that would be given to dlopen(), though
michael@0 27 * currently, none are supported and the behaviour is more or less that of
michael@0 28 * RTLD_GLOBAL | RTLD_BIND_NOW.
michael@0 29 */
michael@0 30 static mozilla::TemporaryRef<LibHandle> Load(Mappable *mappable,
michael@0 31 const char *path, int flags);
michael@0 32
michael@0 33 /**
michael@0 34 * Inherited from LibHandle
michael@0 35 */
michael@0 36 virtual ~CustomElf();
michael@0 37 virtual void *GetSymbolPtr(const char *symbol) const;
michael@0 38 virtual bool Contains(void *addr) const;
michael@0 39
michael@0 40 #ifdef __ARM_EABI__
michael@0 41 virtual const void *FindExidx(int *pcount) const;
michael@0 42 #endif
michael@0 43
michael@0 44 protected:
michael@0 45 virtual Mappable *GetMappable() const;
michael@0 46
michael@0 47 public:
michael@0 48 /**
michael@0 49 * Shows some stats about the Mappable instance. The when argument is to be
michael@0 50 * used by the caller to give an identifier of the when the stats call is
michael@0 51 * made.
michael@0 52 */
michael@0 53 void stats(const char *when) const;
michael@0 54
michael@0 55 private:
michael@0 56 /**
michael@0 57 * Returns a pointer to the Elf Symbol in the Dynamic Symbol table
michael@0 58 * corresponding to the given symbol name (with a pre-computed hash).
michael@0 59 */
michael@0 60 const Elf::Sym *GetSymbol(const char *symbol, unsigned long hash) const;
michael@0 61
michael@0 62 /**
michael@0 63 * Returns the address corresponding to the given symbol name (with a
michael@0 64 * pre-computed hash).
michael@0 65 */
michael@0 66 void *GetSymbolPtr(const char *symbol, unsigned long hash) const;
michael@0 67
michael@0 68 /**
michael@0 69 * Scan dependent libraries to find the address corresponding to the
michael@0 70 * given symbol name. This is used to find symbols that are undefined
michael@0 71 * in the Elf object.
michael@0 72 */
michael@0 73 void *GetSymbolPtrInDeps(const char *symbol) const;
michael@0 74
michael@0 75 /**
michael@0 76 * Private constructor
michael@0 77 */
michael@0 78 CustomElf(Mappable *mappable, const char *path)
michael@0 79 : LibHandle(path)
michael@0 80 , mappable(mappable)
michael@0 81 , init(0)
michael@0 82 , fini(0)
michael@0 83 , initialized(false)
michael@0 84 , has_text_relocs(false)
michael@0 85 { }
michael@0 86
michael@0 87 /**
michael@0 88 * Returns a pointer relative to the base address where the library is
michael@0 89 * loaded.
michael@0 90 */
michael@0 91 void *GetPtr(const Elf::Addr offset) const
michael@0 92 {
michael@0 93 return base + offset;
michael@0 94 }
michael@0 95
michael@0 96 /**
michael@0 97 * Like the above, but returns a typed (const) pointer
michael@0 98 */
michael@0 99 template <typename T>
michael@0 100 const T *GetPtr(const Elf::Addr offset) const
michael@0 101 {
michael@0 102 return reinterpret_cast<const T *>(base + offset);
michael@0 103 }
michael@0 104
michael@0 105 /**
michael@0 106 * Loads an Elf segment defined by the given PT_LOAD header.
michael@0 107 * Returns whether this succeeded or failed.
michael@0 108 */
michael@0 109 bool LoadSegment(const Elf::Phdr *pt_load) const;
michael@0 110
michael@0 111 /**
michael@0 112 * Initializes the library according to information found in the given
michael@0 113 * PT_DYNAMIC header.
michael@0 114 * Returns whether this succeeded or failed.
michael@0 115 */
michael@0 116 bool InitDyn(const Elf::Phdr *pt_dyn);
michael@0 117
michael@0 118 /**
michael@0 119 * Apply .rel.dyn/.rela.dyn relocations.
michael@0 120 * Returns whether this succeeded or failed.
michael@0 121 */
michael@0 122 bool Relocate();
michael@0 123
michael@0 124 /**
michael@0 125 * Apply .rel.plt/.rela.plt relocations.
michael@0 126 * Returns whether this succeeded or failed.
michael@0 127 */
michael@0 128 bool RelocateJumps();
michael@0 129
michael@0 130 /**
michael@0 131 * Call initialization functions (.init/.init_array)
michael@0 132 * Returns true;
michael@0 133 */
michael@0 134 bool CallInit();
michael@0 135
michael@0 136 /**
michael@0 137 * Call destructor functions (.fini_array/.fini)
michael@0 138 * Returns whether this succeeded or failed.
michael@0 139 */
michael@0 140 void CallFini();
michael@0 141
michael@0 142 /**
michael@0 143 * Call a function given a pointer to its location.
michael@0 144 */
michael@0 145 void CallFunction(void *ptr) const
michael@0 146 {
michael@0 147 /* C++ doesn't allow direct conversion between pointer-to-object
michael@0 148 * and pointer-to-function. */
michael@0 149 union {
michael@0 150 void *ptr;
michael@0 151 void (*func)(void);
michael@0 152 } f;
michael@0 153 f.ptr = ptr;
michael@0 154 DEBUG_LOG("%s: Calling function @%p", GetPath(), ptr);
michael@0 155 f.func();
michael@0 156 }
michael@0 157
michael@0 158 /**
michael@0 159 * Call a function given a an address relative to the library base
michael@0 160 */
michael@0 161 void CallFunction(Elf::Addr addr) const
michael@0 162 {
michael@0 163 return CallFunction(GetPtr(addr));
michael@0 164 }
michael@0 165
michael@0 166 /* Appropriated Mappable */
michael@0 167 mozilla::RefPtr<Mappable> mappable;
michael@0 168
michael@0 169 /* Base address where the library is loaded */
michael@0 170 MappedPtr base;
michael@0 171
michael@0 172 /* String table */
michael@0 173 Elf::Strtab strtab;
michael@0 174
michael@0 175 /* Symbol table */
michael@0 176 UnsizedArray<Elf::Sym> symtab;
michael@0 177
michael@0 178 /* Buckets and chains for the System V symbol hash table */
michael@0 179 Array<Elf::Word> buckets;
michael@0 180 UnsizedArray<Elf::Word> chains;
michael@0 181
michael@0 182 /* List of dependent libraries */
michael@0 183 std::vector<mozilla::RefPtr<LibHandle> > dependencies;
michael@0 184
michael@0 185 /* List of .rel.dyn/.rela.dyn relocations */
michael@0 186 Array<Elf::Reloc> relocations;
michael@0 187
michael@0 188 /* List of .rel.plt/.rela.plt relocation */
michael@0 189 Array<Elf::Reloc> jumprels;
michael@0 190
michael@0 191 /* Relative address of the initialization and destruction functions
michael@0 192 * (.init/.fini) */
michael@0 193 Elf::Addr init, fini;
michael@0 194
michael@0 195 /* List of initialization and destruction functions
michael@0 196 * (.init_array/.fini_array) */
michael@0 197 Array<void *> init_array, fini_array;
michael@0 198
michael@0 199 bool initialized;
michael@0 200
michael@0 201 bool has_text_relocs;
michael@0 202
michael@0 203 #ifdef __ARM_EABI__
michael@0 204 /* ARM.exidx information used by FindExidx */
michael@0 205 Array<uint32_t[2]> arm_exidx;
michael@0 206 #endif
michael@0 207 };
michael@0 208
michael@0 209 #endif /* CustomElf_h */

mercurial