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