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