diff options
Diffstat (limited to 'mozglue/linker/BaseElf.h')
-rw-r--r-- | mozglue/linker/BaseElf.h | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/mozglue/linker/BaseElf.h b/mozglue/linker/BaseElf.h new file mode 100644 index 0000000000..9569dbc579 --- /dev/null +++ b/mozglue/linker/BaseElf.h @@ -0,0 +1,128 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BaseElf_h +#define BaseElf_h + +#include "ElfLoader.h" +#include "Elfxx.h" + +/** + * Base class for ELF libraries. This class includes things that will be + * common between SystemElfs and CustomElfs. + */ +class BaseElf : public LibHandle { + public: + /** + * Hash function for symbol lookup, as defined in ELF standard for System V. + */ + static unsigned long Hash(const char* symbol); + + /** + * Returns the address corresponding to the given symbol name (with a + * pre-computed hash). + */ + void* GetSymbolPtr(const char* symbol, unsigned long hash) const; + + /** + * Returns a pointer to the Elf Symbol in the Dynamic Symbol table + * corresponding to the given symbol name (with a pre-computed hash). + */ + const Elf::Sym* GetSymbol(const char* symbol, unsigned long hash) const; + + explicit BaseElf(const char* path, Mappable* mappable = nullptr) + : LibHandle(path), mappable(mappable) {} + + protected: + /** + * Inherited from LibHandle. Those are temporary and are not supposed to + * be used. + */ + virtual void* GetSymbolPtr(const char* symbol) const; + virtual bool Contains(void* addr) const; + virtual void* GetBase() const { return GetPtr(0); } + +#ifdef __ARM_EABI__ + virtual const void* FindExidx(int* pcount) const; +#endif + + virtual Mappable* GetMappable() const { return NULL; }; + + public: + /* private: */ + /** + * Returns a pointer relative to the base address where the library is + * loaded. + */ + void* GetPtr(const Elf::Addr offset) const { + if (reinterpret_cast<void*>(offset) > base) + return reinterpret_cast<void*>(offset); + return base + offset; + } + + /** + * Like the above, but returns a typed (const) pointer + */ + template <typename T> + const T* GetPtr(const Elf::Addr offset) const { + if (reinterpret_cast<void*>(offset) > base) + return reinterpret_cast<const T*>(offset); + return reinterpret_cast<const T*>(base + offset); + } + + /* Appropriated Mappable */ + /* /!\ we rely on this being nullptr for BaseElf instances, but not + * CustomElf instances. */ + RefPtr<Mappable> mappable; + + /* Base address where the library is loaded */ + MappedPtr base; + + /* Buckets and chains for the System V symbol hash table */ + Array<Elf::Word> buckets; + UnsizedArray<Elf::Word> chains; + + /* protected: */ + /* String table */ + Elf::Strtab strtab; + + /* Symbol table */ + UnsizedArray<Elf::Sym> symtab; + +#ifdef __ARM_EABI__ + /* ARM.exidx information used by FindExidx */ + Array<uint32_t[2]> arm_exidx; +#endif +}; + +/** + * Class for ELF libraries that already loaded in memory. + */ +class LoadedElf : public BaseElf { + public: + /** + * Returns a LoadedElf corresponding to the already loaded ELF + * at the given base address. + */ + static already_AddRefed<LibHandle> Create(const char* path, void* base_addr); + + private: + explicit LoadedElf(const char* path) : BaseElf(path) {} + + ~LoadedElf() { + /* Avoid base's destructor unmapping something that doesn't actually + * belong to it. */ + base.release(); + ElfLoader::Singleton.Forget(this); + } + + /** + * Initializes the library according to information found in the given + * PT_DYNAMIC header. + * Returns whether this succeeded or failed. + */ + bool InitDyn(const Elf::Phdr* pt_dyn); +}; + +#endif /* BaseElf_h */ |