1 /*
2 * Copyright 2011, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ELF_OBJECT_HXX
18 #define ELF_OBJECT_HXX
19
20 #include "ELFHeader.h"
21 #include "ELFReloc.h"
22 #include "ELFSection.h"
23 #include "ELFSectionHeaderTable.h"
24 #include "StubLayout.h"
25 #include "ELF.h"
26
27 #include <llvm/ADT/SmallVector.h>
28
29 #include "utils/rsl_assert.h"
30
31 template <unsigned Bitwidth>
32 template <typename Archiver>
33 inline ELFObject<Bitwidth> *
read(Archiver & AR)34 ELFObject<Bitwidth>::read(Archiver &AR) {
35 llvm::OwningPtr<ELFObjectTy> object(new ELFObjectTy());
36
37 // Read header
38 object->header.reset(ELFHeaderTy::read(AR));
39 if (!object->header) {
40 return 0;
41 }
42
43 // Read section table
44 object->shtab.reset(ELFSectionHeaderTableTy::read(AR, object.get()));
45 if (!object->shtab) {
46 return 0;
47 }
48
49 // Read each section
50 llvm::SmallVector<size_t, 4> progbits_ndx;
51 for (size_t i = 0; i < object->header->getSectionHeaderNum(); ++i) {
52 if ((*object->shtab)[i]->getType() == SHT_PROGBITS) {
53 object->stab.push_back(NULL);
54 progbits_ndx.push_back(i);
55 } else {
56 llvm::OwningPtr<ELFSectionTy> sec(
57 ELFSectionTy::read(AR, object.get(), (*object->shtab)[i]));
58 object->stab.push_back(sec.take());
59 }
60 }
61
62 object->shtab->buildNameMap();
63 ELFSectionSymTabTy *symtab =
64 static_cast<ELFSectionSymTabTy *>(object->getSectionByName(".symtab"));
65 rsl_assert(symtab && "Symtab is required.");
66 symtab->buildNameMap();
67
68 for (size_t i = 0; i < progbits_ndx.size(); ++i) {
69 size_t index = progbits_ndx[i];
70
71 llvm::OwningPtr<ELFSectionTy> sec(
72 ELFSectionTy::read(AR, object.get(), (*object->shtab)[index]));
73 object->stab[index] = sec.take();
74 }
75
76 return object.take();
77 }
78
79 template <unsigned Bitwidth>
getSectionName(size_t i) const80 inline char const *ELFObject<Bitwidth>::getSectionName(size_t i) const {
81 ELFSectionTy const *sec = stab[header->getStringSectionIndex()];
82
83 if (sec) {
84 ELFSectionStrTabTy const &st =
85 static_cast<ELFSectionStrTabTy const &>(*sec);
86 return st[i];
87 }
88
89 return NULL;
90 }
91
92 template <unsigned Bitwidth>
93 inline ELFSection<Bitwidth> const *
getSectionByIndex(size_t i) const94 ELFObject<Bitwidth>::getSectionByIndex(size_t i) const {
95 return stab[i];
96 }
97
98 template <unsigned Bitwidth>
99 inline ELFSection<Bitwidth> *
getSectionByIndex(size_t i)100 ELFObject<Bitwidth>::getSectionByIndex(size_t i) {
101 return stab[i];
102 }
103
104 template <unsigned Bitwidth>
105 inline ELFSection<Bitwidth> const *
getSectionByName(std::string const & str) const106 ELFObject<Bitwidth>::getSectionByName(std::string const &str) const {
107 size_t idx = getSectionHeaderTable()->getByName(str)->getIndex();
108 return stab[idx];
109 }
110
111 template <unsigned Bitwidth>
112 inline ELFSection<Bitwidth> *
getSectionByName(std::string const & str)113 ELFObject<Bitwidth>::getSectionByName(std::string const &str) {
114 ELFObjectTy const *const_this = this;
115 ELFSectionTy const *sptr = const_this->getSectionByName(str);
116 // Const cast for the same API's const and non-const versions.
117 return const_cast<ELFSectionTy *>(sptr);
118 }
119
120
121 template <unsigned Bitwidth>
122 inline void ELFObject<Bitwidth>::
relocateARM(void * (* find_sym)(void * context,char const * name),void * context,ELFSectionRelTableTy * reltab,ELFSectionProgBitsTy * text)123 relocateARM(void *(*find_sym)(void *context, char const *name),
124 void *context,
125 ELFSectionRelTableTy *reltab,
126 ELFSectionProgBitsTy *text) {
127 // FIXME: Should be implement in independent files.
128 rsl_assert(Bitwidth == 32 && "ARM only have 32 bits.");
129
130 ELFSectionSymTabTy *symtab =
131 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
132 rsl_assert(symtab && "Symtab is required.");
133
134 for (size_t i = 0; i < reltab->size(); ++i) {
135 // FIXME: Can not implement here, use Fixup!
136 ELFRelocTy *rel = (*reltab)[i];
137 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
138
139 // FIXME: May be not uint32_t *.
140 typedef int32_t Inst_t;
141 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
142 Inst_t P = (Inst_t)(int64_t)inst;
143 Inst_t A = 0;
144 Inst_t S = (Inst_t)(int64_t)sym->getAddress();
145
146 switch (rel->getType()) {
147 default:
148 rsl_assert(0 && "Not implemented relocation type.");
149 break;
150
151 case R_ARM_ABS32:
152 {
153 A = *inst;
154 *inst = (S+A);
155 }
156 break;
157
158 // FIXME: Predefine relocation codes.
159 case R_ARM_CALL:
160 {
161 #define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1)))
162 A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24);
163 #undef SIGN_EXTEND
164
165 switch (sym->getType()) {
166 default:
167 rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
168 abort();
169 break;
170
171 case STT_FUNC:
172 if (S == 0) {
173 rsl_assert(0 && "We should get function address at previous "
174 "sym->getAddress() function call.");
175 abort();
176 }
177 break;
178
179 case STT_NOTYPE:
180 if (S == 0) {
181 void *ext_func = find_sym(context, sym->getName());
182 #ifdef SUPPORT_NEAR_JUMP_EVEN_IF_BLc2BLX_NEEDED
183 S = (Inst_t)(uintptr_t)ext_func;
184 sym->setAddress(ext_func);
185
186 uint32_t result = (S >> 2) - (P >> 2) + A;
187 if (result > 0x007fffff && result < 0xff800000) {
188 #endif
189 #ifndef __arm__
190 // We have not implement function stub in this runtime env
191 rsl_assert(0 && "Target address is far from call instruction");
192 abort();
193 #else
194 void *stub = text->getStubLayout()->allocateStub(ext_func);
195 if (!stub) {
196 llvm::errs() << "unable to allocate stub." << "\n";
197 exit(EXIT_FAILURE);
198 }
199
200 //out() << "stub: for " << ext_func << " at " << stub << "\n";
201 sym->setAddress(stub);
202 S = (uint32_t)stub;
203 #endif
204 #ifdef SUPPORT_NEAR_JUMP_EVEN_IF_BLc2BLX_NEEDED
205 }
206 #endif
207 }
208 break;
209 }
210
211 uint32_t result = (S >> 2) - (P >> 2) + A;
212
213 if (result > 0x007fffff && result < 0xff800000) {
214 rsl_assert(0 && "Stub is still too far");
215 abort();
216 }
217
218 *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000);
219 }
220 break;
221 case R_ARM_MOVT_ABS:
222 case R_ARM_MOVW_ABS_NC:
223 {
224 if (S==0 && sym->getType() == STT_NOTYPE)
225 {
226 void *ext_sym = find_sym(context, sym->getName());
227 S = (Inst_t)(uintptr_t)ext_sym;
228 sym->setAddress(ext_sym);
229 }
230 if (rel->getType() == R_ARM_MOVT_ABS) {
231 S >>= 16;
232 }
233
234 // No need sign extend.
235 A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF);
236 uint32_t result = (S+A);
237 *inst = (((result) & 0xF000) << 4) |
238 ((result) & 0xFFF) |
239 (*inst & 0xFFF0F000);
240 }
241 break;
242 }
243 //llvm::errs() << "S: " << (void *)S << '\n';
244 //llvm::errs() << "A: " << (void *)A << '\n';
245 //llvm::errs() << "P: " << (void *)P << '\n';
246 //llvm::errs() << "S+A: " << (void *)(S+A) << '\n';
247 //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n';
248 }
249 }
250
251 template <unsigned Bitwidth>
252 inline void ELFObject<Bitwidth>::
relocateX86_64(void * (* find_sym)(void * context,char const * name),void * context,ELFSectionRelTableTy * reltab,ELFSectionProgBitsTy * text)253 relocateX86_64(void *(*find_sym)(void *context, char const *name),
254 void *context,
255 ELFSectionRelTableTy *reltab,
256 ELFSectionProgBitsTy *text) {
257 rsl_assert(Bitwidth == 64 && "Only support X86_64.");
258
259 ELFSectionSymTabTy *symtab =
260 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
261 rsl_assert(symtab && "Symtab is required.");
262
263 for (size_t i = 0; i < reltab->size(); ++i) {
264 // FIXME: Can not implement here, use Fixup!
265 ELFRelocTy *rel = (*reltab)[i];
266 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
267
268 //typedef uint64_t Inst_t;
269 typedef int32_t Inst_t;
270 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
271 Inst_t P = (Inst_t)(int64_t)inst;
272 Inst_t A = (Inst_t)(int64_t)rel->getAddend();
273 Inst_t S = (Inst_t)(int64_t)sym->getAddress();
274
275 if (S == 0) {
276 S = (Inst_t)(int64_t)find_sym(context, sym->getName());
277 sym->setAddress((void *)S);
278 }
279
280 switch (rel->getType()) {
281 default:
282 rsl_assert(0 && "Not implemented relocation type.");
283 break;
284
285 // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here.
286 case 1: // R_X86_64_64
287 *inst = (S+A);
288 break;
289
290 case 2: // R_X86_64_PC32
291 *inst = (S+A-P);
292 break;
293
294 case 10: // R_X86_64_32
295 case 11: // R_X86_64_32S
296 *inst = (S+A);
297 break;
298 }
299 }
300 }
301
302 template <unsigned Bitwidth>
303 inline void ELFObject<Bitwidth>::
relocateX86_32(void * (* find_sym)(void * context,char const * name),void * context,ELFSectionRelTableTy * reltab,ELFSectionProgBitsTy * text)304 relocateX86_32(void *(*find_sym)(void *context, char const *name),
305 void *context,
306 ELFSectionRelTableTy *reltab,
307 ELFSectionProgBitsTy *text) {
308 rsl_assert(Bitwidth == 32 && "Only support X86.");
309
310 ELFSectionSymTabTy *symtab =
311 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
312 rsl_assert(symtab && "Symtab is required.");
313
314 for (size_t i = 0; i < reltab->size(); ++i) {
315 // FIXME: Can not implement here, use Fixup!
316 ELFRelocTy *rel = (*reltab)[i];
317 ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
318
319 //typedef uint64_t Inst_t;
320 typedef int32_t Inst_t;
321 Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
322 Inst_t P = (Inst_t)(uintptr_t)inst;
323 Inst_t A = (Inst_t)(uintptr_t)*inst;
324 Inst_t S = (Inst_t)(uintptr_t)sym->getAddress();
325
326 if (S == 0) {
327 S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
328 sym->setAddress((void *)S);
329 }
330
331 switch (rel->getType()) {
332 default:
333 rsl_assert(0 && "Not implemented relocation type.");
334 break;
335
336 case R_386_PC32:
337 *inst = (S+A-P);
338 break;
339
340 case R_386_32:
341 *inst = (S+A);
342 break;
343 }
344 }
345 }
346
347 // TODO: Refactor all relocations.
348 template <unsigned Bitwidth>
349 inline void ELFObject<Bitwidth>::
relocate(void * (* find_sym)(void * context,char const * name),void * context)350 relocate(void *(*find_sym)(void *context, char const *name), void *context) {
351 // Init SHNCommonDataSize.
352 // Need refactoring
353 size_t SHNCommonDataSize = 0;
354
355 ELFSectionSymTabTy *symtab =
356 static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
357 rsl_assert(symtab && "Symtab is required.");
358
359 for (size_t i = 0; i < symtab->size(); ++i) {
360 ELFSymbolTy *sym = (*symtab)[i];
361
362 if (sym->getType() != STT_OBJECT) {
363 continue;
364 }
365
366 size_t idx = (size_t)sym->getSectionIndex();
367 switch (idx) {
368 default:
369 if ((*shtab)[idx]->getType() == SHT_NOBITS) {
370 // FIXME(logan): This is a workaround for .lcomm directives
371 // bug of LLVM ARM MC code generator. Remove this when the
372 // LLVM bug is fixed.
373
374 size_t align = 16;
375 SHNCommonDataSize += (size_t)sym->getSize() + align;
376 }
377 break;
378
379 case SHN_COMMON:
380 {
381 size_t align = (size_t)sym->getValue();
382 SHNCommonDataSize += (size_t)sym->getSize() + align;
383 }
384 break;
385
386 case SHN_ABS:
387 case SHN_UNDEF:
388 case SHN_XINDEX:
389 break;
390 }
391 }
392 if (!initSHNCommonDataSize(SHNCommonDataSize)) {
393 rsl_assert("Allocate memory for common variable fail!");
394 }
395
396 for (size_t i = 0; i < stab.size(); ++i) {
397 ELFSectionHeaderTy *sh = (*shtab)[i];
398 if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) {
399 continue;
400 }
401 ELFSectionRelTableTy *reltab =
402 static_cast<ELFSectionRelTableTy *>(stab[i]);
403 rsl_assert(reltab && "Relocation section can't be NULL.");
404
405 const char *reltab_name = sh->getName();
406 const char *need_rel_name;
407 if (sh->getType() == SHT_REL) {
408 need_rel_name = reltab_name + 4;
409 // ".rel.xxxx"
410 // ^ start from here.
411 } else {
412 need_rel_name = reltab_name + 5;
413 }
414
415 ELFSectionProgBitsTy *need_rel =
416 static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name));
417 rsl_assert(need_rel && "Need be relocated section can't be NULL.");
418
419 switch (getHeader()->getMachine()) {
420 case EM_ARM:
421 relocateARM(find_sym, context, reltab, need_rel);
422 break;
423 case EM_386:
424 relocateX86_32(find_sym, context, reltab, need_rel);
425 break;
426 case EM_X86_64:
427 relocateX86_64(find_sym, context, reltab, need_rel);
428 break;
429
430 default:
431 rsl_assert(0 && "Only support ARM, X86, and X86_64 relocation.");
432 break;
433 }
434 }
435
436 for (size_t i = 0; i < stab.size(); ++i) {
437 ELFSectionHeaderTy *sh = (*shtab)[i];
438 if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) {
439 if (stab[i]) {
440 static_cast<ELFSectionBitsTy *>(stab[i])->protect();
441 }
442 }
443 }
444 }
445
446 template <unsigned Bitwidth>
print() const447 inline void ELFObject<Bitwidth>::print() const {
448 header->print();
449 shtab->print();
450
451 for (size_t i = 0; i < stab.size(); ++i) {
452 ELFSectionTy *sec = stab[i];
453 if (sec) {
454 sec->print();
455 }
456 }
457 }
458
459 #endif // ELF_OBJECT_HXX
460