ELFObject.hxx revision ec5d468bb925d7fe1aaa47b0cc4f084017531746
15cbbce535744b89df5ecea95de21ee3733298260Romain Guy/*
25cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Copyright 2011, The Android Open Source Project
35cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
45cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
55cbbce535744b89df5ecea95de21ee3733298260Romain Guy * you may not use this file except in compliance with the License.
65cbbce535744b89df5ecea95de21ee3733298260Romain Guy * You may obtain a copy of the License at
75cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
85cbbce535744b89df5ecea95de21ee3733298260Romain Guy *     http://www.apache.org/licenses/LICENSE-2.0
95cbbce535744b89df5ecea95de21ee3733298260Romain Guy *
105cbbce535744b89df5ecea95de21ee3733298260Romain Guy * Unless required by applicable law or agreed to in writing, software
115cbbce535744b89df5ecea95de21ee3733298260Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
125cbbce535744b89df5ecea95de21ee3733298260Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135cbbce535744b89df5ecea95de21ee3733298260Romain Guy * See the License for the specific language governing permissions and
145cbbce535744b89df5ecea95de21ee3733298260Romain Guy * limitations under the License.
155cbbce535744b89df5ecea95de21ee3733298260Romain Guy */
165cbbce535744b89df5ecea95de21ee3733298260Romain Guy
175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ELF_OBJECT_HXX
185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ELF_OBJECT_HXX
195cbbce535744b89df5ecea95de21ee3733298260Romain Guy
205cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "ELFHeader.h"
215cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "ELFReloc.h"
225cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "ELFSection.h"
235cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "ELFSectionHeaderTable.h"
245b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#include "StubLayout.h"
255cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "ELF.h"
26ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
27079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy#include <llvm/ADT/SmallVector.h>
28dda570201ac851dd85af3861f7e575721d3345daRomain Guy
295cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include "utils/rsl_assert.h"
305cbbce535744b89df5ecea95de21ee3733298260Romain Guy
315cbbce535744b89df5ecea95de21ee3733298260Romain Guytemplate <unsigned Bitwidth>
325cbbce535744b89df5ecea95de21ee3733298260Romain Guytemplate <typename Archiver>
335cbbce535744b89df5ecea95de21ee3733298260Romain Guyinline ELFObject<Bitwidth> *
345cbbce535744b89df5ecea95de21ee3733298260Romain GuyELFObject<Bitwidth>::read(Archiver &AR) {
355cbbce535744b89df5ecea95de21ee3733298260Romain Guy  llvm::OwningPtr<ELFObjectTy> object(new ELFObjectTy());
365cbbce535744b89df5ecea95de21ee3733298260Romain Guy
375cbbce535744b89df5ecea95de21ee3733298260Romain Guy  // Read header
385cbbce535744b89df5ecea95de21ee3733298260Romain Guy  object->header.reset(ELFHeaderTy::read(AR));
395cbbce535744b89df5ecea95de21ee3733298260Romain Guy  if (!object->header) {
405cbbce535744b89df5ecea95de21ee3733298260Romain Guy    return 0;
415cbbce535744b89df5ecea95de21ee3733298260Romain Guy  }
425cbbce535744b89df5ecea95de21ee3733298260Romain Guy
435cbbce535744b89df5ecea95de21ee3733298260Romain Guy  // Read section table
445cbbce535744b89df5ecea95de21ee3733298260Romain Guy  object->shtab.reset(ELFSectionHeaderTableTy::read(AR, object.get()));
455cbbce535744b89df5ecea95de21ee3733298260Romain Guy  if (!object->shtab) {
465cbbce535744b89df5ecea95de21ee3733298260Romain Guy    return 0;
47ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  }
48ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
495cbbce535744b89df5ecea95de21ee3733298260Romain Guy  // Read each section
505cbbce535744b89df5ecea95de21ee3733298260Romain Guy  llvm::SmallVector<size_t, 4> progbits_ndx;
51ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  for (size_t i = 0; i < object->header->getSectionHeaderNum(); ++i) {
525cbbce535744b89df5ecea95de21ee3733298260Romain Guy    if ((*object->shtab)[i]->getType() == SHT_PROGBITS) {
535cbbce535744b89df5ecea95de21ee3733298260Romain Guy      object->stab.push_back(NULL);
545cbbce535744b89df5ecea95de21ee3733298260Romain Guy      progbits_ndx.push_back(i);
555cbbce535744b89df5ecea95de21ee3733298260Romain Guy    } else {
565cbbce535744b89df5ecea95de21ee3733298260Romain Guy      llvm::OwningPtr<ELFSectionTy> sec(
575cbbce535744b89df5ecea95de21ee3733298260Romain Guy        ELFSectionTy::read(AR, object.get(), (*object->shtab)[i]));
585cbbce535744b89df5ecea95de21ee3733298260Romain Guy      object->stab.push_back(sec.take());
595cbbce535744b89df5ecea95de21ee3733298260Romain Guy    }
605cbbce535744b89df5ecea95de21ee3733298260Romain Guy  }
615cbbce535744b89df5ecea95de21ee3733298260Romain Guy
625cbbce535744b89df5ecea95de21ee3733298260Romain Guy  object->shtab->buildNameMap();
63079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy  ELFSectionSymTabTy *symtab =
64f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    static_cast<ELFSectionSymTabTy *>(object->getSectionByName(".symtab"));
65eb99356a0548684a501766e6a524529ab93304c8Romain Guy  rsl_assert(symtab && "Symtab is required.");
66eb99356a0548684a501766e6a524529ab93304c8Romain Guy  symtab->buildNameMap();
67eb99356a0548684a501766e6a524529ab93304c8Romain Guy
68eb99356a0548684a501766e6a524529ab93304c8Romain Guy  for (size_t i = 0; i < progbits_ndx.size(); ++i) {
69eb99356a0548684a501766e6a524529ab93304c8Romain Guy    size_t index = progbits_ndx[i];
70eb99356a0548684a501766e6a524529ab93304c8Romain Guy
71eb99356a0548684a501766e6a524529ab93304c8Romain Guy    llvm::OwningPtr<ELFSectionTy> sec(
72eb99356a0548684a501766e6a524529ab93304c8Romain Guy      ELFSectionTy::read(AR, object.get(), (*object->shtab)[index]));
73ed7a8fc768df158241819f062a12dafdaf8a628dRomain Guy    object->stab[index] = sec.take();
745b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy  }
755b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
765b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy  return object.take();
775b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
78ed7a8fc768df158241819f062a12dafdaf8a628dRomain Guy
795cbbce535744b89df5ecea95de21ee3733298260Romain Guytemplate <unsigned Bitwidth>
805cbbce535744b89df5ecea95de21ee3733298260Romain Guyinline char const *ELFObject<Bitwidth>::getSectionName(size_t i) const {
815cbbce535744b89df5ecea95de21ee3733298260Romain Guy  ELFSectionTy const *sec = stab[header->getStringSectionIndex()];
82f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
83f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy  if (sec) {
84f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    ELFSectionStrTabTy const &st =
853d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy      static_cast<ELFSectionStrTabTy const &>(*sec);
86f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    return st[i];
87ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  }
88f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
89f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy  return NULL;
90f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy}
91f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
92f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guytemplate <unsigned Bitwidth>
93f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guyinline ELFSection<Bitwidth> const *
94ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuyELFObject<Bitwidth>::getSectionByIndex(size_t i) const {
955cbbce535744b89df5ecea95de21ee3733298260Romain Guy  return stab[i];
965cbbce535744b89df5ecea95de21ee3733298260Romain Guy}
97d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy
98d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guytemplate <unsigned Bitwidth>
99ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyinline ELFSection<Bitwidth> *
100959c91f7f7b4f921d341264f5b4ef54e702a0df0Romain GuyELFObject<Bitwidth>::getSectionByIndex(size_t i) {
101ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  return stab[i];
102ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
103ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
104ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guytemplate <unsigned Bitwidth>
105ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyinline ELFSection<Bitwidth> const *
106d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain GuyELFObject<Bitwidth>::getSectionByName(std::string const &str) const {
107ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  size_t idx = getSectionHeaderTable()->getByName(str)->getIndex();
108ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  return stab[idx];
109ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
110ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
111eb99356a0548684a501766e6a524529ab93304c8Romain Guytemplate <unsigned Bitwidth>
112ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyinline ELFSection<Bitwidth> *
113ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuyELFObject<Bitwidth>::getSectionByName(std::string const &str) {
114ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  ELFObjectTy const *const_this = this;
115ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  ELFSectionTy const *sptr = const_this->getSectionByName(str);
116eb99356a0548684a501766e6a524529ab93304c8Romain Guy  // Const cast for the same API's const and non-const versions.
117ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy  return const_cast<ELFSectionTy *>(sptr);
118ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
119ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
120ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
121ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guytemplate <unsigned Bitwidth>
122af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guyinline void ELFObject<Bitwidth>::
1238b55f377655d13a445b08a0a8ed09b6e95c752b0Romain GuyrelocateARM(void *(*find_sym)(void *context, char const *name),
1245cbbce535744b89df5ecea95de21ee3733298260Romain Guy            void *context,
1255cbbce535744b89df5ecea95de21ee3733298260Romain Guy            ELFSectionRelTableTy *reltab,
1265cbbce535744b89df5ecea95de21ee3733298260Romain Guy            ELFSectionProgBitsTy *text) {
1275cbbce535744b89df5ecea95de21ee3733298260Romain Guy  // FIXME: Should be implement in independent files.
1285cbbce535744b89df5ecea95de21ee3733298260Romain Guy  rsl_assert(Bitwidth == 32 && "ARM only have 32 bits.");
1295cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1305cbbce535744b89df5ecea95de21ee3733298260Romain Guy  ELFSectionSymTabTy *symtab =
1315cbbce535744b89df5ecea95de21ee3733298260Romain Guy    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
1325cbbce535744b89df5ecea95de21ee3733298260Romain Guy  rsl_assert(symtab && "Symtab is required.");
1335cbbce535744b89df5ecea95de21ee3733298260Romain Guy
1345cbbce535744b89df5ecea95de21ee3733298260Romain Guy  for (size_t i = 0; i < reltab->size(); ++i) {
135ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    // FIXME: Can not implement here, use Fixup!
136ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    ELFRelocTy *rel = (*reltab)[i];
1375cbbce535744b89df5ecea95de21ee3733298260Romain Guy    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
138dda570201ac851dd85af3861f7e575721d3345daRomain Guy
139f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    // FIXME: May be not uint32_t *.
1408aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    typedef int32_t Inst_t;
141421458aad764cd9d1403d2540ab979b336b02341Romain Guy    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
142421458aad764cd9d1403d2540ab979b336b02341Romain Guy    Inst_t P = (Inst_t)(int64_t)inst;
143eb99356a0548684a501766e6a524529ab93304c8Romain Guy    Inst_t A = 0;
144eb99356a0548684a501766e6a524529ab93304c8Romain Guy    Inst_t S = (Inst_t)(int64_t)sym->getAddress();
145eb99356a0548684a501766e6a524529ab93304c8Romain Guy
146eb99356a0548684a501766e6a524529ab93304c8Romain Guy    switch (rel->getType()) {
147dbc26d2ba13f80a7590c57de2d80530d96832969Romain Guy    default:
148af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy      rsl_assert(0 && "Not implemented relocation type.");
149af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy      break;
150dbc26d2ba13f80a7590c57de2d80530d96832969Romain Guy
151dbc26d2ba13f80a7590c57de2d80530d96832969Romain Guy    case R_ARM_ABS32:
152dbc26d2ba13f80a7590c57de2d80530d96832969Romain Guy      {
153dbc26d2ba13f80a7590c57de2d80530d96832969Romain Guy        A = *inst;
154af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy        *inst = (S+A);
155af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy      }
156af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy      break;
157af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy
158af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy      // FIXME: Predefine relocation codes.
159af636ebf5feb2837683fbfe965040cb706b32ec1Romain Guy    case R_ARM_CALL:
160eb99356a0548684a501766e6a524529ab93304c8Romain Guy      {
161eb99356a0548684a501766e6a524529ab93304c8Romain Guy#define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1)))
162eb99356a0548684a501766e6a524529ab93304c8Romain Guy        A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24);
163eb99356a0548684a501766e6a524529ab93304c8Romain Guy#undef SIGN_EXTEND
164eb99356a0548684a501766e6a524529ab93304c8Romain Guy
165eb99356a0548684a501766e6a524529ab93304c8Romain Guy        void *callee_addr = sym->getAddress();
166eb99356a0548684a501766e6a524529ab93304c8Romain Guy
167eb99356a0548684a501766e6a524529ab93304c8Romain Guy        switch (sym->getType()) {
168eb99356a0548684a501766e6a524529ab93304c8Romain Guy        default:
169eb99356a0548684a501766e6a524529ab93304c8Romain Guy          rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
170eb99356a0548684a501766e6a524529ab93304c8Romain Guy          abort();
171eb99356a0548684a501766e6a524529ab93304c8Romain Guy          break;
172eb99356a0548684a501766e6a524529ab93304c8Romain Guy
173eb99356a0548684a501766e6a524529ab93304c8Romain Guy        case STT_FUNC:
174eb99356a0548684a501766e6a524529ab93304c8Romain Guy          // NOTE: Callee function is in the object file, but it may be
1758aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy          // in different PROGBITS section (which may be far call).
1768aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
177ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy          if (callee_addr == 0) {
178ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            rsl_assert(0 && "We should get function address at previous "
179ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy                   "sym->getAddress() function call.");
1808aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            abort();
1818aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy          }
1828aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy          break;
1838aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
184967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        case STT_NOTYPE:
1858aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy          // NOTE: Callee function is an external function.  Call find_sym
186ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy          // if it has not resolved yet.
187ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
188ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy          if (callee_addr == 0) {
1898aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            callee_addr = find_sym(context, sym->getName());
1908aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            sym->setAddress(callee_addr);
1918aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy          }
1925b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy          break;
193967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
194967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
195967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if __arm__
196967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        // Get the stub for this function
197967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        void *stub = text->getStubLayout()->allocateStub(callee_addr);
198967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
199967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        if (!stub) {
200967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy          llvm::errs() << "unable to allocate stub." << "\n";
2010baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy          abort();
202967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
203967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
204f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy        //LOGI("Function %s: using stub %p\n", sym->getName(), stub);
205ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        S = (uint32_t)(uintptr_t)stub;
206ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#else
207ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        S = (uint32_t)(uintptr_t)callee_addr;
2085b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif
2095b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
2105b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        // Relocate the R_ARM_CALL relocation type
211db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase        uint32_t result = (S >> 2) - (P >> 2) + A;
212db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase
213db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase        if (result > 0x007fffff && result < 0xff800000) {
214db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase          rsl_assert(0 && "Stub is still too far");
215db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase          abort();
216db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase        }
217db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase
218db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase        *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000);
219db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase      }
220db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase      break;
221db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase    case R_ARM_MOVT_ABS:
2225cbbce535744b89df5ecea95de21ee3733298260Romain Guy    case R_ARM_MOVW_ABS_NC:
223967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy      {
224967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        if (S==0 && sym->getType() == STT_NOTYPE)
225967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        {
2260baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy          void *ext_sym = find_sym(context, sym->getName());
227967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy          S = (Inst_t)(uintptr_t)ext_sym;
2288aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy          sym->setAddress(ext_sym);
2298aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        }
2308aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        if (rel->getType() == R_ARM_MOVT_ABS) {
231079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy          S >>= 16;
232967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
2330baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
234967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        // No need sign extend.
235967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF);
2365cbbce535744b89df5ecea95de21ee3733298260Romain Guy        uint32_t result = (S+A);
2375cbbce535744b89df5ecea95de21ee3733298260Romain Guy        *inst = (((result) & 0xF000) << 4) |
2385cbbce535744b89df5ecea95de21ee3733298260Romain Guy          ((result) & 0xFFF) |
2395cbbce535744b89df5ecea95de21ee3733298260Romain Guy          (*inst & 0xFFF0F000);
2405cbbce535744b89df5ecea95de21ee3733298260Romain Guy      }
2415b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy      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
251template <unsigned Bitwidth>
252inline void ELFObject<Bitwidth>::
253relocateX86_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
302template <unsigned Bitwidth>
303inline void ELFObject<Bitwidth>::
304relocateX86_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
347template <unsigned Bitwidth>
348inline void ELFObject<Bitwidth>::
349relocateMIPS(void *(*find_sym)(void *context, char const *name),
350             void *context,
351             ELFSectionRelTableTy *reltab,
352             ELFSectionProgBitsTy *text) {
353  rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS.");
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 < reltab->size(); ++i) {
360    // FIXME: Can not implement here, use Fixup!
361    ELFRelocTy *rel = (*reltab)[i];
362    ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
363
364    typedef int32_t Inst_t;
365    Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
366    Inst_t P = (Inst_t)(uintptr_t)inst;
367    Inst_t A = (Inst_t)(uintptr_t)*inst;
368    Inst_t S = (Inst_t)(uintptr_t)sym->getAddress();
369
370    if (S == 0) {
371      S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
372      sym->setAddress((void *)S);
373    }
374
375    switch (rel->getType()) {
376    default:
377      rsl_assert(0 && "Not implemented relocation type.");
378      break;
379
380    case R_MIPS_HI16:
381      A = A & 0xFFFF;
382      // FIXME: We just support addend = 0.
383      rsl_assert(A == 0 && "R_MIPS_HI16 addend is not 0.");
384      *inst |= (((S + 0x8000) >> 16) & 0xFFFF);
385      break;
386
387    case R_MIPS_LO16:
388      A = A & 0xFFFF;
389      // FIXME: We just support addend = 0.
390      rsl_assert(A == 0 && "R_MIPS_LO16 addend is not 0.");
391      *inst |= (S & 0xFFFF);
392      break;
393
394    case R_MIPS_26:
395      A = A & 0x3FFFFFF;
396      // FIXME: We just support addend = 0.
397      rsl_assert(A == 0 && "R_MIPS_26 addend is not 0.");
398      *inst |= ((S >> 2) & 0x3FFFFFF);
399      rsl_assert((((P + 4) >> 28) != (S >> 28)) && "Cannot relocate R_MIPS_26 due to differences in the upper four bits.");
400      break;
401
402    case R_MIPS_32:
403      *inst = S + A;
404      break;
405    }
406  }
407}
408
409
410// TODO: Refactor all relocations.
411template <unsigned Bitwidth>
412inline void ELFObject<Bitwidth>::
413relocate(void *(*find_sym)(void *context, char const *name), void *context) {
414  // Init SHNCommonDataSize.
415  // Need refactoring
416  size_t SHNCommonDataSize = 0;
417
418  ELFSectionSymTabTy *symtab =
419    static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
420  rsl_assert(symtab && "Symtab is required.");
421
422  for (size_t i = 0; i < symtab->size(); ++i) {
423    ELFSymbolTy *sym = (*symtab)[i];
424
425    if (sym->getType() != STT_OBJECT) {
426      continue;
427    }
428
429    size_t idx = (size_t)sym->getSectionIndex();
430    switch (idx) {
431    default:
432      if ((*shtab)[idx]->getType() == SHT_NOBITS) {
433        // FIXME(logan): This is a workaround for .lcomm directives
434        // bug of LLVM ARM MC code generator.  Remove this when the
435        // LLVM bug is fixed.
436
437        size_t align = 16;
438        SHNCommonDataSize += (size_t)sym->getSize() + align;
439      }
440      break;
441
442    case SHN_COMMON:
443      {
444        size_t align = (size_t)sym->getValue();
445        SHNCommonDataSize += (size_t)sym->getSize() + align;
446      }
447      break;
448
449    case SHN_ABS:
450    case SHN_UNDEF:
451    case SHN_XINDEX:
452      break;
453    }
454  }
455  if (!initSHNCommonDataSize(SHNCommonDataSize)) {
456    rsl_assert("Allocate memory for common variable fail!");
457  }
458
459  for (size_t i = 0; i < stab.size(); ++i) {
460    ELFSectionHeaderTy *sh = (*shtab)[i];
461    if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) {
462      continue;
463    }
464    ELFSectionRelTableTy *reltab =
465      static_cast<ELFSectionRelTableTy *>(stab[i]);
466    rsl_assert(reltab && "Relocation section can't be NULL.");
467
468    const char *reltab_name = sh->getName();
469    const char *need_rel_name;
470    if (sh->getType() == SHT_REL) {
471      need_rel_name = reltab_name + 4;
472      // ".rel.xxxx"
473      //      ^ start from here.
474    } else {
475      need_rel_name = reltab_name + 5;
476    }
477
478    ELFSectionProgBitsTy *need_rel =
479      static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name));
480    rsl_assert(need_rel && "Need be relocated section can't be NULL.");
481
482    switch (getHeader()->getMachine()) {
483      case EM_ARM:
484        relocateARM(find_sym, context, reltab, need_rel);
485        break;
486      case EM_386:
487        relocateX86_32(find_sym, context, reltab, need_rel);
488        break;
489      case EM_X86_64:
490        relocateX86_64(find_sym, context, reltab, need_rel);
491        break;
492      case EM_MIPS:
493        relocateMIPS(find_sym, context, reltab, need_rel);
494        break;
495
496      default:
497        rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation.");
498        break;
499    }
500  }
501
502  for (size_t i = 0; i < stab.size(); ++i) {
503    ELFSectionHeaderTy *sh = (*shtab)[i];
504    if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) {
505      if (stab[i]) {
506        static_cast<ELFSectionBitsTy *>(stab[i])->protect();
507      }
508    }
509  }
510}
511
512template <unsigned Bitwidth>
513inline void ELFObject<Bitwidth>::print() const {
514  header->print();
515  shtab->print();
516
517  for (size_t i = 0; i < stab.size(); ++i) {
518    ELFSectionTy *sec = stab[i];
519    if (sec) {
520      sec->print();
521    }
522  }
523}
524
525#endif // ELF_OBJECT_HXX
526