ELFObject.hxx revision 72dca268900fa25946bade332f0fbdc2c2ff9487
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
31template <unsigned Bitwidth>
32template <typename Archiver>
33inline ELFObject<Bitwidth> *
34ELFObject<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
79template <unsigned Bitwidth>
80inline 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
92template <unsigned Bitwidth>
93inline ELFSection<Bitwidth> const *
94ELFObject<Bitwidth>::getSectionByIndex(size_t i) const {
95  return stab[i];
96}
97
98template <unsigned Bitwidth>
99inline ELFSection<Bitwidth> *
100ELFObject<Bitwidth>::getSectionByIndex(size_t i) {
101  return stab[i];
102}
103
104template <unsigned Bitwidth>
105inline ELFSection<Bitwidth> const *
106ELFObject<Bitwidth>::getSectionByName(std::string const &str) const {
107  size_t idx = getSectionHeaderTable()->getByName(str)->getIndex();
108  return stab[idx];
109}
110
111template <unsigned Bitwidth>
112inline ELFSection<Bitwidth> *
113ELFObject<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
121template <unsigned Bitwidth>
122inline void ELFObject<Bitwidth>::
123relocateARM(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        void *callee_addr = sym->getAddress();
166
167        switch (sym->getType()) {
168        default:
169          rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
170          abort();
171          break;
172
173        case STT_FUNC:
174          // NOTE: Callee function is in the object file, but it may be
175          // in different PROGBITS section (which may be far call).
176
177          if (callee_addr == 0) {
178            rsl_assert(0 && "We should get function address at previous "
179                   "sym->getAddress() function call.");
180            abort();
181          }
182          break;
183
184        case STT_NOTYPE:
185          // NOTE: Callee function is an external function.  Call find_sym
186          // if it has not resolved yet.
187
188          if (callee_addr == 0) {
189            callee_addr = find_sym(context, sym->getName());
190            sym->setAddress(callee_addr);
191          }
192          break;
193        }
194
195        // Get the stub for this function
196        StubLayout *stub_layout = text->getStubLayout();
197
198        if (!stub_layout) {
199          llvm::errs() << "unable to get stub layout." << "\n";
200          abort();
201        }
202
203        void *stub = stub_layout->allocateStub(callee_addr);
204
205        if (!stub) {
206          llvm::errs() << "unable to allocate stub." << "\n";
207          abort();
208        }
209
210        //LOGI("Function %s: using stub %p\n", sym->getName(), stub);
211        S = (uint32_t)(uintptr_t)stub;
212
213        // Relocate the R_ARM_CALL relocation type
214        uint32_t result = (S >> 2) - (P >> 2) + A;
215
216        if (result > 0x007fffff && result < 0xff800000) {
217          rsl_assert(0 && "Stub is still too far");
218          abort();
219        }
220
221        *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000);
222      }
223      break;
224    case R_ARM_MOVT_ABS:
225    case R_ARM_MOVW_ABS_NC:
226      {
227        if (S==0 && sym->getType() == STT_NOTYPE)
228        {
229          void *ext_sym = find_sym(context, sym->getName());
230          S = (Inst_t)(uintptr_t)ext_sym;
231          sym->setAddress(ext_sym);
232        }
233        if (rel->getType() == R_ARM_MOVT_ABS) {
234          S >>= 16;
235        }
236
237        // No need sign extend.
238        A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF);
239        uint32_t result = (S+A);
240        *inst = (((result) & 0xF000) << 4) |
241          ((result) & 0xFFF) |
242          (*inst & 0xFFF0F000);
243      }
244      break;
245    }
246    //llvm::errs() << "S:     " << (void *)S << '\n';
247    //llvm::errs() << "A:     " << (void *)A << '\n';
248    //llvm::errs() << "P:     " << (void *)P << '\n';
249    //llvm::errs() << "S+A:   " << (void *)(S+A) << '\n';
250    //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n';
251  }
252}
253
254template <unsigned Bitwidth>
255inline void ELFObject<Bitwidth>::
256relocateX86_64(void *(*find_sym)(void *context, char const *name),
257               void *context,
258               ELFSectionRelTableTy *reltab,
259               ELFSectionProgBitsTy *text) {
260  rsl_assert(Bitwidth == 64 && "Only support X86_64.");
261
262  ELFSectionSymTabTy *symtab =
263    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
264  rsl_assert(symtab && "Symtab is required.");
265
266  for (size_t i = 0; i < reltab->size(); ++i) {
267    // FIXME: Can not implement here, use Fixup!
268    ELFRelocTy *rel = (*reltab)[i];
269    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
270
271    //typedef uint64_t Inst_t;
272    typedef int32_t Inst_t;
273    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
274    Inst_t P = (Inst_t)(int64_t)inst;
275    Inst_t A = (Inst_t)(int64_t)rel->getAddend();
276    Inst_t S = (Inst_t)(int64_t)sym->getAddress();
277
278    if (S == 0) {
279      S = (Inst_t)(int64_t)find_sym(context, sym->getName());
280      sym->setAddress((void *)S);
281    }
282
283    switch (rel->getType()) {
284      default:
285        rsl_assert(0 && "Not implemented relocation type.");
286        break;
287
288      // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here.
289      case 1: // R_X86_64_64
290        *inst = (S+A);
291        break;
292
293      case 2: // R_X86_64_PC32
294        *inst = (S+A-P);
295        break;
296
297      case 10: // R_X86_64_32
298      case 11: // R_X86_64_32S
299        *inst = (S+A);
300        break;
301    }
302  }
303}
304
305template <unsigned Bitwidth>
306inline void ELFObject<Bitwidth>::
307relocateX86_32(void *(*find_sym)(void *context, char const *name),
308               void *context,
309               ELFSectionRelTableTy *reltab,
310               ELFSectionProgBitsTy *text) {
311  rsl_assert(Bitwidth == 32 && "Only support X86.");
312
313  ELFSectionSymTabTy *symtab =
314    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
315  rsl_assert(symtab && "Symtab is required.");
316
317  for (size_t i = 0; i < reltab->size(); ++i) {
318    // FIXME: Can not implement here, use Fixup!
319    ELFRelocTy *rel = (*reltab)[i];
320    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
321
322    //typedef uint64_t Inst_t;
323    typedef int32_t Inst_t;
324    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
325    Inst_t P = (Inst_t)(uintptr_t)inst;
326    Inst_t A = (Inst_t)(uintptr_t)*inst;
327    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress();
328
329    if (S == 0) {
330      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
331      sym->setAddress((void *)S);
332    }
333
334    switch (rel->getType()) {
335    default:
336      rsl_assert(0 && "Not implemented relocation type.");
337      break;
338
339    case R_386_PC32:
340      *inst = (S+A-P);
341      break;
342
343    case R_386_32:
344      *inst = (S+A);
345      break;
346    }
347  }
348}
349
350template <unsigned Bitwidth>
351inline void ELFObject<Bitwidth>::
352relocateMIPS(void *(*find_sym)(void *context, char const *name),
353             void *context,
354             ELFSectionRelTableTy *reltab,
355             ELFSectionProgBitsTy *text) {
356  rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS.");
357
358  ELFSectionSymTabTy *symtab =
359    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
360  rsl_assert(symtab && "Symtab is required.");
361
362  for (size_t i = 0; i < reltab->size(); ++i) {
363    // FIXME: Can not implement here, use Fixup!
364    ELFRelocTy *rel = (*reltab)[i];
365    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
366
367    typedef int32_t Inst_t;
368    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
369    Inst_t P = (Inst_t)(uintptr_t)inst;
370    Inst_t A = (Inst_t)(uintptr_t)*inst;
371    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress();
372
373    if (S == 0) {
374      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
375      sym->setAddress((void *)S);
376    }
377
378    switch (rel->getType()) {
379    default:
380      rsl_assert(0 && "Not implemented relocation type.");
381      break;
382
383    case R_MIPS_HI16:
384      A = A & 0xFFFF;
385      // FIXME: We just support addend = 0.
386      rsl_assert(A == 0 && "R_MIPS_HI16 addend is not 0.");
387      *inst |= (((S + 0x8000) >> 16) & 0xFFFF);
388      break;
389
390    case R_MIPS_LO16:
391      A = A & 0xFFFF;
392      // FIXME: We just support addend = 0.
393      rsl_assert(A == 0 && "R_MIPS_LO16 addend is not 0.");
394      *inst |= (S & 0xFFFF);
395      break;
396
397    case R_MIPS_26:
398      A = A & 0x3FFFFFF;
399      // FIXME: We just support addend = 0.
400      rsl_assert(A == 0 && "R_MIPS_26 addend is not 0.");
401      *inst |= ((S >> 2) & 0x3FFFFFF);
402      rsl_assert((((P + 4) >> 28) != (S >> 28)) && "Cannot relocate R_MIPS_26 due to differences in the upper four bits.");
403      break;
404
405    case R_MIPS_32:
406      *inst = S + A;
407      break;
408    }
409  }
410}
411
412
413// TODO: Refactor all relocations.
414template <unsigned Bitwidth>
415inline void ELFObject<Bitwidth>::
416relocate(void *(*find_sym)(void *context, char const *name), void *context) {
417  // Init SHNCommonDataSize.
418  // Need refactoring
419  size_t SHNCommonDataSize = 0;
420
421  ELFSectionSymTabTy *symtab =
422    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
423  rsl_assert(symtab && "Symtab is required.");
424
425  for (size_t i = 0; i < symtab->size(); ++i) {
426    ELFSymbolTy *sym = (*symtab)[i];
427
428    if (sym->getType() != STT_OBJECT) {
429      continue;
430    }
431
432    size_t idx = (size_t)sym->getSectionIndex();
433    switch (idx) {
434    default:
435      if ((*shtab)[idx]->getType() == SHT_NOBITS) {
436        // FIXME(logan): This is a workaround for .lcomm directives
437        // bug of LLVM ARM MC code generator.  Remove this when the
438        // LLVM bug is fixed.
439
440        size_t align = 16;
441        SHNCommonDataSize += (size_t)sym->getSize() + align;
442      }
443      break;
444
445    case SHN_COMMON:
446      {
447        size_t align = (size_t)sym->getValue();
448        SHNCommonDataSize += (size_t)sym->getSize() + align;
449      }
450      break;
451
452    case SHN_ABS:
453    case SHN_UNDEF:
454    case SHN_XINDEX:
455      break;
456    }
457  }
458  if (!initSHNCommonDataSize(SHNCommonDataSize)) {
459    rsl_assert("Allocate memory for common variable fail!");
460  }
461
462  for (size_t i = 0; i < stab.size(); ++i) {
463    ELFSectionHeaderTy *sh = (*shtab)[i];
464    if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) {
465      continue;
466    }
467    ELFSectionRelTableTy *reltab =
468      static_cast<ELFSectionRelTableTy *>(stab[i]);
469    rsl_assert(reltab && "Relocation section can't be NULL.");
470
471    const char *reltab_name = sh->getName();
472    const char *need_rel_name;
473    if (sh->getType() == SHT_REL) {
474      need_rel_name = reltab_name + 4;
475      // ".rel.xxxx"
476      //      ^ start from here.
477    } else {
478      need_rel_name = reltab_name + 5;
479    }
480
481    ELFSectionProgBitsTy *need_rel =
482      static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name));
483    rsl_assert(need_rel && "Need be relocated section can't be NULL.");
484
485    switch (getHeader()->getMachine()) {
486      case EM_ARM:
487        relocateARM(find_sym, context, reltab, need_rel);
488        break;
489      case EM_386:
490        relocateX86_32(find_sym, context, reltab, need_rel);
491        break;
492      case EM_X86_64:
493        relocateX86_64(find_sym, context, reltab, need_rel);
494        break;
495      case EM_MIPS:
496        relocateMIPS(find_sym, context, reltab, need_rel);
497        break;
498
499      default:
500        rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation.");
501        break;
502    }
503  }
504
505  for (size_t i = 0; i < stab.size(); ++i) {
506    ELFSectionHeaderTy *sh = (*shtab)[i];
507    if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) {
508      if (stab[i]) {
509        static_cast<ELFSectionBitsTy *>(stab[i])->protect();
510      }
511    }
512  }
513}
514
515template <unsigned Bitwidth>
516inline void ELFObject<Bitwidth>::print() const {
517  header->print();
518  shtab->print();
519
520  for (size_t i = 0; i < stab.size(); ++i) {
521    ELFSectionTy *sec = stab[i];
522    if (sec) {
523      sec->print();
524    }
525  }
526}
527
528#endif // ELF_OBJECT_HXX
529