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