ELFObject.hxx revision 59411237b1aacabd1dbe36cb4b073a4ac9caab6d
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    Inst_t T = 0;
147
148    if (sym->isConcreteFunc() && (sym->getValue() & 0x1)) {
149      T = 1;
150    }
151
152    switch (rel->getType()) {
153    default:
154      rsl_assert(0 && "Not implemented relocation type.");
155      break;
156
157    case R_ARM_ABS32:
158      {
159        A = *inst;
160        *inst = (S + A) | T;
161      }
162      break;
163
164      // FIXME: Predefine relocation codes.
165    case R_ARM_CALL:
166    case R_ARM_THM_CALL:
167      {
168#define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1)))
169        if (rel->getType() == R_ARM_CALL) {
170          A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24);
171          A <<= 2;
172        }
173        else {
174          // Hack for two 16bit.
175          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
176          Inst_t s  = (*inst >> 26) & 0x1u,    // 26
177                 u  = (*inst >> 16) & 0x3FFu,  // 25-16
178                 l  =  *inst        & 0x7FFu, // 10-0
179                 j1 = (*inst >> 13) & 0x1u,    // 13
180                 j2 = (*inst >> 11) & 0x1u;    // 11
181          Inst_t i1 = (~(j1 ^ s)) & 0x1u,
182                 i2 = (~(j2 ^ s)) & 0x1u;
183          // [31-25][24][23][22][21-12][11-1][0]
184          //      0   s  i1  i2      u     l  0
185          A = SIGN_EXTEND((s << 23) | (i1 << 22) | (i2 << 21) | (u << 11) | l, 24);
186          A <<= 1;
187        }
188#undef SIGN_EXTEND
189
190        void *callee_addr = sym->getAddress(EM_ARM);
191
192        switch (sym->getType()) {
193        default:
194          rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
195          abort();
196          break;
197
198        case STT_FUNC:
199          // NOTE: Callee function is in the object file, but it may be
200          // in different PROGBITS section (which may be far call).
201
202          if (callee_addr == 0) {
203            rsl_assert(0 && "We should get function address at previous "
204                   "sym->getAddress(EM_ARM) function call.");
205            abort();
206          }
207          break;
208
209        case STT_NOTYPE:
210          // NOTE: Callee function is an external function.  Call find_sym
211          // if it has not resolved yet.
212
213          if (callee_addr == 0) {
214            callee_addr = find_sym(context, sym->getName());
215            if (!callee_addr) {
216              missingSymbols = true;
217            }
218            sym->setAddress(callee_addr);
219          }
220          break;
221        }
222
223        // Get the stub for this function
224        StubLayout *stub_layout = text->getStubLayout();
225
226        if (!stub_layout) {
227          llvm::errs() << "unable to get stub layout." << "\n";
228          abort();
229        }
230
231        void *stub = stub_layout->allocateStub(callee_addr);
232
233        if (!stub) {
234          llvm::errs() << "unable to allocate stub." << "\n";
235          abort();
236        }
237
238        //LOGI("Function %s: using stub %p\n", sym->getName(), stub);
239        S = (uint32_t)(uintptr_t)stub;
240
241        if (rel->getType() == R_ARM_CALL) {
242          // Relocate the R_ARM_CALL relocation type
243          uint32_t result = (S + A - P) >> 2;
244
245          if (result > 0x007FFFFF && result < 0xFF800000) {
246            rsl_assert(0 && "Stub is still too far");
247            abort();
248          }
249
250          *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000);
251        }
252        else {
253          P &= ~0x3;  // Base address align to 4 bytes.(For BLX.)
254
255          // Relocate the R_ARM_THM_CALL relocation type
256          uint32_t result = (S + A - P) >> 1;
257
258          if (result > 0x007FFFFF && result < 0xFF800000) {
259            rsl_assert(0 && "Stub is still too far");
260            abort();
261          }
262
263          //*inst &= 0xF800D000u;
264          // Rewrite instruction to BLX.(Stub is always ARM.)
265          *inst &= 0xF800C000u;
266          // [31-25][24][23][22][21-12][11-1][0]
267          //      0   s  i1  i2      u     l  0
268          Inst_t s  = (result >> 23) & 0x1u,   // 26
269                 u  = (result >> 11) & 0x3FFu, // 25-16
270                 // For BLX, bit [0] is 0.
271                 l  =  result        & 0x7FEu, // 10-0
272                 i1 = (result >> 22) & 0x1u,
273                 i2 = (result >> 21) & 0x1u;
274          Inst_t j1 = ((~i1) ^ s) & 0x01u,       // 13
275                 j2 = ((~i2) ^ s) & 0x01u;       // 11
276          *inst |= s << 26;
277          *inst |= u << 16;
278          *inst |= l;
279          *inst |= j1 << 13;
280          *inst |= j2 << 11;
281          // Hack for two 16bit.
282          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
283        }
284      }
285      break;
286    case R_ARM_MOVT_ABS:
287    case R_ARM_MOVW_ABS_NC:
288    case R_ARM_THM_MOVW_ABS_NC:
289    case R_ARM_THM_MOVT_ABS:
290      {
291        if (S==0 && sym->getType() == STT_NOTYPE)
292        {
293          void *ext_sym = find_sym(context, sym->getName());
294          if (!ext_sym) {
295            missingSymbols = true;
296          }
297          S = (Inst_t)(uintptr_t)ext_sym;
298          sym->setAddress(ext_sym);
299        }
300        if (rel->getType() == R_ARM_MOVT_ABS
301            || rel->getType() == R_ARM_THM_MOVT_ABS) {
302          S >>= 16;
303        }
304
305        if (rel->getType() == R_ARM_MOVT_ABS
306            || rel->getType() == R_ARM_MOVW_ABS_NC) {
307          // No need sign extend.
308          A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF);
309          uint32_t result = (S + A);
310          *inst = (((result) & 0xF000) << 4) |
311            ((result) & 0xFFF) |
312            (*inst & 0xFFF0F000);
313        }
314        else {
315          // Hack for two 16bit.
316          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
317          // imm16: [19-16][26][14-12][7-0]
318          A = (((*inst >>  4) & 0xF000u) |
319               ((*inst >> 15) & 0x0800u) |
320               ((*inst >>  4) & 0x0700u) |
321               ( *inst        & 0x00FFu));
322          uint32_t result;
323          if (rel->getType() == R_ARM_THM_MOVT_ABS) {
324            result = (S + A);
325          } else {
326            result = (S + A) | T;
327          }
328          // imm16: [19-16][26][14-12][7-0]
329          *inst &= 0xFBF08F00u;
330          *inst |= (result & 0xF000u) << 4;
331          *inst |= (result & 0x0800u) << 15;
332          *inst |= (result & 0x0700u) << 4;
333          *inst |= (result & 0x00FFu);
334          // Hack for two 16bit.
335          *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
336        }
337      }
338      break;
339    }
340    //llvm::errs() << "S:     " << (void *)S << '\n';
341    //llvm::errs() << "A:     " << (void *)A << '\n';
342    //llvm::errs() << "P:     " << (void *)P << '\n';
343    //llvm::errs() << "S+A:   " << (void *)(S+A) << '\n';
344    //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n';
345  }
346}
347
348template <unsigned Bitwidth>
349inline void ELFObject<Bitwidth>::
350relocateX86_64(void *(*find_sym)(void *context, char const *name),
351               void *context,
352               ELFSectionRelTableTy *reltab,
353               ELFSectionProgBitsTy *text) {
354  rsl_assert(Bitwidth == 64 && "Only support X86_64.");
355
356  ELFSectionSymTabTy *symtab =
357    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
358  rsl_assert(symtab && "Symtab is required.");
359
360  for (size_t i = 0; i < reltab->size(); ++i) {
361    // FIXME: Can not implement here, use Fixup!
362    ELFRelocTy *rel = (*reltab)[i];
363    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
364
365    //typedef uint64_t Inst_t;
366    typedef int32_t Inst_t;
367    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
368    Inst_t P = (Inst_t)(int64_t)inst;
369    Inst_t A = (Inst_t)(int64_t)rel->getAddend();
370    Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_X86_64);
371
372    if (S == 0) {
373      S = (Inst_t)(int64_t)find_sym(context, sym->getName());
374      if (!S) {
375        missingSymbols = true;
376      }
377      sym->setAddress((void *)S);
378    }
379
380    switch (rel->getType()) {
381      default:
382        rsl_assert(0 && "Not implemented relocation type.");
383        break;
384
385      // FIXME: XXX: R_X86_64_64 is 64 bit, there is a big problem here.
386      case 1: // R_X86_64_64
387        *inst = (S+A);
388        break;
389
390      case 2: // R_X86_64_PC32
391        *inst = (S+A-P);
392        break;
393
394      case 10: // R_X86_64_32
395      case 11: // R_X86_64_32S
396        *inst = (S+A);
397        break;
398    }
399  }
400}
401
402template <unsigned Bitwidth>
403inline void ELFObject<Bitwidth>::
404relocateX86_32(void *(*find_sym)(void *context, char const *name),
405               void *context,
406               ELFSectionRelTableTy *reltab,
407               ELFSectionProgBitsTy *text) {
408  rsl_assert(Bitwidth == 32 && "Only support X86.");
409
410  ELFSectionSymTabTy *symtab =
411    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
412  rsl_assert(symtab && "Symtab is required.");
413
414  for (size_t i = 0; i < reltab->size(); ++i) {
415    // FIXME: Can not implement here, use Fixup!
416    ELFRelocTy *rel = (*reltab)[i];
417    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
418
419    //typedef uint64_t Inst_t;
420    typedef int32_t Inst_t;
421    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
422    Inst_t P = (Inst_t)(uintptr_t)inst;
423    Inst_t A = (Inst_t)(uintptr_t)*inst;
424    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_386);
425
426    if (S == 0) {
427      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
428      if (!S) {
429        missingSymbols = true;
430      }
431      sym->setAddress((void *)S);
432    }
433
434    switch (rel->getType()) {
435    default:
436      rsl_assert(0 && "Not implemented relocation type.");
437      break;
438
439    case R_386_PC32:
440      *inst = (S+A-P);
441      break;
442
443    case R_386_32:
444      *inst = (S+A);
445      break;
446    }
447  }
448}
449
450template <unsigned Bitwidth>
451inline void ELFObject<Bitwidth>::
452relocateMIPS(void *(*find_sym)(void *context, char const *name),
453             void *context,
454             ELFSectionRelTableTy *reltab,
455             ELFSectionProgBitsTy *text) {
456  rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS.");
457
458  ELFSectionSymTabTy *symtab =
459    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
460  rsl_assert(symtab && "Symtab is required.");
461
462  for (size_t i = 0; i < reltab->size(); ++i) {
463    // FIXME: Can not implement here, use Fixup!
464    ELFRelocTy *rel = (*reltab)[i];
465    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
466
467    typedef int32_t Inst_t;
468    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
469    Inst_t P = (Inst_t)(uintptr_t)inst;
470    Inst_t A = (Inst_t)(uintptr_t)*inst;
471    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_MIPS);
472
473    bool need_stub = false;
474
475    if (S == 0 && strcmp (sym->getName(), "_gp_disp") != 0) {
476      need_stub = true;
477      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
478      if (!S) {
479        missingSymbols = true;
480      }
481      sym->setAddress((void *)S);
482    }
483
484    switch (rel->getType()) {
485    default:
486      rsl_assert(0 && "Not implemented relocation type.");
487      break;
488
489    case R_MIPS_NONE:
490    case R_MIPS_JALR: // ignore this
491      break;
492
493    case R_MIPS_16:
494      *inst &= 0xFFFF0000;
495      A = A & 0xFFFF;
496      A = S + (short)A;
497      rsl_assert(A >= -32768 && A <= 32767 && "R_MIPS_16 overflow.");
498      *inst |= (A & 0xFFFF);
499      break;
500
501    case R_MIPS_32:
502      *inst = S + A;
503      break;
504
505    case R_MIPS_26:
506      *inst &= 0xFC000000;
507      if (need_stub == false) {
508        A = (A & 0x3FFFFFF) << 2;
509        if (sym->getBindingAttribute() == STB_LOCAL) { // local binding
510          A |= ((P + 4) & 0xF0000000);
511          A += S;
512          *inst |= ((A >> 2) & 0x3FFFFFF);
513        }
514        else { // external binding
515          if (A & 0x08000000) // Sign extend from bit 27
516            A |= 0xF0000000;
517          A += S;
518          *inst |= ((A >> 2) & 0x3FFFFFF);
519          if (((P + 4) >> 28) != (A >> 28)) { // far local call
520            void *stub = text->getStubLayout()->allocateStub((void *)A);
521            rsl_assert(stub && "cannot allocate stub.");
522            sym->setAddress(stub);
523            S = (int32_t)(intptr_t)stub;
524            *inst |= ((S >> 2) & 0x3FFFFFF);
525            rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
526          }
527        }
528      }
529      else { // shared-library call
530        A = (A & 0x3FFFFFF) << 2;
531        rsl_assert(A == 0 && "R_MIPS_26 addend is not zero.");
532        void *stub = text->getStubLayout()->allocateStub((void *)S);
533        rsl_assert(stub && "cannot allocate stub.");
534        sym->setAddress(stub);
535        S = (int32_t)(intptr_t)stub;
536        *inst |= ((S >> 2) & 0x3FFFFFF);
537        rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
538      }
539      break;
540
541    case R_MIPS_HI16:
542      *inst &= 0xFFFF0000;
543      A = (A & 0xFFFF) << 16;
544      // Find the nearest LO16 relocation type after this entry
545      for (size_t j = i + 1; j < reltab->size(); j++) {
546        ELFRelocTy *this_rel = (*reltab)[j];
547        ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
548        if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
549          Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
550          Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
551          this_A = this_A & 0xFFFF;
552          A += (short)this_A;
553          break;
554        }
555      }
556      if (strcmp (sym->getName(), "_gp_disp") == 0) {
557          S = (int)(intptr_t)got_address() + GP_OFFSET - (int)P;
558          sym->setAddress((void *)S);
559      }
560      *inst |= (((S + A + (int)0x8000) >> 16) & 0xFFFF);
561      break;
562
563    case R_MIPS_LO16:
564      *inst &= 0xFFFF0000;
565      A = A & 0xFFFF;
566      if (strcmp (sym->getName(), "_gp_disp") == 0) {
567          S = (Inst_t)(intptr_t)sym->getAddress(EM_MIPS);
568      }
569      *inst |= ((S + A) & 0xFFFF);
570      break;
571
572    case R_MIPS_GOT16:
573    case R_MIPS_CALL16:
574      {
575        *inst &= 0xFFFF0000;
576        A = A & 0xFFFF;
577        if (rel->getType() == R_MIPS_GOT16) {
578          if (sym->getBindingAttribute() == STB_LOCAL) {
579            A <<= 16;
580
581            // Find the nearest LO16 relocation type after this entry
582            for (size_t j = i + 1; j < reltab->size(); j++) {
583              ELFRelocTy *this_rel = (*reltab)[j];
584              ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
585              if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
586                Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
587                Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
588                this_A = this_A & 0xFFFF;
589                A += (short)this_A;
590                break;
591              }
592            }
593          }
594          else {
595            rsl_assert(A == 0 && "R_MIPS_GOT16 addend is not 0.");
596          }
597        }
598        else { // R_MIPS_CALL16
599          rsl_assert(A == 0 && "R_MIPS_CALL16 addend is not 0.");
600        }
601        int got_index = search_got((int)rel->getSymTabIndex(), (void *)(S + A),
602                                   sym->getBindingAttribute());
603        int got_offset = (got_index << 2) - GP_OFFSET;
604        *inst |= (got_offset & 0xFFFF);
605      }
606      break;
607
608    case R_MIPS_GPREL32:
609      *inst = A + S - ((int)(intptr_t)got_address() + GP_OFFSET);
610      break;
611    }
612  }
613}
614
615
616// TODO: Refactor all relocations.
617template <unsigned Bitwidth>
618inline void ELFObject<Bitwidth>::
619relocate(void *(*find_sym)(void *context, char const *name), void *context) {
620  // Init SHNCommonDataSize.
621  // Need refactoring
622  size_t SHNCommonDataSize = 0;
623
624  ELFSectionSymTabTy *symtab =
625    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
626  rsl_assert(symtab && "Symtab is required.");
627
628  for (size_t i = 0; i < symtab->size(); ++i) {
629    ELFSymbolTy *sym = (*symtab)[i];
630
631    if (sym->getType() != STT_OBJECT) {
632      continue;
633    }
634
635    size_t idx = (size_t)sym->getSectionIndex();
636    switch (idx) {
637    default:
638      if ((*shtab)[idx]->getType() == SHT_NOBITS) {
639        // FIXME(logan): This is a workaround for .lcomm directives
640        // bug of LLVM ARM MC code generator.  Remove this when the
641        // LLVM bug is fixed.
642
643        size_t align = 16;
644        SHNCommonDataSize += (size_t)sym->getSize() + align;
645      }
646      break;
647
648    case SHN_COMMON:
649      {
650        size_t align = (size_t)sym->getValue();
651        SHNCommonDataSize += (size_t)sym->getSize() + align;
652      }
653      break;
654
655    case SHN_ABS:
656    case SHN_UNDEF:
657    case SHN_XINDEX:
658      break;
659    }
660  }
661  if (!initSHNCommonDataSize(SHNCommonDataSize)) {
662    rsl_assert("Allocate memory for common variable fail!");
663  }
664
665  for (size_t i = 0; i < stab.size(); ++i) {
666    ELFSectionHeaderTy *sh = (*shtab)[i];
667    if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) {
668      continue;
669    }
670    ELFSectionRelTableTy *reltab =
671      static_cast<ELFSectionRelTableTy *>(stab[i]);
672    rsl_assert(reltab && "Relocation section can't be NULL.");
673
674    const char *reltab_name = sh->getName();
675    const char *need_rel_name;
676    if (sh->getType() == SHT_REL) {
677      need_rel_name = reltab_name + 4;
678      // ".rel.xxxx"
679      //      ^ start from here.
680    } else {
681      need_rel_name = reltab_name + 5;
682    }
683
684    ELFSectionProgBitsTy *need_rel =
685      static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name));
686    rsl_assert(need_rel && "Need be relocated section can't be NULL.");
687
688    switch (getHeader()->getMachine()) {
689      case EM_ARM:
690        relocateARM(find_sym, context, reltab, need_rel);
691        break;
692      case EM_386:
693        relocateX86_32(find_sym, context, reltab, need_rel);
694        break;
695      case EM_X86_64:
696        relocateX86_64(find_sym, context, reltab, need_rel);
697        break;
698      case EM_MIPS:
699        relocateMIPS(find_sym, context, reltab, need_rel);
700        break;
701
702      default:
703        rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation.");
704        break;
705    }
706  }
707
708  for (size_t i = 0; i < stab.size(); ++i) {
709    ELFSectionHeaderTy *sh = (*shtab)[i];
710    if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) {
711      if (stab[i]) {
712        static_cast<ELFSectionBitsTy *>(stab[i])->protect();
713      }
714    }
715  }
716}
717
718template <unsigned Bitwidth>
719inline void ELFObject<Bitwidth>::print() const {
720  header->print();
721  shtab->print();
722
723  for (size_t i = 0; i < stab.size(); ++i) {
724    ELFSectionTy *sec = stab[i];
725    if (sec) {
726      sec->print();
727    }
728  }
729}
730
731#endif // ELF_OBJECT_HXX
732