diff options
Diffstat (limited to 'mozglue/linker/BaseElf.h')
-rw-r--r-- | mozglue/linker/BaseElf.h | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/mozglue/linker/BaseElf.h b/mozglue/linker/BaseElf.h new file mode 100644 index 000000000..19f9061bc --- /dev/null +++ b/mozglue/linker/BaseElf.h @@ -0,0 +1,141 @@ +/* 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; + + 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: + 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 */ |