ELFObject.hxx revision 9ed73923af9db7283a8c76b5dfa2dda5b732a852
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 "GOT.h"
26#include "ELF.h"
27
28#include <llvm/ADT/SmallVector.h>
29
30#include "utils/rsl_assert.h"
31
32template <unsigned Bitwidth>
33template <typename Archiver>
34inline ELFObject<Bitwidth> *
35ELFObject<Bitwidth>::read(Archiver &AR) {
36  llvm::OwningPtr<ELFObjectTy> object(new ELFObjectTy());
37
38  // Read header
39  object->header.reset(ELFHeaderTy::read(AR));
40  if (!object->header) {
41    return 0;
42  }
43
44  // Read section table
45  object->shtab.reset(ELFSectionHeaderTableTy::read(AR, object.get()));
46  if (!object->shtab) {
47    return 0;
48  }
49
50  // Read each section
51  llvm::SmallVector<size_t, 4> progbits_ndx;
52  for (size_t i = 0; i < object->header->getSectionHeaderNum(); ++i) {
53    if ((*object->shtab)[i]->getType() == SHT_PROGBITS) {
54      object->stab.push_back(NULL);
55      progbits_ndx.push_back(i);
56    } else {
57      llvm::OwningPtr<ELFSectionTy> sec(
58        ELFSectionTy::read(AR, object.get(), (*object->shtab)[i]));
59      object->stab.push_back(sec.take());
60    }
61  }
62
63  object->shtab->buildNameMap();
64  ELFSectionSymTabTy *symtab =
65    static_cast<ELFSectionSymTabTy *>(object->getSectionByName(".symtab"));
66  rsl_assert(symtab && "Symtab is required.");
67  symtab->buildNameMap();
68
69  for (size_t i = 0; i < progbits_ndx.size(); ++i) {
70    size_t index = progbits_ndx[i];
71
72    llvm::OwningPtr<ELFSectionTy> sec(
73      ELFSectionTy::read(AR, object.get(), (*object->shtab)[index]));
74    object->stab[index] = sec.take();
75  }
76
77  return object.take();
78}
79
80template <unsigned Bitwidth>
81inline char const *ELFObject<Bitwidth>::getSectionName(size_t i) const {
82  ELFSectionTy const *sec = stab[header->getStringSectionIndex()];
83
84  if (sec) {
85    ELFSectionStrTabTy const &st =
86      static_cast<ELFSectionStrTabTy const &>(*sec);
87    return st[i];
88  }
89
90  return NULL;
91}
92
93template <unsigned Bitwidth>
94inline ELFSection<Bitwidth> const *
95ELFObject<Bitwidth>::getSectionByIndex(size_t i) const {
96  return stab[i];
97}
98
99template <unsigned Bitwidth>
100inline ELFSection<Bitwidth> *
101ELFObject<Bitwidth>::getSectionByIndex(size_t i) {
102  return stab[i];
103}
104
105template <unsigned Bitwidth>
106inline ELFSection<Bitwidth> const *
107ELFObject<Bitwidth>::getSectionByName(std::string const &str) const {
108  size_t idx = getSectionHeaderTable()->getByName(str)->getIndex();
109  return stab[idx];
110}
111
112template <unsigned Bitwidth>
113inline ELFSection<Bitwidth> *
114ELFObject<Bitwidth>::getSectionByName(std::string const &str) {
115  ELFObjectTy const *const_this = this;
116  ELFSectionTy const *sptr = const_this->getSectionByName(str);
117  // Const cast for the same API's const and non-const versions.
118  return const_cast<ELFSectionTy *>(sptr);
119}
120
121
122template <unsigned Bitwidth>
123inline void ELFObject<Bitwidth>::
124relocateARM(void *(*find_sym)(void *context, char const *name),
125            void *context,
126            ELFSectionRelTableTy *reltab,
127            ELFSectionProgBitsTy *text) {
128  // FIXME: Should be implement in independent files.
129  rsl_assert(Bitwidth == 32 && "ARM only have 32 bits.");
130
131  ELFSectionSymTabTy *symtab =
132    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
133  rsl_assert(symtab && "Symtab is required.");
134
135  for (size_t i = 0; i < reltab->size(); ++i) {
136    // FIXME: Can not implement here, use Fixup!
137    ELFRelocTy *rel = (*reltab)[i];
138    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
139
140    // FIXME: May be not uint32_t *.
141    typedef int32_t Inst_t;
142    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
143    Inst_t P = (Inst_t)(int64_t)inst;
144    Inst_t A = 0;
145    Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_ARM);
146
147    switch (rel->getType()) {
148    default:
149      rsl_assert(0 && "Not implemented relocation type.");
150      break;
151
152    case R_ARM_ABS32:
153      {
154        A = *inst;
155        *inst = (S+A);
156      }
157      break;
158
159      // FIXME: Predefine relocation codes.
160    case R_ARM_CALL:
161      {
162#define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1)))
163        A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24);
164#undef SIGN_EXTEND
165
166        void *callee_addr = sym->getAddress(EM_ARM);
167
168        switch (sym->getType()) {
169        default:
170          rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
171          abort();
172          break;
173
174        case STT_FUNC:
175          // NOTE: Callee function is in the object file, but it may be
176          // in different PROGBITS section (which may be far call).
177
178          if (callee_addr == 0) {
179            rsl_assert(0 && "We should get function address at previous "
180                   "sym->getAddress(EM_ARM) function call.");
181            abort();
182          }
183          break;
184
185        case STT_NOTYPE:
186          // NOTE: Callee function is an external function.  Call find_sym
187          // if it has not resolved yet.
188
189          if (callee_addr == 0) {
190            callee_addr = find_sym(context, sym->getName());
191            sym->setAddress(callee_addr);
192          }
193          break;
194        }
195
196        // Get the stub for this function
197        StubLayout *stub_layout = text->getStubLayout();
198
199        if (!stub_layout) {
200          llvm::errs() << "unable to get stub layout." << "\n";
201          abort();
202        }
203
204        void *stub = stub_layout->allocateStub(callee_addr);
205
206        if (!stub) {
207          llvm::errs() << "unable to allocate stub." << "\n";
208          abort();
209        }
210
211        //LOGI("Function %s: using stub %p\n", sym->getName(), stub);
212        S = (uint32_t)(uintptr_t)stub;
213
214        // Relocate the R_ARM_CALL relocation type
215        uint32_t result = (S >> 2) - (P >> 2) + A;
216
217        if (result > 0x007fffff && result < 0xff800000) {
218          rsl_assert(0 && "Stub is still too far");
219          abort();
220        }
221
222        *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000);
223      }
224      break;
225    case R_ARM_MOVT_ABS:
226    case R_ARM_MOVW_ABS_NC:
227      {
228        if (S==0 && sym->getType() == STT_NOTYPE)
229        {
230          void *ext_sym = find_sym(context, sym->getName());
231          S = (Inst_t)(uintptr_t)ext_sym;
232          sym->setAddress(ext_sym);
233        }
234        if (rel->getType() == R_ARM_MOVT_ABS) {
235          S >>= 16;
236        }
237
238        // No need sign extend.
239        A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF);
240        uint32_t result = (S+A);
241        *inst = (((result) & 0xF000) << 4) |
242          ((result) & 0xFFF) |
243          (*inst & 0xFFF0F000);
244      }
245      break;
246    }
247    //llvm::errs() << "S:     " << (void *)S << '\n';
248    //llvm::errs() << "A:     " << (void *)A << '\n';
249    //llvm::errs() << "P:     " << (void *)P << '\n';
250    //llvm::errs() << "S+A:   " << (void *)(S+A) << '\n';
251    //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n';
252  }
253}
254
255template <unsigned Bitwidth>
256inline void ELFObject<Bitwidth>::
257relocateX86_64(void *(*find_sym)(void *context, char const *name),
258               void *context,
259               ELFSectionRelTableTy *reltab,
260               ELFSectionProgBitsTy *text) {
261  rsl_assert(Bitwidth == 64 && "Only support X86_64.");
262
263  ELFSectionSymTabTy *symtab =
264    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
265  rsl_assert(symtab && "Symtab is required.");
266
267  for (size_t i = 0; i < reltab->size(); ++i) {
268    // FIXME: Can not implement here, use Fixup!
269    ELFRelocTy *rel = (*reltab)[i];
270    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
271
272    //typedef uint64_t Inst_t;
273    typedef int32_t Inst_t;
274    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
275    Inst_t P = (Inst_t)(int64_t)inst;
276    Inst_t A = (Inst_t)(int64_t)rel->getAddend();
277    Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_X86_64);
278
279    if (S == 0) {
280      S = (Inst_t)(int64_t)find_sym(context, sym->getName());
281      sym->setAddress((void *)S);
282    }
283
284    switch (rel->getType()) {
285      default:
286        rsl_assert(0 && "Not implemented relocation type.");
287        break;
288
289      // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here.
290      case 1: // R_X86_64_64
291        *inst = (S+A);
292        break;
293
294      case 2: // R_X86_64_PC32
295        *inst = (S+A-P);
296        break;
297
298      case 10: // R_X86_64_32
299      case 11: // R_X86_64_32S
300        *inst = (S+A);
301        break;
302    }
303  }
304}
305
306template <unsigned Bitwidth>
307inline void ELFObject<Bitwidth>::
308relocateX86_32(void *(*find_sym)(void *context, char const *name),
309               void *context,
310               ELFSectionRelTableTy *reltab,
311               ELFSectionProgBitsTy *text) {
312  rsl_assert(Bitwidth == 32 && "Only support X86.");
313
314  ELFSectionSymTabTy *symtab =
315    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
316  rsl_assert(symtab && "Symtab is required.");
317
318  for (size_t i = 0; i < reltab->size(); ++i) {
319    // FIXME: Can not implement here, use Fixup!
320    ELFRelocTy *rel = (*reltab)[i];
321    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
322
323    //typedef uint64_t Inst_t;
324    typedef int32_t Inst_t;
325    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
326    Inst_t P = (Inst_t)(uintptr_t)inst;
327    Inst_t A = (Inst_t)(uintptr_t)*inst;
328    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_386);
329
330    if (S == 0) {
331      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
332      sym->setAddress((void *)S);
333    }
334
335    switch (rel->getType()) {
336    default:
337      rsl_assert(0 && "Not implemented relocation type.");
338      break;
339
340    case R_386_PC32:
341      *inst = (S+A-P);
342      break;
343
344    case R_386_32:
345      *inst = (S+A);
346      break;
347    }
348  }
349}
350
351template <unsigned Bitwidth>
352inline void ELFObject<Bitwidth>::
353relocateMIPS(void *(*find_sym)(void *context, char const *name),
354             void *context,
355             ELFSectionRelTableTy *reltab,
356             ELFSectionProgBitsTy *text) {
357  rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS.");
358
359  ELFSectionSymTabTy *symtab =
360    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
361  rsl_assert(symtab && "Symtab is required.");
362
363  for (size_t i = 0; i < reltab->size(); ++i) {
364    // FIXME: Can not implement here, use Fixup!
365    ELFRelocTy *rel = (*reltab)[i];
366    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
367
368    typedef int32_t Inst_t;
369    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
370    Inst_t P = (Inst_t)(uintptr_t)inst;
371    Inst_t A = (Inst_t)(uintptr_t)*inst;
372    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_MIPS);
373
374    bool need_stub = false;
375
376    if (S == 0 && strcmp (sym->getName(), "_gp_disp") != 0) {
377      need_stub = true;
378      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
379      sym->setAddress((void *)S);
380    }
381
382    switch (rel->getType()) {
383    default:
384      rsl_assert(0 && "Not implemented relocation type.");
385      break;
386
387    case R_MIPS_NONE:
388    case R_MIPS_JALR: // ignore this
389      break;
390
391    case R_MIPS_16:
392      *inst &= 0xFFFF0000;
393      A = A & 0xFFFF;
394      A = S + (short)A;
395      rsl_assert(A >= -32768 && A <= 32767 && "R_MIPS_16 overflow.");
396      *inst |= (A & 0xFFFF);
397      break;
398
399    case R_MIPS_32:
400      *inst = S + A;
401      break;
402
403    case R_MIPS_26:
404      *inst &= 0xFC000000;
405      if (need_stub == false) {
406        A = (A & 0x3FFFFFF) << 2;
407        if (sym->getBindingAttribute() == STB_LOCAL) { // local binding
408          A |= ((P + 4) & 0xF0000000);
409          A += S;
410          *inst |= ((A >> 2) & 0x3FFFFFF);
411        }
412        else { // external binding
413          if (A & 0x08000000) // Sign extend from bit 27
414            A |= 0xF0000000;
415          A += S;
416          *inst |= ((A >> 2) & 0x3FFFFFF);
417          if (((P + 4) >> 28) != (A >> 28)) { // far local call
418            void *stub = text->getStubLayout()->allocateStub((void *)A);
419            rsl_assert(stub && "cannot allocate stub.");
420            sym->setAddress(stub);
421            S = (int32_t)stub;
422            *inst |= ((S >> 2) & 0x3FFFFFF);
423            rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
424          }
425        }
426      }
427      else { // shared-library call
428        A = (A & 0x3FFFFFF) << 2;
429        rsl_assert(A == 0 && "R_MIPS_26 addend is not zero.");
430        void *stub = text->getStubLayout()->allocateStub((void *)S);
431        rsl_assert(stub && "cannot allocate stub.");
432        sym->setAddress(stub);
433        S = (int32_t)stub;
434        *inst |= ((S >> 2) & 0x3FFFFFF);
435        rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
436      }
437      break;
438
439    case R_MIPS_HI16:
440      *inst &= 0xFFFF0000;
441      A = (A & 0xFFFF) << 16;
442      // Find the nearest LO16 relocation type after this entry
443      for (size_t j = i + 1; j < reltab->size(); j++) {
444        ELFRelocTy *this_rel = (*reltab)[j];
445        ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
446        if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
447          Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
448          Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
449          this_A = this_A & 0xFFFF;
450          A += (short)this_A;
451          break;
452        }
453      }
454      if (strcmp (sym->getName(), "_gp_disp") == 0) {
455          S = (int)got_address() + GP_OFFSET - (int)P;
456          sym->setAddress((void *)S);
457      }
458      *inst |= (((S + A + (int)0x8000) >> 16) & 0xFFFF);
459      break;
460
461    case R_MIPS_LO16:
462      *inst &= 0xFFFF0000;
463      A = A & 0xFFFF;
464      if (strcmp (sym->getName(), "_gp_disp") == 0) {
465          S = (Inst_t)sym->getAddress(EM_MIPS);
466      }
467      *inst |= ((S + A) & 0xFFFF);
468      break;
469
470    case R_MIPS_GOT16:
471    case R_MIPS_CALL16:
472      {
473        *inst &= 0xFFFF0000;
474        A = A & 0xFFFF;
475        if (rel->getType() == R_MIPS_GOT16) {
476          if (sym->getBindingAttribute() == STB_LOCAL) {
477            A <<= 16;
478
479            // Find the nearest LO16 relocation type after this entry
480            for (size_t j = i + 1; j < reltab->size(); j++) {
481              ELFRelocTy *this_rel = (*reltab)[j];
482              ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
483              if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
484                Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
485                Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
486                this_A = this_A & 0xFFFF;
487                A += (short)this_A;
488                break;
489              }
490            }
491          }
492          else {
493            rsl_assert(A == 0 && "R_MIPS_GOT16 addend is not 0.");
494          }
495        }
496        else { // R_MIPS_CALL16
497          rsl_assert(A == 0 && "R_MIPS_CALL16 addend is not 0.");
498        }
499        int got_index = search_got((int)rel->getSymTabIndex(), (void *)(S + A),
500                                   sym->getBindingAttribute());
501        int got_offset = (got_index << 2) - GP_OFFSET;
502        *inst |= (got_offset & 0xFFFF);
503      }
504      break;
505
506    case R_MIPS_GPREL32:
507      *inst = A + S - ((int)got_address() + GP_OFFSET);
508      break;
509    }
510  }
511}
512
513
514// TODO: Refactor all relocations.
515template <unsigned Bitwidth>
516inline void ELFObject<Bitwidth>::
517relocate(void *(*find_sym)(void *context, char const *name), void *context) {
518  // Init SHNCommonDataSize.
519  // Need refactoring
520  size_t SHNCommonDataSize = 0;
521
522  ELFSectionSymTabTy *symtab =
523    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
524  rsl_assert(symtab && "Symtab is required.");
525
526  for (size_t i = 0; i < symtab->size(); ++i) {
527    ELFSymbolTy *sym = (*symtab)[i];
528
529    if (sym->getType() != STT_OBJECT) {
530      continue;
531    }
532
533    size_t idx = (size_t)sym->getSectionIndex();
534    switch (idx) {
535    default:
536      if ((*shtab)[idx]->getType() == SHT_NOBITS) {
537        // FIXME(logan): This is a workaround for .lcomm directives
538        // bug of LLVM ARM MC code generator.  Remove this when the
539        // LLVM bug is fixed.
540
541        size_t align = 16;
542        SHNCommonDataSize += (size_t)sym->getSize() + align;
543      }
544      break;
545
546    case SHN_COMMON:
547      {
548        size_t align = (size_t)sym->getValue();
549        SHNCommonDataSize += (size_t)sym->getSize() + align;
550      }
551      break;
552
553    case SHN_ABS:
554    case SHN_UNDEF:
555    case SHN_XINDEX:
556      break;
557    }
558  }
559  if (!initSHNCommonDataSize(SHNCommonDataSize)) {
560    rsl_assert("Allocate memory for common variable fail!");
561  }
562
563  for (size_t i = 0; i < stab.size(); ++i) {
564    ELFSectionHeaderTy *sh = (*shtab)[i];
565    if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) {
566      continue;
567    }
568    ELFSectionRelTableTy *reltab =
569      static_cast<ELFSectionRelTableTy *>(stab[i]);
570    rsl_assert(reltab && "Relocation section can't be NULL.");
571
572    const char *reltab_name = sh->getName();
573    const char *need_rel_name;
574    if (sh->getType() == SHT_REL) {
575      need_rel_name = reltab_name + 4;
576      // ".rel.xxxx"
577      //      ^ start from here.
578    } else {
579      need_rel_name = reltab_name + 5;
580    }
581
582    ELFSectionProgBitsTy *need_rel =
583      static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name));
584    rsl_assert(need_rel && "Need be relocated section can't be NULL.");
585
586    switch (getHeader()->getMachine()) {
587      case EM_ARM:
588        relocateARM(find_sym, context, reltab, need_rel);
589        break;
590      case EM_386:
591        relocateX86_32(find_sym, context, reltab, need_rel);
592        break;
593      case EM_X86_64:
594        relocateX86_64(find_sym, context, reltab, need_rel);
595        break;
596      case EM_MIPS:
597        relocateMIPS(find_sym, context, reltab, need_rel);
598        break;
599
600      default:
601        rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation.");
602        break;
603    }
604  }
605
606  for (size_t i = 0; i < stab.size(); ++i) {
607    ELFSectionHeaderTy *sh = (*shtab)[i];
608    if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) {
609      if (stab[i]) {
610        static_cast<ELFSectionBitsTy *>(stab[i])->protect();
611      }
612    }
613  }
614}
615
616template <unsigned Bitwidth>
617inline void ELFObject<Bitwidth>::print() const {
618  header->print();
619  shtab->print();
620
621  for (size_t i = 0; i < stab.size(); ++i) {
622    ELFSectionTy *sec = stab[i];
623    if (sec) {
624      sec->print();
625    }
626  }
627}
628
629#endif // ELF_OBJECT_HXX
630