Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright 2011-2012, 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 <android/log.h>
     21 
     22 #include "ELFHeader.h"
     23 #include "ELFReloc.h"
     24 #include "ELFSection.h"
     25 #include "ELFSectionHeaderTable.h"
     26 #include "StubLayout.h"
     27 #include "GOT.h"
     28 #include "ELF.h"
     29 
     30 #include <llvm/ADT/SmallVector.h>
     31 
     32 #include "utils/rsl_assert.h"
     33 
     34 
     35 template <unsigned Bitwidth>
     36 template <typename Archiver>
     37 inline ELFObject<Bitwidth> *
     38 ELFObject<Bitwidth>::read(Archiver &AR) {
     39   std::unique_ptr<ELFObjectTy> object(new ELFObjectTy());
     40 
     41   // Read header
     42   object->header.reset(ELFHeaderTy::read(AR));
     43   if (!object->header) {
     44     return 0;
     45   }
     46 
     47   // Read section table
     48   object->shtab.reset(ELFSectionHeaderTableTy::read(AR, object.get()));
     49   if (!object->shtab) {
     50     return 0;
     51   }
     52 
     53   // Read each section
     54   llvm::SmallVector<size_t, 4> progbits_ndx;
     55   for (size_t i = 0; i < object->header->getSectionHeaderNum(); ++i) {
     56     if ((*object->shtab)[i]->getType() == SHT_PROGBITS) {
     57       object->stab.push_back(NULL);
     58       progbits_ndx.push_back(i);
     59     } else {
     60       std::unique_ptr<ELFSectionTy> sec(
     61         ELFSectionTy::read(AR, object.get(), (*object->shtab)[i]));
     62       object->stab.push_back(sec.release());
     63     }
     64   }
     65 
     66   object->shtab->buildNameMap();
     67   ELFSectionSymTabTy *symtab =
     68     static_cast<ELFSectionSymTabTy *>(object->getSectionByName(".symtab"));
     69   rsl_assert(symtab && "Symtab is required.");
     70   symtab->buildNameMap();
     71 
     72   for (size_t i = 0; i < progbits_ndx.size(); ++i) {
     73     size_t index = progbits_ndx[i];
     74 
     75     std::unique_ptr<ELFSectionTy> sec(
     76       ELFSectionTy::read(AR, object.get(), (*object->shtab)[index]));
     77     object->stab[index] = sec.release();
     78   }
     79 
     80   return object.release();
     81 }
     82 
     83 template <unsigned Bitwidth>
     84 inline char const *ELFObject<Bitwidth>::getSectionName(size_t i) const {
     85   ELFSectionTy const *sec = stab[header->getStringSectionIndex()];
     86 
     87   if (sec) {
     88     ELFSectionStrTabTy const &st =
     89       static_cast<ELFSectionStrTabTy const &>(*sec);
     90     return st[i];
     91   }
     92 
     93   return NULL;
     94 }
     95 
     96 template <unsigned Bitwidth>
     97 inline ELFSection<Bitwidth> const *
     98 ELFObject<Bitwidth>::getSectionByIndex(size_t i) const {
     99   return stab[i];
    100 }
    101 
    102 template <unsigned Bitwidth>
    103 inline ELFSection<Bitwidth> *
    104 ELFObject<Bitwidth>::getSectionByIndex(size_t i) {
    105   return stab[i];
    106 }
    107 
    108 template <unsigned Bitwidth>
    109 inline ELFSection<Bitwidth> const *
    110 ELFObject<Bitwidth>::getSectionByName(std::string const &str) const {
    111   size_t idx = getSectionHeaderTable()->getByName(str)->getIndex();
    112   return stab[idx];
    113 }
    114 
    115 template <unsigned Bitwidth>
    116 inline ELFSection<Bitwidth> *
    117 ELFObject<Bitwidth>::getSectionByName(std::string const &str) {
    118   ELFObjectTy const *const_this = this;
    119   ELFSectionTy const *sptr = const_this->getSectionByName(str);
    120   // Const cast for the same API's const and non-const versions.
    121   return const_cast<ELFSectionTy *>(sptr);
    122 }
    123 
    124 
    125 template <unsigned Bitwidth>
    126 inline void ELFObject<Bitwidth>::
    127 relocateARM(void *(*find_sym)(void *context, char const *name),
    128             void *context,
    129             ELFSectionRelTableTy *reltab,
    130             ELFSectionProgBitsTy *text) {
    131   // FIXME: Should be implement in independent files.
    132   rsl_assert(Bitwidth == 32 && "ARM only have 32 bits.");
    133 
    134   ELFSectionSymTabTy *symtab =
    135     static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
    136   rsl_assert(symtab && "Symtab is required.");
    137 
    138   for (size_t i = 0; i < reltab->size(); ++i) {
    139     // FIXME: Can not implement here, use Fixup!
    140     ELFRelocTy *rel = (*reltab)[i];
    141     ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
    142 
    143     // FIXME: May be not uint32_t *.
    144     typedef int32_t Inst_t;
    145     Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    146     Inst_t P = (Inst_t)(int64_t)inst;
    147     Inst_t A = 0;
    148     Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_ARM);
    149     Inst_t T = 0;
    150 
    151     if (sym->isConcreteFunc() && (sym->getValue() & 0x1)) {
    152       T = 1;
    153     }
    154     relinfo_t reltype = rel->getType();
    155     switch (reltype) {
    156     default:
    157       rsl_assert(0 && "Not implemented relocation type.");
    158       break;
    159 
    160     case R_ARM_ABS32:
    161       {
    162         if (S == 0 && sym->getType() == STT_NOTYPE) {
    163           void *ext_sym = find_sym(context, sym->getName());
    164           if (!ext_sym) {
    165             missingSymbols = true;
    166           }
    167           S = (Inst_t)(uintptr_t)ext_sym;
    168           sym->setAddress(ext_sym);
    169         }
    170         A = *inst;
    171         *inst = (S + A) | T;
    172       }
    173       break;
    174 
    175       // FIXME: Predefine relocation codes.
    176     case R_ARM_CALL:
    177     case R_ARM_THM_CALL:
    178     case R_ARM_JUMP24:
    179     case R_ARM_THM_JUMP24:
    180       {
    181 #define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1)))
    182         if (reltype == R_ARM_CALL || reltype == R_ARM_JUMP24) {
    183           A = (Inst_t)(int64_t)SIGN_EXTEND(*inst & 0xFFFFFF, 24);
    184           A <<= 2;
    185         } else {
    186           // Hack for two 16bit.
    187           *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
    188           Inst_t s  = (*inst >> 26) & 0x1u,    // 26
    189                  u  = (*inst >> 16) & 0x3FFu,  // 25-16
    190                  l  =  *inst        & 0x7FFu, // 10-0
    191                  j1 = (*inst >> 13) & 0x1u,    // 13
    192                  j2 = (*inst >> 11) & 0x1u;    // 11
    193           Inst_t i1 = (~(j1 ^ s)) & 0x1u,
    194                  i2 = (~(j2 ^ s)) & 0x1u;
    195           // [31-25][24][23][22][21-12][11-1][0]
    196           //      0   s  i1  i2      u     l  0
    197           A = SIGN_EXTEND((s << 23) | (i1 << 22) | (i2 << 21) | (u << 11) | l, 24);
    198           A <<= 1;
    199         }
    200 #undef SIGN_EXTEND
    201 
    202         void *callee_addr = sym->getAddress(EM_ARM);
    203 
    204         switch (sym->getType()) {
    205         default:
    206           rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
    207           abort();
    208           break;
    209 
    210         case STT_FUNC:
    211           // NOTE: Callee function is in the object file, but it may be
    212           // in different PROGBITS section (which may be far call).
    213 
    214           if (callee_addr == 0) {
    215             rsl_assert(0 && "We should get function address at previous "
    216                    "sym->getAddress(EM_ARM) function call.");
    217             abort();
    218           }
    219           break;
    220 
    221         case STT_NOTYPE:
    222           // NOTE: Callee function is an external function.  Call find_sym
    223           // if it has not resolved yet.
    224 
    225           if (callee_addr == 0) {
    226             callee_addr = find_sym(context, sym->getName());
    227             if (!callee_addr) {
    228               missingSymbols = true;
    229             }
    230             sym->setAddress(callee_addr);
    231           }
    232           break;
    233         }
    234 
    235         // Get the stub for this function
    236         StubLayout *stub_layout = text->getStubLayout();
    237 
    238         if (!stub_layout) {
    239           llvm::errs() << "unable to get stub layout." << "\n";
    240           abort();
    241         }
    242 
    243         void *stub = stub_layout->allocateStub(callee_addr);
    244 
    245         if (!stub) {
    246           llvm::errs() << "unable to allocate stub." << "\n";
    247           abort();
    248         }
    249 
    250         //LOGI("Function %s: using stub %p\n", sym->getName(), stub);
    251         S = (uint32_t)(uintptr_t)stub;
    252 
    253         if (reltype == R_ARM_CALL || reltype == R_ARM_JUMP24) {
    254           // Relocate the R_ARM_CALL relocation type
    255           uint32_t result = (S + A - P) >> 2;
    256 
    257           if (result > 0x007FFFFF && result < 0xFF800000) {
    258             rsl_assert(0 && "Stub is still too far");
    259             abort();
    260           }
    261 
    262           *inst = ((result) & 0x00FFFFFF) | (*inst & 0xFF000000);
    263         } else {
    264           P &= ~0x3;  // Base address align to 4 bytes.  (For BLX.)
    265 
    266           // Relocate the R_ARM_THM_CALL relocation type
    267           uint32_t result = (S + A - P) >> 1;
    268 
    269           if (result > 0x007FFFFF && result < 0xFF800000) {
    270             rsl_assert(0 && "Stub is still too far");
    271             abort();
    272           }
    273 
    274           //*inst &= 0xF800D000u;
    275           // Rewrite instruction to BLX.  (Stub is always ARM.)
    276           *inst &= 0xF800C000u;
    277           // [31-25][24][23][22][21-12][11-1][0]
    278           //      0   s  i1  i2      u     l  0
    279           Inst_t s  = (result >> 23) & 0x1u,   // 26
    280                  u  = (result >> 11) & 0x3FFu, // 25-16
    281                  // For BLX, bit [0] is 0.
    282                  l  =  result        & 0x7FEu, // 10-0
    283                  i1 = (result >> 22) & 0x1u,
    284                  i2 = (result >> 21) & 0x1u;
    285           Inst_t j1 = ((~i1) ^ s) & 0x01u,       // 13
    286                  j2 = ((~i2) ^ s) & 0x01u;       // 11
    287           *inst |= s << 26;
    288           *inst |= u << 16;
    289           *inst |= l;
    290           *inst |= j1 << 13;
    291           *inst |= j2 << 11;
    292           // Hack for two 16bit.
    293           *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
    294         }
    295       }
    296       break;
    297     case R_ARM_MOVT_ABS:
    298     case R_ARM_MOVW_ABS_NC:
    299     case R_ARM_THM_MOVW_ABS_NC:
    300     case R_ARM_THM_MOVT_ABS:
    301       {
    302         if (S == 0 && sym->getType() == STT_NOTYPE) {
    303           void *ext_sym = find_sym(context, sym->getName());
    304           if (!ext_sym) {
    305             missingSymbols = true;
    306           }
    307           S = (Inst_t)(uintptr_t)ext_sym;
    308           sym->setAddress(ext_sym);
    309         }
    310         if (reltype == R_ARM_MOVT_ABS
    311             || reltype == R_ARM_THM_MOVT_ABS) {
    312           S >>= 16;
    313         }
    314 
    315         if (reltype == R_ARM_MOVT_ABS
    316             || reltype == R_ARM_MOVW_ABS_NC) {
    317           // No need sign extend.
    318           A = ((*inst & 0xF0000) >> 4) | (*inst & 0xFFF);
    319           uint32_t result = (S + A);
    320           *inst = (((result) & 0xF000) << 4) |
    321             ((result) & 0xFFF) |
    322             (*inst & 0xFFF0F000);
    323         } else {
    324           // Hack for two 16bit.
    325           *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
    326           // imm16: [19-16][26][14-12][7-0]
    327           A = (((*inst >>  4) & 0xF000u) |
    328                ((*inst >> 15) & 0x0800u) |
    329                ((*inst >>  4) & 0x0700u) |
    330                ( *inst        & 0x00FFu));
    331           uint32_t result;
    332           if (reltype == R_ARM_THM_MOVT_ABS) {
    333             result = (S + A);
    334           } else {
    335             result = (S + A) | T;
    336           }
    337           // imm16: [19-16][26][14-12][7-0]
    338           *inst &= 0xFBF08F00u;
    339           *inst |= (result & 0xF000u) << 4;
    340           *inst |= (result & 0x0800u) << 15;
    341           *inst |= (result & 0x0700u) << 4;
    342           *inst |= (result & 0x00FFu);
    343           // Hack for two 16bit.
    344           *inst = ((*inst >> 16) & 0xFFFF) | (*inst << 16);
    345         }
    346       }
    347       break;
    348     }
    349     //llvm::errs() << "S:     " << (void *)S << '\n';
    350     //llvm::errs() << "A:     " << (void *)A << '\n';
    351     //llvm::errs() << "P:     " << (void *)P << '\n';
    352     //llvm::errs() << "S+A:   " << (void *)(S+A) << '\n';
    353     //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n';
    354   }
    355 }
    356 
    357 template <unsigned Bitwidth>
    358 inline void ELFObject<Bitwidth>::
    359 relocateAARCH64(void *(*find_sym)(void *context, char const *name),
    360             void *context,
    361             ELFSectionRelTableTy *reltab,
    362             ELFSectionProgBitsTy *text) {
    363   // FIXME: Should be implement in independent files.
    364   rsl_assert(Bitwidth == 64 && "AARCH64 only have 64 bits.");
    365 
    366   // Change this to true to enable some debugging in the log.
    367   const bool kDebugSymbolPrint = false;
    368 
    369   ELFSectionSymTabTy *symtab =
    370     static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
    371   rsl_assert(symtab && "Symtab is required.");
    372 
    373   for (size_t i = 0; i < reltab->size(); ++i) {
    374     ELFRelocTy *rel = (*reltab)[i];
    375     ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
    376 
    377     typedef int64_t Inst_t;
    378     Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    379     int32_t* inst32 = reinterpret_cast<int32_t*>(inst);
    380     int16_t* inst16 = reinterpret_cast<int16_t*>(inst);
    381     Inst_t P = (Inst_t)(int64_t)inst;
    382     Inst_t A = 0;
    383     Inst_t S = (Inst_t)(int64_t)sym->getAddress(EM_ARM);
    384     Inst_t Page_P = P & ~0xfff;         // Page address.
    385 
    386     if (S == 0 && sym->getType() == STT_NOTYPE) {
    387       void *ext_sym = find_sym(context, sym->getName());
    388       if (!ext_sym) {
    389         missingSymbols = true;
    390       }
    391       S = (Inst_t)(uintptr_t)ext_sym;
    392       sym->setAddress(ext_sym);
    393     }
    394 
    395     if (kDebugSymbolPrint) {
    396       __android_log_print(ANDROID_LOG_INFO, "rs", "AARCH64 relocation symbol %s value is %llx\n",
    397           sym->getName(), (unsigned long long)S);
    398     }
    399 
    400     // TODO: add other relocations when we know what ones are used.
    401     relinfo_t reltype = rel->getType();
    402     switch (reltype) {
    403     default:
    404       __android_log_print(ANDROID_LOG_ERROR, "rs",
    405         "Unimplemented AARCH64 relocation type %d(0x%x)\n", static_cast<uint32_t>(reltype),
    406         static_cast<uint32_t>(reltype));
    407       rsl_assert(0 && "Unimplemented relocation type.");
    408       break;
    409 
    410     case R_AARCH64_ABS64:
    411         A = *inst + rel->getAddend();
    412         *inst = S + A;
    413       break;
    414 
    415     case R_AARCH64_ABS32:
    416         A = *inst + rel->getAddend();
    417         *inst32 = static_cast<int32_t>(S + A);
    418       break;
    419 
    420     case R_AARCH64_ABS16:
    421         A = *inst + rel->getAddend();
    422         *inst16 = static_cast<int16_t>(S + A);
    423       break;
    424 
    425     case R_AARCH64_PREL64:
    426         A = *inst + rel->getAddend();
    427         *inst = S + A - P;
    428       break;
    429 
    430     case R_AARCH64_PREL32:
    431         A = *inst32 + rel->getAddend();
    432         *inst32 = static_cast<int32_t>(S + A - P);
    433       break;
    434 
    435     case R_AARCH64_PREL16:
    436         A = *inst16 + rel->getAddend();
    437         *inst16 = static_cast<int16_t>(S + A - P);
    438       break;
    439 
    440     case R_AARCH64_ADR_PREL_PG_HI21:
    441       // Relocate an ADRP instruction to the page
    442       {
    443         A = rel->getAddend();
    444         int32_t immed = ((S + A) & ~0xfff) - Page_P;
    445         immed >>= 12;
    446         uint32_t immlo = immed & 0b11;              // 2 bits.
    447         uint32_t immhi = (immed >> 2) & 0x7FFFF;   // 19 bits.
    448         *inst32 |= static_cast<int32_t>(immlo << 29 | immhi << 5);
    449       }
    450       break;
    451 
    452     case R_AARCH64_ADR_PREL_LO21:
    453       {
    454         A = rel->getAddend();
    455         int32_t immed = S + A - P;
    456         uint32_t immlo = immed & 0b11;              // 2 bits.
    457         uint32_t immhi = (immed >> 2) & 0x7FFFF;   // 19 bits.
    458         *inst32 |= static_cast<int32_t>(immlo << 29 | immhi << 5);
    459       }
    460       break;
    461 
    462     case R_AARCH64_ADD_ABS_LO12_NC:
    463       // ADD instruction immediate value.
    464       {
    465         A = rel->getAddend();
    466         int32_t immed = S + A;
    467         uint32_t imm12 = (immed & 0xFFF);   // 12 bits.
    468         *inst32 |= static_cast<int32_t>(imm12 << 10);
    469       }
    470       break;
    471 
    472     case R_AARCH64_LDST8_ABS_LO12_NC:
    473     case R_AARCH64_LDST16_ABS_LO12_NC:
    474     case R_AARCH64_LDST32_ABS_LO12_NC:
    475     case R_AARCH64_LDST64_ABS_LO12_NC:
    476     case R_AARCH64_LDST128_ABS_LO12_NC:
    477       {
    478         // Set LD/ST (unsigned) immediate instruction to the low 12 bits, shifted depending
    479         // on relocation.
    480         A = rel->getAddend();
    481         uint32_t shift = 0;
    482         switch (reltype) {
    483           case R_AARCH64_LDST8_ABS_LO12_NC: shift = 0; break;
    484           case R_AARCH64_LDST16_ABS_LO12_NC: shift = 1; break;
    485           case R_AARCH64_LDST32_ABS_LO12_NC: shift = 2; break;
    486           case R_AARCH64_LDST64_ABS_LO12_NC: shift = 3; break;
    487           case R_AARCH64_LDST128_ABS_LO12_NC: shift = 4; break;
    488           default:
    489             rsl_assert("Cannot reach");
    490         }
    491 
    492         // Form imm12 by taking 12 bits and shifting by appropriate amount.
    493         uint32_t imm12 = ((S + A) & 0xFFF) >> shift;
    494 
    495         // Put it into the instruction.
    496         *inst32 |= static_cast<int32_t>(imm12 << 10);
    497       }
    498       break;
    499 
    500     case R_AARCH64_CALL26:
    501     case R_AARCH64_JUMP26:
    502       {
    503 #define SIGN_EXTEND(x, l) (((x)^(1<<((l)-1)))-(1<<(l-1)))
    504         A = (Inst_t)(int64_t)SIGN_EXTEND(*inst32 & 0x3FFFFFF, 26);
    505         A <<= 2;
    506 #undef SIGN_EXTEND
    507 
    508         void *callee_addr = sym->getAddress(EM_AARCH64);
    509         bool call_via_stub = false;     // Call via a stub (linker veneer).
    510 
    511         switch (sym->getType()) {
    512         default:
    513           rsl_assert(0 && "Wrong type for R_ARM_CALL relocation.");
    514           abort();
    515           break;
    516 
    517         case STT_FUNC:
    518           // NOTE: Callee function is in the object file, but it may be
    519           // in different PROGBITS section (which may be far call).
    520 
    521           if (callee_addr == 0) {
    522             rsl_assert(0 && "We should get function address at previous "
    523                    "sym->getAddress(EM_ARM) function call.");
    524             abort();
    525           }
    526           break;
    527 
    528         case STT_NOTYPE:
    529           // NOTE: Callee function is an external function.  Call find_sym
    530           // if it has not resolved yet.
    531 
    532           if (callee_addr == 0) {
    533             callee_addr = find_sym(context, sym->getName());
    534             if (!callee_addr) {
    535               missingSymbols = true;
    536             }
    537             sym->setAddress(callee_addr);
    538           }
    539           break;
    540         }
    541 
    542         S = reinterpret_cast<int64_t>(callee_addr);
    543         uint32_t result = (S + A - P) >> 2;
    544 
    545         // See if we can do the branch without a stub.
    546         if (result > 0x01FFFFFF && result < 0xFE000000) {
    547           // Not in range, need a stub.
    548           call_via_stub = true;
    549         }
    550 
    551         // Calling via a stub makes a BL instruction to a stub containing the following code:
    552         // ldr x16, addr
    553         // br x16
    554         // addr:
    555         // .word low32
    556         // .word high32
    557         //
    558         // This loads the PC value from the 64 bits at PC + 8.  Since AARCH64 can't
    559         // manipulate the PC directly we have to load a register and branch to the contents.
    560         if (call_via_stub) {
    561           // Get the stub for this function
    562           StubLayout *stub_layout = text->getStubLayout();
    563 
    564           if (!stub_layout) {
    565             __android_log_print(ANDROID_LOG_ERROR, "rs", "unable to get stub layout\n");
    566             llvm::errs() << "unable to get stub layout." << "\n";
    567             abort();
    568           }
    569 
    570           void *stub = stub_layout->allocateStub(callee_addr);
    571 
    572           if (!stub) {
    573             __android_log_print(ANDROID_LOG_ERROR, "rs", "unable to allocate stub\n");
    574             llvm::errs() << "unable to allocate stub." << "\n";
    575             abort();
    576           }
    577 
    578           //LOGI("Function %s: using stub %p\n", sym->getName(), stub);
    579           S = (uint64_t)(uintptr_t)stub;
    580 
    581           result = (S + A - P) >> 2;
    582 
    583           if (result > 0x01FFFFFF && result < 0xFE000000) {
    584             __android_log_print(ANDROID_LOG_ERROR, "rs", "stub is still too far\n");
    585             rsl_assert(0 && "Stub is still too far");
    586             abort();
    587           }
    588         }
    589 
    590         // 'result' contains the offset from PC to the destination address, encoded
    591         // in the correct form for the BL or B instructions.
    592         *inst32 = (result & 0x03FFFFFF) | (*inst & 0xFC000000);
    593       }
    594       break;
    595     case R_AARCH64_MOVW_UABS_G0:
    596     case R_AARCH64_MOVW_UABS_G0_NC:
    597     case R_AARCH64_MOVW_UABS_G1:
    598     case R_AARCH64_MOVW_UABS_G1_NC:
    599     case R_AARCH64_MOVW_UABS_G2:
    600     case R_AARCH64_MOVW_UABS_G2_NC:
    601     case R_AARCH64_MOVW_UABS_G3:
    602       {
    603         int shift = 0;
    604         switch (reltype) {
    605         case R_AARCH64_MOVW_UABS_G0:
    606         case R_AARCH64_MOVW_UABS_G0_NC: shift = 0; break;
    607         case R_AARCH64_MOVW_UABS_G1:
    608         case R_AARCH64_MOVW_UABS_G1_NC: shift = 16; break;
    609         case R_AARCH64_MOVW_UABS_G2:
    610         case R_AARCH64_MOVW_UABS_G2_NC: shift = 32; break;
    611         case R_AARCH64_MOVW_UABS_G3: shift = 48; break;
    612         }
    613 
    614         A = (*inst32 >> 5) & 0xFFFF;
    615         uint32_t value = ((S + A) >> shift) & 0xFFFF;
    616         *inst32 = (*inst32 & ~(0xFFFF << 6)) | (value << 6);
    617       }
    618       break;
    619 
    620     case R_AARCH64_MOVW_SABS_G0:
    621     case R_AARCH64_MOVW_SABS_G1:
    622     case R_AARCH64_MOVW_SABS_G2:
    623       {
    624         int shift = 0;
    625         switch (reltype) {
    626         case R_AARCH64_MOVW_SABS_G0: shift = 0; break;
    627         case R_AARCH64_MOVW_SABS_G1: shift = 16; break;
    628         case R_AARCH64_MOVW_SABS_G2: shift = 32; break;
    629         }
    630 
    631         A = (*inst32 >> 5) & 0xFFFF;
    632         int32_t value = ((S + A) >> shift) & 0xFFFF;
    633 
    634         *inst32 = (*inst32 & ~(0xFFFF << 6)) | (value << 6);
    635 
    636         // This relocation type must also set the instruction bit 30 to 0 or 1
    637         // depending on the sign of the value.  The bit corresponds to the
    638         // movz or movn encoding.  A value of 0 means movn.
    639         if (value >= 0) {
    640           // Set the instruction to movz (set bit 30 to 1)
    641           *inst32 |= 0x40000000;
    642         } else {
    643           // Set the instruction to movn (set bit 30 to 0)
    644           *inst32 &= ~0x40000000;
    645         }
    646       }
    647       break;
    648     }
    649     //llvm::errs() << "S:     " << (void *)S << '\n';
    650     //llvm::errs() << "A:     " << (void *)A << '\n';
    651     //llvm::errs() << "P:     " << (void *)P << '\n';
    652     //llvm::errs() << "S+A:   " << (void *)(S+A) << '\n';
    653     //llvm::errs() << "S+A-P: " << (void *)(S+A-P) << '\n';
    654   }
    655 }
    656 
    657 template <unsigned Bitwidth>
    658 inline void ELFObject<Bitwidth>::
    659 relocateX86_64(void *(*find_sym)(void *context, char const *name),
    660                void *context,
    661                ELFSectionRelTableTy *reltab,
    662                ELFSectionProgBitsTy *text) {
    663   rsl_assert(Bitwidth == 64 && "Only support X86_64.");
    664 
    665   ELFSectionSymTabTy *symtab =
    666     static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
    667   rsl_assert(symtab && "Symtab is required.");
    668 
    669   for (size_t i = 0; i < reltab->size(); ++i) {
    670     // FIXME: Can not implement here, use Fixup!
    671     ELFRelocTy *rel = (*reltab)[i];
    672     ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
    673 
    674     typedef intptr_t Inst_t;
    675     Inst_t *inst = (Inst_t*)&(*text)[rel->getOffset()];
    676     Inst_t P = (Inst_t)inst;
    677     Inst_t A = (Inst_t)rel->getAddend();
    678     Inst_t S = (Inst_t)sym->getAddress(EM_X86_64);
    679 
    680     if (S == 0) {
    681       S = (Inst_t)find_sym(context, sym->getName());
    682       if (!S) {
    683         missingSymbols = true;
    684       }
    685       sym->setAddress((void *)S);
    686     }
    687 
    688     switch (rel->getType()) {
    689     default:
    690       rsl_assert(0 && "Not implemented relocation type.");
    691       break;
    692 
    693     // FIXME, consider other relocation types if RS support dynamic reolcations in future.
    694     case R_X86_64_64: {//Direct 64-bit.
    695       int64_t *paddr = (int64_t*)&(*text)[rel->getOffset()];
    696       int64_t vAddr = S + A;
    697       *paddr = vAddr;
    698       break;
    699     }
    700     case R_X86_64_PC32: {//PC relative 32-bit signed.
    701       int32_t *paddr = (int32_t*)&(*text)[rel->getOffset()];
    702       int64_t vOffset = S + A - P;
    703 
    704       if (vOffset > INT32_MAX || vOffset < INT32_MIN) {
    705         // Not in range, need a stub.
    706         StubLayout *stub_layout = text->getStubLayout();
    707         if (!stub_layout) {
    708           __android_log_print(ANDROID_LOG_ERROR, "rs", "unable to get stub layout\n");
    709           llvm::errs() << "unable to get stub layout." << "\n";
    710           abort();
    711         }
    712 
    713         void *stub = stub_layout->allocateStub((void *)S);
    714 
    715         if (!stub) {
    716           __android_log_print(ANDROID_LOG_ERROR, "rs", "unable to allocate stub\n");
    717           llvm::errs() << "unable to allocate stub." << "\n";
    718           abort();
    719         }
    720 
    721         S = (Inst_t)stub;
    722         vOffset = S + A - P;
    723 
    724         if (vOffset > INT32_MAX || vOffset < INT32_MIN) {
    725           __android_log_print(ANDROID_LOG_ERROR, "rs", "stub is still too far\n");
    726           rsl_assert(0 && "Stub is still too far");
    727           abort();
    728         }
    729       }
    730 
    731       rsl_assert(vOffset <= INT32_MAX && vOffset >= INT32_MIN);
    732       *paddr = (int32_t)(vOffset & 0xFFFFFFFF);
    733       break;
    734     }
    735     case R_X86_64_32: {//Direct 32-bit zero-extended.
    736       uint32_t *paddr = (uint32_t*)&(*text)[rel->getOffset()];
    737       int64_t vAddr = S + A;
    738       rsl_assert(vAddr <= UINT32_MAX);
    739       *paddr = (uint32_t)(vAddr & 0xFFFFFFFF);
    740       break;
    741     }
    742     case R_X86_64_32S: {//Direct 32-bit sign-extended.
    743       int32_t *paddr = (int32_t*)&(*text)[rel->getOffset()];
    744       int64_t vAddr = S + A;
    745       rsl_assert(vAddr <= INT32_MAX && vAddr >= INT32_MIN);
    746       *paddr = (uint32_t)(vAddr & 0xFFFFFFFF);
    747       break;
    748     }
    749     case R_X86_64_16: {//Direct 16-bit zero-extended.
    750       uint16_t *paddr = (uint16_t*)&(*text)[rel->getOffset()];
    751       int64_t vAddr = S + A;
    752       rsl_assert(vAddr <= UINT16_MAX);
    753       *paddr = (uint16_t)(vAddr & 0xFFFF);
    754       break;
    755     }
    756     case R_X86_64_PC16: {//16-bit sign-extended PC relative.
    757       int16_t *paddr = (int16_t*)&(*text)[rel->getOffset()];
    758       int64_t vOffset = S + A - P;
    759       rsl_assert(vOffset <= INT16_MAX && vOffset >= INT16_MIN);
    760       *paddr = (int16_t)(vOffset & 0xFFFF);
    761       break;
    762     }
    763     case R_X86_64_8: {//Direct 8-bit sign-extended.
    764       int8_t *paddr = (int8_t*)&(*text)[rel->getOffset()];
    765       int64_t vAddr = S + A;
    766       rsl_assert(vAddr <= INT8_MAX && vAddr >= INT8_MIN);
    767       *paddr = (uint8_t)(vAddr & 0xFF);
    768       break;
    769     }
    770     case R_X86_64_PC8: {//8-bit sign-extended PC relative.
    771       int8_t *paddr = (int8_t*)&(*text)[rel->getOffset()];
    772       int64_t vOffset = S + A - P;
    773       rsl_assert(vOffset <= INT8_MAX && vOffset >= INT8_MIN);
    774       *paddr = (int8_t)(vOffset & 0xFF);
    775       break;
    776     }
    777     case R_X86_64_PC64: {//PC relative 64-bit.
    778       int64_t *paddr = (int64_t*)&(*text)[rel->getOffset()];
    779       *paddr = (int64_t)(S + A - P);
    780       break;
    781     }
    782     }
    783   }
    784 }
    785 
    786 template <unsigned Bitwidth>
    787 inline void ELFObject<Bitwidth>::
    788 relocateX86_32(void *(*find_sym)(void *context, char const *name),
    789                void *context,
    790                ELFSectionRelTableTy *reltab,
    791                ELFSectionProgBitsTy *text) {
    792   rsl_assert(Bitwidth == 32 && "Only support X86.");
    793 
    794   ELFSectionSymTabTy *symtab =
    795     static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
    796   rsl_assert(symtab && "Symtab is required.");
    797 
    798   for (size_t i = 0; i < reltab->size(); ++i) {
    799     // FIXME: Can not implement here, use Fixup!
    800     ELFRelocTy *rel = (*reltab)[i];
    801     ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
    802 
    803     typedef intptr_t Inst_t;
    804     Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    805     Inst_t P = (Inst_t)inst;
    806     Inst_t A = (Inst_t)*inst;
    807     Inst_t S = (Inst_t)sym->getAddress(EM_386);
    808 
    809     if (S == 0) {
    810       S = (Inst_t)find_sym(context, sym->getName());
    811       if (!S) {
    812         missingSymbols = true;
    813       }
    814       sym->setAddress((void *)S);
    815     }
    816 
    817     switch (rel->getType()) {
    818     default:
    819       rsl_assert(0 && "Not implemented relocation type.");
    820       break;
    821 
    822     case R_386_PC32: {//Add PC-relative symbol value.
    823       int32_t *paddr = (int32_t*)&(*text)[rel->getOffset()];
    824       *paddr = (int32_t)(S + A - P);
    825       break;
    826     }
    827     case R_386_32: {//Add symbol value.
    828       uint32_t *paddr = (uint32_t*)&(*text)[rel->getOffset()];
    829       *paddr = (uint32_t)(S + A);
    830       break;
    831     }
    832     }
    833   }
    834 }
    835 
    836 template <unsigned Bitwidth>
    837 inline void ELFObject<Bitwidth>::
    838 relocateMIPS(void *(*find_sym)(void *context, char const *name),
    839              void *context,
    840              ELFSectionRelTableTy *reltab,
    841              ELFSectionProgBitsTy *text) {
    842   rsl_assert(Bitwidth == 32 && "Only support 32-bit MIPS.");
    843 
    844   ELFSectionSymTabTy *symtab =
    845     static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
    846   rsl_assert(symtab && "Symtab is required.");
    847 
    848   for (size_t i = 0; i < reltab->size(); ++i) {
    849     // FIXME: Can not implement here, use Fixup!
    850     ELFRelocTy *rel = (*reltab)[i];
    851     ELFSymbolTy *sym = (*symtab)[rel->getSymTabIndex()];
    852 
    853     typedef int32_t Inst_t;
    854     Inst_t *inst = (Inst_t *)&(*text)[rel->getOffset()];
    855     Inst_t P = (Inst_t)(uintptr_t)inst;
    856     Inst_t A = (Inst_t)(uintptr_t)*inst;
    857     Inst_t S = (Inst_t)(uintptr_t)sym->getAddress(EM_MIPS);
    858 
    859     bool need_stub = false;
    860 
    861     if (S == 0 && strcmp (sym->getName(), "_gp_disp") != 0) {
    862       need_stub = true;
    863       S = (Inst_t)(uintptr_t)find_sym(context, sym->getName());
    864       if (!S) {
    865         missingSymbols = true;
    866       }
    867 #if defined(__LP64__) || defined(__x86_64__)
    868       llvm::errs() << "Code temporarily disabled for 64bit build";
    869       abort();
    870 #else
    871       sym->setAddress((void *)S);
    872 #endif
    873     }
    874 
    875     switch (rel->getType()) {
    876     default:
    877       rsl_assert(0 && "Not implemented relocation type.");
    878       break;
    879 
    880     case R_MIPS_NONE:
    881     case R_MIPS_JALR: // ignore this
    882       break;
    883 
    884     case R_MIPS_16:
    885       *inst &= 0xFFFF0000;
    886       A = A & 0xFFFF;
    887       A = S + (short)A;
    888       rsl_assert(A >= -32768 && A <= 32767 && "R_MIPS_16 overflow.");
    889       *inst |= (A & 0xFFFF);
    890       break;
    891 
    892     case R_MIPS_32:
    893       *inst = S + A;
    894       break;
    895 
    896     case R_MIPS_26:
    897       *inst &= 0xFC000000;
    898       if (need_stub == false) {
    899         A = (A & 0x3FFFFFF) << 2;
    900         if (sym->getBindingAttribute() == STB_LOCAL) { // local binding
    901           A |= ((P + 4) & 0xF0000000);
    902           A += S;
    903           *inst |= ((A >> 2) & 0x3FFFFFF);
    904         } else { // external binding
    905           if (A & 0x08000000) // Sign extend from bit 27
    906             A |= 0xF0000000;
    907           A += S;
    908           *inst |= ((A >> 2) & 0x3FFFFFF);
    909           if (((P + 4) >> 28) != (A >> 28)) { // far local call
    910 #if defined(__LP64__) || defined(__x86_64__)
    911             llvm::errs() << "Code temporarily disabled for 64bit build";
    912             abort();
    913             void* stub = NULL;
    914 #else
    915             void *stub = text->getStubLayout()->allocateStub((void *)A);
    916 #endif
    917             rsl_assert(stub && "cannot allocate stub.");
    918             sym->setAddress(stub);
    919             S = (int32_t)(intptr_t)stub;
    920             *inst |= ((S >> 2) & 0x3FFFFFF);
    921             rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
    922           }
    923         }
    924       } else { // shared-library call
    925         A = (A & 0x3FFFFFF) << 2;
    926         rsl_assert(A == 0 && "R_MIPS_26 addend is not zero.");
    927 #if defined(__LP64__) || defined(__x86_64__)
    928         llvm::errs() << "Code temporarily disabled for 64bit build";
    929         abort();
    930         void* stub = NULL;
    931 #else
    932         void *stub = text->getStubLayout()->allocateStub((void *)S);
    933 #endif
    934         rsl_assert(stub && "cannot allocate stub.");
    935         sym->setAddress(stub);
    936         S = (int32_t)(intptr_t)stub;
    937         *inst |= ((S >> 2) & 0x3FFFFFF);
    938         rsl_assert(((P + 4) >> 28) == (S >> 28) && "stub is too far.");
    939       }
    940       break;
    941 
    942     case R_MIPS_HI16:
    943       *inst &= 0xFFFF0000;
    944       A = (A & 0xFFFF) << 16;
    945       // Find the nearest LO16 relocation type after this entry
    946       for (size_t j = i + 1; j < reltab->size(); j++) {
    947         ELFRelocTy *this_rel = (*reltab)[j];
    948         ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
    949         if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
    950           Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
    951           Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
    952           this_A = this_A & 0xFFFF;
    953           A += (short)this_A;
    954           break;
    955         }
    956       }
    957       if (strcmp (sym->getName(), "_gp_disp") == 0) {
    958           S = (int)(intptr_t)got_address() + GP_OFFSET - (int)P;
    959 #if defined(__LP64__) || defined(__x86_64__)
    960           llvm::errs() << "Code temporarily disabled for 64bit build";
    961           abort();
    962 #else
    963           sym->setAddress((void *)S);
    964 #endif
    965       }
    966       *inst |= (((S + A + (int)0x8000) >> 16) & 0xFFFF);
    967       break;
    968 
    969     case R_MIPS_LO16:
    970       *inst &= 0xFFFF0000;
    971       A = A & 0xFFFF;
    972       if (strcmp (sym->getName(), "_gp_disp") == 0) {
    973           S = (Inst_t)(intptr_t)sym->getAddress(EM_MIPS);
    974       }
    975       *inst |= ((S + A) & 0xFFFF);
    976       break;
    977 
    978     case R_MIPS_GOT16:
    979     case R_MIPS_CALL16:
    980       {
    981         *inst &= 0xFFFF0000;
    982         A = A & 0xFFFF;
    983         if (rel->getType() == R_MIPS_GOT16) {
    984           if (sym->getBindingAttribute() == STB_LOCAL) {
    985             A <<= 16;
    986 
    987             // Find the nearest LO16 relocation type after this entry
    988             for (size_t j = i + 1; j < reltab->size(); j++) {
    989               ELFRelocTy *this_rel = (*reltab)[j];
    990               ELFSymbolTy *this_sym = (*symtab)[this_rel->getSymTabIndex()];
    991               if (this_rel->getType() == R_MIPS_LO16 && this_sym == sym) {
    992                 Inst_t *this_inst = (Inst_t *)&(*text)[this_rel->getOffset()];
    993                 Inst_t this_A = (Inst_t)(uintptr_t)*this_inst;
    994                 this_A = this_A & 0xFFFF;
    995                 A += (short)this_A;
    996                 break;
    997               }
    998             }
    999           } else {
   1000             rsl_assert(A == 0 && "R_MIPS_GOT16 addend is not 0.");
   1001           }
   1002         } else { // R_MIPS_CALL16
   1003           rsl_assert(A == 0 && "R_MIPS_CALL16 addend is not 0.");
   1004         }
   1005 #if defined(__LP64__) || defined(__x86_64__)
   1006         llvm::errs() << "Code temporarily disabled for 64bit build";
   1007         abort();
   1008         int got_index = 0;
   1009 #else
   1010         int got_index = search_got((int)rel->getSymTabIndex(), (void *)(S + A),
   1011                                    sym->getBindingAttribute());
   1012 #endif
   1013         int got_offset = (got_index << 2) - GP_OFFSET;
   1014         *inst |= (got_offset & 0xFFFF);
   1015       }
   1016       break;
   1017 
   1018     case R_MIPS_GPREL32:
   1019       *inst = A + S - ((int)(intptr_t)got_address() + GP_OFFSET);
   1020       break;
   1021     }
   1022   }
   1023 }
   1024 
   1025 
   1026 // TODO: Refactor all relocations.
   1027 template <unsigned Bitwidth>
   1028 inline void ELFObject<Bitwidth>::
   1029 relocate(void *(*find_sym)(void *context, char const *name), void *context) {
   1030   // Init SHNCommonDataSize.
   1031   // Need refactoring
   1032   size_t SHNCommonDataSize = 0;
   1033 
   1034   ELFSectionSymTabTy *symtab =
   1035     static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
   1036   rsl_assert(symtab && "Symtab is required.");
   1037 
   1038   for (size_t i = 0; i < symtab->size(); ++i) {
   1039     ELFSymbolTy *sym = (*symtab)[i];
   1040 
   1041     if (sym->getType() != STT_OBJECT) {
   1042       continue;
   1043     }
   1044 
   1045     size_t idx = (size_t)sym->getSectionIndex();
   1046     switch (idx) {
   1047     default:
   1048       if ((*shtab)[idx]->getType() == SHT_NOBITS) {
   1049         // FIXME(logan): This is a workaround for .lcomm directives
   1050         // bug of LLVM ARM MC code generator.  Remove this when the
   1051         // LLVM bug is fixed.
   1052 
   1053         size_t align = 16;
   1054         SHNCommonDataSize += (size_t)sym->getSize() + align;
   1055       }
   1056       break;
   1057 
   1058     case SHN_COMMON:
   1059       {
   1060         size_t align = (size_t)sym->getValue();
   1061         SHNCommonDataSize += (size_t)sym->getSize() + align;
   1062       }
   1063       break;
   1064 
   1065     case SHN_ABS:
   1066     case SHN_UNDEF:
   1067     case SHN_XINDEX:
   1068       break;
   1069     }
   1070   }
   1071   if (!initSHNCommonDataSize(SHNCommonDataSize)) {
   1072     rsl_assert("Allocate memory for common variable fail!");
   1073     // TODO: Refactor object loading to use proper status/error returns.
   1074     // We mark the object as having missing symbols and return early in this
   1075     // case to signal a loading error (usually due to running out of
   1076     // available memory to allocate).
   1077     missingSymbols = true;
   1078     return;
   1079   }
   1080 
   1081   for (size_t i = 0; i < stab.size(); ++i) {
   1082     ELFSectionHeaderTy *sh = (*shtab)[i];
   1083     if (sh->getType() != SHT_REL && sh->getType() != SHT_RELA) {
   1084       continue;
   1085     }
   1086     ELFSectionRelTableTy *reltab =
   1087       static_cast<ELFSectionRelTableTy *>(stab[i]);
   1088     rsl_assert(reltab && "Relocation section can't be NULL.");
   1089 
   1090     const char *reltab_name = sh->getName();
   1091     const char *need_rel_name;
   1092     if (sh->getType() == SHT_REL) {
   1093       need_rel_name = reltab_name + 4;
   1094       // ".rel.xxxx"
   1095       //      ^ start from here.
   1096     } else {
   1097       need_rel_name = reltab_name + 5;
   1098     }
   1099 
   1100     // TODO: We currently skip relocations of ARM unwind information, because
   1101     // it is unused.
   1102     if (!strcmp(".ARM.exidx", need_rel_name)) {
   1103       continue;
   1104     }
   1105 
   1106     ELFSectionProgBitsTy *need_rel =
   1107       static_cast<ELFSectionProgBitsTy *>(getSectionByName(need_rel_name));
   1108     rsl_assert(need_rel && "Need be relocated section can't be NULL.");
   1109 
   1110     switch (getHeader()->getMachine()) {
   1111       case EM_ARM:
   1112         relocateARM(find_sym, context, reltab, need_rel);
   1113         break;
   1114       case EM_AARCH64:
   1115         relocateAARCH64(find_sym, context, reltab, need_rel);
   1116         break;
   1117       case EM_386:
   1118         relocateX86_32(find_sym, context, reltab, need_rel);
   1119         break;
   1120       case EM_X86_64:
   1121         relocateX86_64(find_sym, context, reltab, need_rel);
   1122         break;
   1123       case EM_MIPS:
   1124         relocateMIPS(find_sym, context, reltab, need_rel);
   1125         break;
   1126 
   1127       default:
   1128         rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation.");
   1129         break;
   1130     }
   1131   }
   1132 
   1133   for (size_t i = 0; i < stab.size(); ++i) {
   1134     ELFSectionHeaderTy *sh = (*shtab)[i];
   1135     if (sh->getType() == SHT_PROGBITS || sh->getType() == SHT_NOBITS) {
   1136       if (stab[i]) {
   1137         static_cast<ELFSectionBitsTy *>(stab[i])->protect();
   1138       }
   1139     }
   1140   }
   1141 }
   1142 
   1143 template <unsigned Bitwidth>
   1144 inline void ELFObject<Bitwidth>::print() const {
   1145   header->print();
   1146   shtab->print();
   1147 
   1148   for (size_t i = 0; i < stab.size(); ++i) {
   1149     ELFSectionTy *sec = stab[i];
   1150     if (sec) {
   1151       sec->print();
   1152     }
   1153   }
   1154 }
   1155 
   1156 #endif // ELF_OBJECT_HXX
   1157