Home | History | Annotate | Download | only in ARM
      1 //===- ARMRelocator.cpp  ----------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===--------------------------------------------------------------------===//
      9 
     10 #include <mcld/LinkerConfig.h>
     11 #include <mcld/IRBuilder.h>
     12 #include <llvm/ADT/Twine.h>
     13 #include <llvm/Support/DataTypes.h>
     14 #include <llvm/Support/ELF.h>
     15 #include <llvm/Support/Host.h>
     16 #include <mcld/Support/MsgHandling.h>
     17 #include <mcld/LD/LDSymbol.h>
     18 #include <mcld/LD/ELFFileFormat.h>
     19 #include <mcld/Object/ObjectBuilder.h>
     20 #include "ARMRelocator.h"
     21 #include "ARMRelocationFunctions.h"
     22 
     23 using namespace mcld;
     24 
     25 //=========================================//
     26 // Relocation helper function              //
     27 //=========================================//
     28 static Relocator::DWord getThumbBit(const Relocation& pReloc)
     29 {
     30   // Set thumb bit if
     31   // - symbol has type of STT_FUNC, is defined and with bit 0 of its value set
     32   Relocator::DWord thumbBit =
     33        ((!pReloc.symInfo()->isUndef() || pReloc.symInfo()->isDyn()) &&
     34         (pReloc.symInfo()->type() == ResolveInfo::Function) &&
     35         ((pReloc.symValue() & 0x1) != 0))?
     36         1:0;
     37   return thumbBit;
     38 }
     39 
     40 // Using uint64_t to make sure those complicate operations won't cause
     41 // undefined behavior.
     42 static
     43 uint64_t helper_sign_extend(uint64_t pVal, uint64_t pOri_width)
     44 {
     45   assert(pOri_width <= 64);
     46   if (pOri_width == 64)
     47     return pVal;
     48 
     49   uint64_t mask = (~((uint64_t)0)) >> (64 - pOri_width);
     50   pVal &= mask;
     51   // Reverse sign bit, then subtract sign bit.
     52   uint64_t sign_bit = 1 << (pOri_width - 1);
     53   return (pVal ^ sign_bit) - sign_bit;
     54 }
     55 
     56 static
     57 uint64_t helper_bit_select(uint64_t pA, uint64_t pB, uint64_t pMask)
     58 {
     59   return (pA & ~pMask) | (pB & pMask) ;
     60 }
     61 
     62 // Check if symbol can use relocation R_ARM_RELATIVE
     63 static bool
     64 helper_use_relative_reloc(const ResolveInfo& pSym,
     65                           const ARMRelocator& pFactory)
     66 {
     67   // if symbol is dynamic or undefine or preemptible
     68   if (pSym.isDyn() ||
     69       pSym.isUndef() ||
     70       pFactory.getTarget().isSymbolPreemptible(pSym))
     71     return false;
     72   return true;
     73 }
     74 
     75 // Strip LSB (THUMB bit) if "S" is a THUMB target.
     76 static inline void helper_clear_thumb_bit(Relocator::DWord& pValue)
     77 {
     78   pValue &= (~0x1);
     79 }
     80 
     81 static
     82 Relocator::Address helper_get_GOT_address(ResolveInfo& pSym,
     83                                           ARMRelocator& pParent)
     84 {
     85   ARMGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(pSym);
     86   assert(NULL != got_entry);
     87   return pParent.getTarget().getGOT().addr() + got_entry->getOffset();
     88 }
     89 
     90 static
     91 ARMGOTEntry& helper_GOT_init(Relocation& pReloc,
     92                              bool pHasRel,
     93                              ARMRelocator& pParent)
     94 {
     95   // rsym - The relocation target symbol
     96   ResolveInfo* rsym = pReloc.symInfo();
     97   ARMGNULDBackend& ld_backend = pParent.getTarget();
     98   assert(NULL == pParent.getSymGOTMap().lookUp(*rsym));
     99 
    100   ARMGOTEntry* got_entry = ld_backend.getGOT().createGOT();
    101   pParent.getSymGOTMap().record(*rsym, *got_entry);
    102   // If we first get this GOT entry, we should initialize it.
    103   if (!pHasRel) {
    104     // No corresponding dynamic relocation, initialize to the symbol value.
    105     got_entry->setValue(ARMRelocator::SymVal);
    106   }
    107   else {
    108     // Initialize corresponding dynamic relocation.
    109     Relocation& rel_entry = *ld_backend.getRelDyn().create();
    110     if (rsym->isLocal() || helper_use_relative_reloc(*rsym, pParent)) {
    111       // Initialize got entry to target symbol address
    112       got_entry->setValue(ARMRelocator::SymVal);
    113       rel_entry.setType(llvm::ELF::R_ARM_RELATIVE);
    114       rel_entry.setSymInfo(NULL);
    115     }
    116     else {
    117       // Initialize got entry to 0 for corresponding dynamic relocation.
    118       got_entry->setValue(0);
    119       rel_entry.setType(llvm::ELF::R_ARM_GLOB_DAT);
    120       rel_entry.setSymInfo(rsym);
    121     }
    122     rel_entry.targetRef().assign(*got_entry);
    123   }
    124   return *got_entry;
    125 }
    126 
    127 static
    128 Relocator::Address helper_GOT_ORG(ARMRelocator& pParent)
    129 {
    130   return pParent.getTarget().getGOT().addr();
    131 }
    132 
    133 static
    134 Relocator::Address helper_get_PLT_address(ResolveInfo& pSym,
    135                                           ARMRelocator& pParent)
    136 {
    137   ARMPLT1* plt_entry = pParent.getSymPLTMap().lookUp(pSym);
    138   assert(NULL != plt_entry);
    139   return pParent.getTarget().getPLT().addr() + plt_entry->getOffset();
    140 }
    141 
    142 static
    143 ARMPLT1& helper_PLT_init(Relocation& pReloc, ARMRelocator& pParent)
    144 {
    145   // rsym - The relocation target symbol
    146   ResolveInfo* rsym = pReloc.symInfo();
    147   ARMGNULDBackend& ld_backend = pParent.getTarget();
    148   assert(NULL == pParent.getSymPLTMap().lookUp(*rsym));
    149 
    150   // initialize the plt and the corresponding gotplt and dyn relocation
    151   ARMPLT1* plt_entry = ld_backend.getPLT().create();
    152   pParent.getSymPLTMap().record(*rsym, *plt_entry);
    153 
    154   assert(NULL == pParent.getSymGOTPLTMap().lookUp(*rsym) &&
    155          "PLT entry not exist, but DynRel entry exist!");
    156   ARMGOTEntry* gotplt_entry = ld_backend.getGOT().createGOTPLT();
    157   pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
    158 
    159   Relocation& rel_entry = *ld_backend.getRelPLT().create();
    160   rel_entry.setType(llvm::ELF::R_ARM_JUMP_SLOT);
    161   rel_entry.targetRef().assign(*gotplt_entry);
    162   rel_entry.setSymInfo(rsym);
    163 
    164   return *plt_entry;
    165 }
    166 
    167 // Get an relocation entry in .rel.dyn and set its type to pType,
    168 // its FragmentRef to pReloc->targetFrag() and its ResolveInfo to
    169 // pReloc->symInfo()
    170 static
    171 void helper_DynRel_init(Relocation& pReloc,
    172                         Relocator::Type pType,
    173                         ARMRelocator& pParent)
    174 {
    175   // rsym - The relocation target symbol
    176   ResolveInfo* rsym = pReloc.symInfo();
    177   ARMGNULDBackend& ld_backend = pParent.getTarget();
    178 
    179   Relocation& rel_entry = *ld_backend.getRelDyn().create();
    180   rel_entry.setType(pType);
    181   rel_entry.targetRef() = pReloc.targetRef();
    182 
    183   if (pType == llvm::ELF::R_ARM_RELATIVE)
    184     rel_entry.setSymInfo(NULL);
    185   else
    186     rel_entry.setSymInfo(rsym);
    187 }
    188 
    189 static Relocator::DWord
    190 helper_extract_movw_movt_addend(Relocator::DWord pTarget)
    191 {
    192   // imm16: [19-16][11-0]
    193   return helper_sign_extend((((pTarget >> 4)) & 0xf000U) | (pTarget & 0xfffU),
    194                             16);
    195 }
    196 
    197 static Relocator::DWord
    198 helper_insert_val_movw_movt_inst(Relocator::DWord pTarget,
    199                                  Relocator::DWord pImm)
    200 {
    201   // imm16: [19-16][11-0]
    202   pTarget &= 0xfff0f000U;
    203   pTarget |= pImm & 0x0fffU;
    204   pTarget |= (pImm & 0xf000U) << 4;
    205   return pTarget;
    206 }
    207 
    208 static Relocator::DWord
    209 helper_extract_thumb_movw_movt_addend(Relocator::DWord pValue)
    210 {
    211   // imm16: [19-16][26][14-12][7-0]
    212   return helper_sign_extend((((pValue >> 4) & 0xf000U) |
    213                              ((pValue >> 15) & 0x0800U) |
    214                              ((pValue >> 4) & 0x0700U) |
    215                              (pValue& 0x00ffU)),
    216                             16);
    217 }
    218 
    219 static Relocator::DWord
    220 helper_insert_val_thumb_movw_movt_inst(Relocator::DWord pValue,
    221                                        Relocator::DWord pImm)
    222 {
    223   // imm16: [19-16][26][14-12][7-0]
    224   pValue &= 0xfbf08f00U;
    225   pValue |= (pImm & 0xf000U) << 4;
    226   pValue |= (pImm & 0x0800U) << 15;
    227   pValue |= (pImm & 0x0700U) << 4;
    228   pValue |= (pImm & 0x00ffU);
    229   return pValue;
    230 }
    231 
    232 static Relocator::DWord
    233 helper_thumb32_branch_offset(Relocator::DWord pUpper16,
    234                              Relocator::DWord pLower16)
    235 {
    236   Relocator::DWord s = (pUpper16 & (1U << 10)) >> 10,        // 26 bit
    237                            u  = pUpper16 & 0x3ffU,              // 25-16
    238                            l  = pLower16 & 0x7ffU,              // 10-0
    239                            j1 = (pLower16 & (1U << 13)) >> 13,  // 13
    240                            j2 = (pLower16 & (1U << 11)) >> 11;  // 11
    241   Relocator::DWord i1 = j1 ^ s? 0: 1,
    242                               i2 = j2 ^ s? 0: 1;
    243 
    244   // [31-25][24][23][22][21-12][11-1][0]
    245   //      0   s  i1  i2      u     l  0
    246   return helper_sign_extend((s << 24) | (i1 << 23) | (i2 << 22) |
    247                             (u << 12) | (l << 1),
    248                             25);
    249 }
    250 
    251 static Relocator::DWord
    252 helper_thumb32_branch_upper(Relocator::DWord pUpper16,
    253                             Relocator::DWord pOffset)
    254 {
    255   uint32_t sign = ((pOffset & 0x80000000U) >> 31);
    256   return (pUpper16 & ~0x7ffU) | ((pOffset >> 12) & 0x3ffU) | (sign << 10);
    257 }
    258 
    259 static Relocator::DWord
    260 helper_thumb32_branch_lower(Relocator::DWord pLower16,
    261                             Relocator::DWord pOffset)
    262 {
    263   uint32_t sign = ((pOffset & 0x80000000U) >> 31);
    264   return ((pLower16 & ~0x2fffU) |
    265           ((((pOffset >> 23) & 1) ^ !sign) << 13) |
    266           ((((pOffset >> 22) & 1) ^ !sign) << 11) |
    267           ((pOffset >> 1) & 0x7ffU));
    268 }
    269 
    270 static Relocator::DWord
    271 helper_thumb32_cond_branch_offset(Relocator::DWord pUpper16,
    272                                   Relocator::DWord pLower16)
    273 {
    274   uint32_t s = (pUpper16 & 0x0400U) >> 10;
    275   uint32_t j1 = (pLower16 & 0x2000U) >> 13;
    276   uint32_t j2 = (pLower16 & 0x0800U) >> 11;
    277   uint32_t lower = (pLower16 & 0x07ffU);
    278   uint32_t upper = (s << 8) | (j2 << 7) | (j1 << 6) | (pUpper16 & 0x003fU);
    279   return helper_sign_extend((upper << 12) | (lower << 1), 21);
    280 }
    281 
    282 static Relocator::DWord
    283 helper_thumb32_cond_branch_upper(Relocator::DWord pUpper16,
    284                                  Relocator::DWord pOffset)
    285 {
    286   uint32_t sign = ((pOffset & 0x80000000U) >> 31);
    287   return (pUpper16 & 0xfbc0U) | (sign << 10) | ((pOffset & 0x0003f000U) >> 12);
    288 }
    289 
    290 static Relocator::DWord
    291 helper_thumb32_cond_branch_lower(Relocator::DWord pLower16,
    292                                  Relocator::DWord pOffset)
    293 {
    294   uint32_t j2 = (pOffset & 0x00080000U) >> 19;
    295   uint32_t j1 = (pOffset & 0x00040000U) >> 18;
    296   uint32_t lo = (pOffset & 0x00000ffeU) >> 1;
    297   return (pLower16 & 0xd000U) | (j1 << 13) | (j2 << 11) | lo;
    298 }
    299 
    300 // Return true if overflow
    301 static bool
    302 helper_check_signed_overflow(Relocator::DWord pValue,
    303                              unsigned bits)
    304 {
    305   int32_t signed_val = static_cast<int32_t>(pValue);
    306   int32_t max = (1 << (bits - 1)) - 1;
    307   int32_t min = -(1 << (bits - 1));
    308   if (signed_val > max || signed_val < min) {
    309     return true;
    310   } else {
    311     return false;
    312   }
    313 }
    314 
    315 
    316 //===--------------------------------------------------------------------===//
    317 // Relocation Functions and Tables
    318 //===--------------------------------------------------------------------===//
    319 DECL_ARM_APPLY_RELOC_FUNCS
    320 
    321 /// the prototype of applying function
    322 typedef Relocator::Result (*ApplyFunctionType)(Relocation& pReloc,
    323                                                ARMRelocator& pParent);
    324 
    325 // the table entry of applying functions
    326 struct ApplyFunctionTriple
    327 {
    328   ApplyFunctionType func;
    329   unsigned int type;
    330   const char* name;
    331 };
    332 
    333 // declare the table of applying functions
    334 static const ApplyFunctionTriple ApplyFunctions[] = {
    335   DECL_ARM_APPLY_RELOC_FUNC_PTRS
    336 };
    337 
    338 //===--------------------------------------------------------------------===//
    339 // ARMRelocator
    340 //===--------------------------------------------------------------------===//
    341 ARMRelocator::ARMRelocator(ARMGNULDBackend& pParent,
    342                            const LinkerConfig& pConfig)
    343   : Relocator(pConfig),
    344     m_Target(pParent) {
    345 }
    346 
    347 ARMRelocator::~ARMRelocator()
    348 {
    349 }
    350 
    351 Relocator::Result
    352 ARMRelocator::applyRelocation(Relocation& pRelocation)
    353 {
    354   Relocation::Type type = pRelocation.type();
    355   if (type > 130) { // 131-255 doesn't noted in ARM spec
    356     return Relocator::Unknown;
    357   }
    358 
    359   return ApplyFunctions[type].func(pRelocation, *this);
    360 }
    361 
    362 const char* ARMRelocator::getName(Relocator::Type pType) const
    363 {
    364   return ApplyFunctions[pType].name;
    365 }
    366 
    367 Relocator::Size ARMRelocator::getSize(Relocation::Type pType) const
    368 {
    369   return 32;
    370 }
    371 
    372 void ARMRelocator::addCopyReloc(ResolveInfo& pSym)
    373 {
    374   Relocation& rel_entry = *getTarget().getRelDyn().create();
    375   rel_entry.setType(llvm::ELF::R_ARM_COPY);
    376   assert(pSym.outSymbol()->hasFragRef());
    377   rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
    378   rel_entry.setSymInfo(&pSym);
    379 }
    380 
    381 /// defineSymbolForCopyReloc
    382 /// For a symbol needing copy relocation, define a copy symbol in the BSS
    383 /// section and all other reference to this symbol should refer to this
    384 /// copy.
    385 /// This is executed at scan relocation stage.
    386 LDSymbol&
    387 ARMRelocator::defineSymbolforCopyReloc(IRBuilder& pBuilder,
    388                                        const ResolveInfo& pSym)
    389 {
    390   // get or create corresponding BSS LDSection
    391   LDSection* bss_sect_hdr = NULL;
    392   ELFFileFormat* file_format = getTarget().getOutputFormat();
    393   if (ResolveInfo::ThreadLocal == pSym.type())
    394     bss_sect_hdr = &file_format->getTBSS();
    395   else
    396     bss_sect_hdr = &file_format->getBSS();
    397 
    398   // get or create corresponding BSS SectionData
    399   SectionData* bss_data = NULL;
    400   if (bss_sect_hdr->hasSectionData())
    401     bss_data = bss_sect_hdr->getSectionData();
    402   else
    403     bss_data = IRBuilder::CreateSectionData(*bss_sect_hdr);
    404 
    405   // Determine the alignment by the symbol value
    406   // FIXME: here we use the largest alignment
    407   uint32_t addralign = config().targets().bitclass() / 8;
    408 
    409   // allocate space in BSS for the copy symbol
    410   Fragment* frag = new FillFragment(0x0, 1, pSym.size());
    411   uint64_t size = ObjectBuilder::AppendFragment(*frag,
    412                                                 *bss_data,
    413                                                 addralign);
    414   bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
    415 
    416   // change symbol binding to Global if it's a weak symbol
    417   ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
    418   if (binding == ResolveInfo::Weak)
    419     binding = ResolveInfo::Global;
    420 
    421   // Define the copy symbol in the bss section and resolve it
    422   LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    423                       pSym.name(),
    424                       (ResolveInfo::Type)pSym.type(),
    425                       ResolveInfo::Define,
    426                       binding,
    427                       pSym.size(),  // size
    428                       0x0,          // value
    429                       FragmentRef::Create(*frag, 0x0),
    430                       (ResolveInfo::Visibility)pSym.other());
    431 
    432   return *cpy_sym;
    433 }
    434 
    435 /// checkValidReloc - When we attempt to generate a dynamic relocation for
    436 /// ouput file, check if the relocation is supported by dynamic linker.
    437 void ARMRelocator::checkValidReloc(Relocation& pReloc) const
    438 {
    439   // If not PIC object, no relocation type is invalid
    440   if (!config().isCodeIndep())
    441     return;
    442 
    443   switch(pReloc.type()) {
    444     case llvm::ELF::R_ARM_RELATIVE:
    445     case llvm::ELF::R_ARM_COPY:
    446     case llvm::ELF::R_ARM_GLOB_DAT:
    447     case llvm::ELF::R_ARM_JUMP_SLOT:
    448     case llvm::ELF::R_ARM_ABS32:
    449     case llvm::ELF::R_ARM_ABS32_NOI:
    450     case llvm::ELF::R_ARM_PC24:
    451     case llvm::ELF::R_ARM_TLS_DTPMOD32:
    452     case llvm::ELF::R_ARM_TLS_DTPOFF32:
    453     case llvm::ELF::R_ARM_TLS_TPOFF32:
    454       break;
    455 
    456     default:
    457       error(diag::non_pic_relocation) << (int)pReloc.type()
    458                                       << pReloc.symInfo()->name();
    459       break;
    460   }
    461 }
    462 
    463 bool ARMRelocator::mayHaveFunctionPointerAccess(const Relocation& pReloc) const
    464 {
    465   switch (pReloc.type()) {
    466     case llvm::ELF::R_ARM_PC24:
    467     case llvm::ELF::R_ARM_THM_CALL:
    468     case llvm::ELF::R_ARM_PLT32:
    469     case llvm::ELF::R_ARM_CALL:
    470     case llvm::ELF::R_ARM_JUMP24:
    471     case llvm::ELF::R_ARM_THM_JUMP24:
    472     case llvm::ELF::R_ARM_SBREL31:
    473     case llvm::ELF::R_ARM_PREL31:
    474     case llvm::ELF::R_ARM_THM_JUMP19:
    475     case llvm::ELF::R_ARM_THM_JUMP6:
    476     case llvm::ELF::R_ARM_THM_JUMP11:
    477     case llvm::ELF::R_ARM_THM_JUMP8: {
    478       return false;
    479     }
    480     default: {
    481       return true;
    482     }
    483   }
    484 }
    485 
    486 void
    487 ARMRelocator::scanLocalReloc(Relocation& pReloc, const LDSection& pSection)
    488 {
    489   // rsym - The relocation target symbol
    490   ResolveInfo* rsym = pReloc.symInfo();
    491 
    492   switch(pReloc.type()){
    493 
    494     // Set R_ARM_TARGET1 to R_ARM_ABS32
    495     // Ref: GNU gold 1.11 arm.cc, line 9892
    496     // FIXME: R_ARM_TARGET1 should be set by option --target1-rel
    497     // or --target1-rel
    498     case llvm::ELF::R_ARM_TARGET1:
    499        pReloc.setType(llvm::ELF::R_ARM_ABS32);
    500     case llvm::ELF::R_ARM_ABS32:
    501     case llvm::ELF::R_ARM_ABS32_NOI: {
    502       // If buiding PIC object (shared library or PIC executable),
    503       // a dynamic relocations with RELATIVE type to this location is needed.
    504       // Reserve an entry in .rel.dyn
    505       if (config().isCodeIndep()) {
    506         helper_DynRel_init(pReloc, llvm::ELF::R_ARM_RELATIVE, *this);
    507         // set Rel bit
    508         rsym->setReserved(rsym->reserved() | ReserveRel);
    509         getTarget().checkAndSetHasTextRel(*pSection.getLink());
    510       }
    511       return;
    512     }
    513 
    514     case llvm::ELF::R_ARM_ABS16:
    515     case llvm::ELF::R_ARM_ABS12:
    516     case llvm::ELF::R_ARM_THM_ABS5:
    517     case llvm::ELF::R_ARM_ABS8:
    518     case llvm::ELF::R_ARM_BASE_ABS:
    519     case llvm::ELF::R_ARM_MOVW_ABS_NC:
    520     case llvm::ELF::R_ARM_MOVT_ABS:
    521     case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
    522     case llvm::ELF::R_ARM_THM_MOVT_ABS: {
    523       // PIC code should not contain these kinds of relocation
    524       if (config().isCodeIndep()) {
    525         error(diag::non_pic_relocation) << (int)pReloc.type()
    526                                         << pReloc.symInfo()->name();
    527       }
    528       return;
    529     }
    530     case llvm::ELF::R_ARM_GOTOFF32:
    531     case llvm::ELF::R_ARM_GOTOFF12: {
    532       // FIXME: A GOT section is needed
    533       return;
    534     }
    535 
    536     // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
    537     // Ref: GNU gold 1.11 arm.cc, line 9892
    538     // FIXME: R_ARM_TARGET2 should be set by option --target2
    539     case llvm::ELF::R_ARM_TARGET2:
    540       pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
    541     case llvm::ELF::R_ARM_GOT_BREL:
    542     case llvm::ELF::R_ARM_GOT_PREL: {
    543       // A GOT entry is needed for these relocation type.
    544       // return if we already create GOT for this symbol
    545       if (rsym->reserved() & ReserveGOT)
    546         return;
    547 
    548       // If building PIC object, a dynamic relocation with
    549       // type RELATIVE is needed to relocate this GOT entry.
    550       if (config().isCodeIndep())
    551          helper_GOT_init(pReloc, true, *this);
    552       else
    553          helper_GOT_init(pReloc, false, *this);
    554       // set GOT bit
    555       rsym->setReserved(rsym->reserved() | ReserveGOT);
    556       return;
    557     }
    558 
    559     case llvm::ELF::R_ARM_BASE_PREL: {
    560       // FIXME: Currently we only support R_ARM_BASE_PREL against
    561       // symbol _GLOBAL_OFFSET_TABLE_
    562       if (rsym != getTarget().getGOTSymbol()->resolveInfo())
    563         fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name()
    564                                      << "mclinker (at) googlegroups.com";
    565       return;
    566     }
    567     case llvm::ELF::R_ARM_COPY:
    568     case llvm::ELF::R_ARM_GLOB_DAT:
    569     case llvm::ELF::R_ARM_JUMP_SLOT:
    570     case llvm::ELF::R_ARM_RELATIVE: {
    571       // These are relocation type for dynamic linker, shold not
    572       // appear in object file.
    573       fatal(diag::dynamic_relocation) << (int)pReloc.type();
    574       break;
    575     }
    576     default: {
    577       break;
    578     }
    579   } // end switch
    580 }
    581 
    582 void ARMRelocator::scanGlobalReloc(Relocation& pReloc,
    583                                    IRBuilder& pBuilder,
    584                                    const LDSection& pSection)
    585 {
    586   // rsym - The relocation target symbol
    587   ResolveInfo* rsym = pReloc.symInfo();
    588 
    589   switch(pReloc.type()) {
    590 
    591     // Set R_ARM_TARGET1 to R_ARM_ABS32
    592     // Ref: GNU gold 1.11 arm.cc, line 9892
    593     // FIXME: R_ARM_TARGET1 should be set by option --target1-rel
    594     // or --target1-rel
    595     case llvm::ELF::R_ARM_TARGET1:
    596       pReloc.setType(llvm::ELF::R_ARM_ABS32);
    597     case llvm::ELF::R_ARM_ABS32:
    598     case llvm::ELF::R_ARM_ABS16:
    599     case llvm::ELF::R_ARM_ABS12:
    600     case llvm::ELF::R_ARM_THM_ABS5:
    601     case llvm::ELF::R_ARM_ABS8:
    602     case llvm::ELF::R_ARM_BASE_ABS:
    603     case llvm::ELF::R_ARM_MOVW_ABS_NC:
    604     case llvm::ELF::R_ARM_MOVT_ABS:
    605     case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
    606     case llvm::ELF::R_ARM_THM_MOVT_ABS:
    607     case llvm::ELF::R_ARM_ABS32_NOI: {
    608       // Absolute relocation type, symbol may needs PLT entry or
    609       // dynamic relocation entry
    610       if (getTarget().symbolNeedsPLT(*rsym)) {
    611         // create plt for this symbol if it does not have one
    612         if (!(rsym->reserved() & ReservePLT)){
    613           // Symbol needs PLT entry, we need to reserve a PLT entry
    614           // and the corresponding GOT and dynamic relocation entry
    615           // in .got and .rel.plt.
    616           helper_PLT_init(pReloc, *this);
    617           // set PLT bit
    618           rsym->setReserved(rsym->reserved() | ReservePLT);
    619         }
    620       }
    621 
    622       if (getTarget().symbolNeedsDynRel(*rsym,
    623                                        (rsym->reserved() & ReservePLT), true)) {
    624         if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
    625           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
    626           addCopyReloc(*cpy_sym.resolveInfo());
    627         }
    628         else {
    629           checkValidReloc(pReloc);
    630           // set Rel bit
    631           if (helper_use_relative_reloc(*rsym, *this))
    632             helper_DynRel_init(pReloc, llvm::ELF::R_ARM_RELATIVE, *this);
    633           else
    634             helper_DynRel_init(pReloc, pReloc.type(), *this);
    635           rsym->setReserved(rsym->reserved() | ReserveRel);
    636           getTarget().checkAndSetHasTextRel(*pSection.getLink());
    637         }
    638       }
    639       return;
    640     }
    641 
    642     case llvm::ELF::R_ARM_GOTOFF32:
    643     case llvm::ELF::R_ARM_GOTOFF12: {
    644       // FIXME: A GOT section is needed
    645       return;
    646     }
    647 
    648     case llvm::ELF::R_ARM_BASE_PREL:
    649     case llvm::ELF::R_ARM_THM_MOVW_BREL_NC:
    650     case llvm::ELF::R_ARM_THM_MOVW_BREL:
    651     case llvm::ELF::R_ARM_THM_MOVT_BREL:
    652       // FIXME: Currently we only support these relocations against
    653       // symbol _GLOBAL_OFFSET_TABLE_
    654       if (rsym != getTarget().getGOTSymbol()->resolveInfo()) {
    655         fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name()
    656                                      << "mclinker (at) googlegroups.com";
    657       }
    658     case llvm::ELF::R_ARM_REL32:
    659     case llvm::ELF::R_ARM_LDR_PC_G0:
    660     case llvm::ELF::R_ARM_SBREL32:
    661     case llvm::ELF::R_ARM_THM_PC8:
    662     case llvm::ELF::R_ARM_MOVW_PREL_NC:
    663     case llvm::ELF::R_ARM_MOVT_PREL:
    664     case llvm::ELF::R_ARM_THM_MOVW_PREL_NC:
    665     case llvm::ELF::R_ARM_THM_MOVT_PREL:
    666     case llvm::ELF::R_ARM_THM_ALU_PREL_11_0:
    667     case llvm::ELF::R_ARM_THM_PC12:
    668     case llvm::ELF::R_ARM_REL32_NOI:
    669     case llvm::ELF::R_ARM_ALU_PC_G0_NC:
    670     case llvm::ELF::R_ARM_ALU_PC_G0:
    671     case llvm::ELF::R_ARM_ALU_PC_G1_NC:
    672     case llvm::ELF::R_ARM_ALU_PC_G1:
    673     case llvm::ELF::R_ARM_ALU_PC_G2:
    674     case llvm::ELF::R_ARM_LDR_PC_G1:
    675     case llvm::ELF::R_ARM_LDR_PC_G2:
    676     case llvm::ELF::R_ARM_LDRS_PC_G0:
    677     case llvm::ELF::R_ARM_LDRS_PC_G1:
    678     case llvm::ELF::R_ARM_LDRS_PC_G2:
    679     case llvm::ELF::R_ARM_LDC_PC_G0:
    680     case llvm::ELF::R_ARM_LDC_PC_G1:
    681     case llvm::ELF::R_ARM_LDC_PC_G2:
    682     case llvm::ELF::R_ARM_ALU_SB_G0_NC:
    683     case llvm::ELF::R_ARM_ALU_SB_G0:
    684     case llvm::ELF::R_ARM_ALU_SB_G1_NC:
    685     case llvm::ELF::R_ARM_ALU_SB_G1:
    686     case llvm::ELF::R_ARM_ALU_SB_G2:
    687     case llvm::ELF::R_ARM_LDR_SB_G0:
    688     case llvm::ELF::R_ARM_LDR_SB_G1:
    689     case llvm::ELF::R_ARM_LDR_SB_G2:
    690     case llvm::ELF::R_ARM_LDRS_SB_G0:
    691     case llvm::ELF::R_ARM_LDRS_SB_G1:
    692     case llvm::ELF::R_ARM_LDRS_SB_G2:
    693     case llvm::ELF::R_ARM_LDC_SB_G0:
    694     case llvm::ELF::R_ARM_LDC_SB_G1:
    695     case llvm::ELF::R_ARM_LDC_SB_G2:
    696     case llvm::ELF::R_ARM_MOVW_BREL_NC:
    697     case llvm::ELF::R_ARM_MOVT_BREL:
    698     case llvm::ELF::R_ARM_MOVW_BREL: {
    699       // Relative addressing relocation, may needs dynamic relocation
    700       if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT),
    701                                                                        false)) {
    702         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
    703         if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
    704           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
    705           addCopyReloc(*cpy_sym.resolveInfo());
    706         }
    707         else {
    708           checkValidReloc(pReloc);
    709           // set Rel bit
    710           //helper_DynRel_init(pReloc, pReloc.type(), *this);
    711           rsym->setReserved(rsym->reserved() | ReserveRel);
    712           getTarget().checkAndSetHasTextRel(*pSection.getLink());
    713         }
    714       }
    715       return;
    716     }
    717 
    718     case llvm::ELF::R_ARM_PC24:
    719     case llvm::ELF::R_ARM_THM_CALL:
    720     case llvm::ELF::R_ARM_PLT32:
    721     case llvm::ELF::R_ARM_CALL:
    722     case llvm::ELF::R_ARM_JUMP24:
    723     case llvm::ELF::R_ARM_THM_JUMP24:
    724     case llvm::ELF::R_ARM_SBREL31:
    725     case llvm::ELF::R_ARM_PREL31:
    726     case llvm::ELF::R_ARM_THM_JUMP19:
    727     case llvm::ELF::R_ARM_THM_JUMP6:
    728     case llvm::ELF::R_ARM_THM_JUMP11:
    729     case llvm::ELF::R_ARM_THM_JUMP8: {
    730       // These are branch relocation (except PREL31)
    731       // A PLT entry is needed when building shared library
    732 
    733       // return if we already create plt for this symbol
    734       if (rsym->reserved() & ReservePLT)
    735         return;
    736 
    737       // if the symbol's value can be decided at link time, then no need plt
    738       if (getTarget().symbolFinalValueIsKnown(*rsym))
    739         return;
    740 
    741       // if symbol is defined in the ouput file and it's not
    742       // preemptible, no need plt
    743       if (rsym->isDefine() && !rsym->isDyn() &&
    744           !getTarget().isSymbolPreemptible(*rsym)) {
    745         return;
    746       }
    747 
    748       // Symbol needs PLT entry, we need to reserve a PLT entry
    749       // and the corresponding GOT and dynamic relocation entry
    750       // in .got and .rel.plt.
    751       helper_PLT_init(pReloc, *this);
    752       // set PLT bit
    753       rsym->setReserved(rsym->reserved() | ReservePLT);
    754       return;
    755     }
    756 
    757     // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
    758     // Ref: GNU gold 1.11 arm.cc, line 9892
    759     // FIXME: R_ARM_TARGET2 should be set by option --target2
    760     case llvm::ELF::R_ARM_TARGET2:
    761       pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
    762     case llvm::ELF::R_ARM_GOT_BREL:
    763     case llvm::ELF::R_ARM_GOT_ABS:
    764     case llvm::ELF::R_ARM_GOT_PREL: {
    765       // Symbol needs GOT entry, reserve entry in .got
    766       // return if we already create GOT for this symbol
    767       if (rsym->reserved() & ReserveGOT)
    768         return;
    769       // if the symbol cannot be fully resolved at link time, then we need a
    770       // dynamic relocation
    771       if (!getTarget().symbolFinalValueIsKnown(*rsym))
    772         helper_GOT_init(pReloc, true, *this);
    773       else
    774         helper_GOT_init(pReloc, false, *this);
    775       // set GOT bit
    776       rsym->setReserved(rsym->reserved() | ReserveGOT);
    777       return;
    778     }
    779 
    780     case llvm::ELF::R_ARM_COPY:
    781     case llvm::ELF::R_ARM_GLOB_DAT:
    782     case llvm::ELF::R_ARM_JUMP_SLOT:
    783     case llvm::ELF::R_ARM_RELATIVE: {
    784       // These are relocation type for dynamic linker, shold not
    785       // appear in object file.
    786       fatal(diag::dynamic_relocation) << (int)pReloc.type();
    787       break;
    788     }
    789     default: {
    790       break;
    791     }
    792   } // end switch
    793 }
    794 
    795 void ARMRelocator::scanRelocation(Relocation& pReloc,
    796                                   IRBuilder& pBuilder,
    797                                   Module& pModule,
    798                                   LDSection& pSection,
    799                                   Input& pInput)
    800 {
    801   // rsym - The relocation target symbol
    802   ResolveInfo* rsym = pReloc.symInfo();
    803   assert(NULL != rsym &&
    804          "ResolveInfo of relocation not set while scanRelocation");
    805 
    806   assert(NULL != pSection.getLink());
    807   if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
    808     return;
    809 
    810   // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
    811   // entries should be created.
    812   // FIXME: Below judgements concern nothing about TLS related relocation
    813 
    814   // rsym is local
    815   if (rsym->isLocal())
    816     scanLocalReloc(pReloc, pSection);
    817 
    818   // rsym is external
    819   else
    820     scanGlobalReloc(pReloc, pBuilder, pSection);
    821 
    822   // check if we shoule issue undefined reference for the relocation target
    823   // symbol
    824   if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
    825     issueUndefRef(pReloc, pSection, pInput);
    826 }
    827 
    828 //=========================================//
    829 // Each relocation function implementation //
    830 //=========================================//
    831 
    832 // R_ARM_NONE
    833 ARMRelocator::Result none(Relocation& pReloc, ARMRelocator& pParent)
    834 {
    835   return Relocator::OK;
    836 }
    837 
    838 // R_ARM_ABS32: (S + A) | T
    839 ARMRelocator::Result abs32(Relocation& pReloc, ARMRelocator& pParent)
    840 {
    841   ResolveInfo* rsym = pReloc.symInfo();
    842   Relocator::DWord T = getThumbBit(pReloc);
    843   Relocator::DWord A = pReloc.target() + pReloc.addend();
    844   Relocator::DWord S = pReloc.symValue();
    845   if (T != 0x0)
    846     helper_clear_thumb_bit(S);
    847 
    848   // If the flag of target section is not ALLOC, we will not scan this relocation
    849   // but perform static relocation. (e.g., applying .debug section)
    850   if (0x0 == (llvm::ELF::SHF_ALLOC &
    851       pReloc.targetRef().frag()->getParent()->getSection().flag())) {
    852     pReloc.target() = (S + A) | T;
    853     return Relocator::OK;
    854   }
    855 
    856   // An external symbol may need PLT and dynamic relocation
    857   if (!rsym->isLocal()) {
    858     if (rsym->reserved() & ARMRelocator::ReservePLT) {
    859       S = helper_get_PLT_address(*rsym, pParent);
    860       T = 0 ; // PLT is not thumb
    861     }
    862     // If we generate a dynamic relocation (except R_ARM_RELATIVE)
    863     // for a place, we should not perform static relocation on it
    864     // in order to keep the addend store in the place correct.
    865     if ((rsym->reserved() & ARMRelocator::ReserveRel) &&
    866         (!helper_use_relative_reloc(*rsym, pParent)))
    867       return Relocator::OK;
    868   }
    869 
    870   // perform static relocation
    871   pReloc.target() = (S + A) | T;
    872   return Relocator::OK;
    873 }
    874 
    875 // R_ARM_REL32: ((S + A) | T) - P
    876 ARMRelocator::Result rel32(Relocation& pReloc, ARMRelocator& pParent)
    877 {
    878   // perform static relocation
    879   Relocator::Address S = pReloc.symValue();
    880   Relocator::DWord   T = getThumbBit(pReloc);
    881   Relocator::DWord   A = pReloc.target() + pReloc.addend();
    882 
    883   // An external symbol may need PLT (this reloc is from a stub/veneer)
    884   if (!pReloc.symInfo()->isLocal()) {
    885     if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) {
    886       S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
    887       T = 0;  // PLT is not thumb.
    888     }
    889   }
    890 
    891   if (T != 0x0)
    892     helper_clear_thumb_bit(S);
    893 
    894   // perform relocation
    895   pReloc.target() = ((S + A) | T) - pReloc.place();
    896 
    897   return Relocator::OK;
    898 }
    899 
    900 // R_ARM_BASE_PREL: B(S) + A - P
    901 ARMRelocator::Result base_prel(Relocation& pReloc, ARMRelocator& pParent)
    902 {
    903   // perform static relocation
    904   Relocator::DWord A = pReloc.target() + pReloc.addend();
    905   pReloc.target() = pReloc.symValue() + A - pReloc.place();
    906   return Relocator::OK;
    907 }
    908 
    909 // R_ARM_GOTOFF32: ((S + A) | T) - GOT_ORG
    910 ARMRelocator::Result gotoff32(Relocation& pReloc, ARMRelocator& pParent)
    911 {
    912   Relocator::DWord T = getThumbBit(pReloc);
    913   Relocator::DWord A = pReloc.target() + pReloc.addend();
    914   Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
    915   Relocator::Address S = pReloc.symValue();
    916   if (T != 0x0)
    917     helper_clear_thumb_bit(S);
    918 
    919   pReloc.target() = ((S + A) | T) - GOT_ORG;
    920   return Relocator::OK;
    921 }
    922 
    923 // R_ARM_GOT_BREL: GOT(S) + A - GOT_ORG
    924 ARMRelocator::Result got_brel(Relocation& pReloc, ARMRelocator& pParent)
    925 {
    926   if (!(pReloc.symInfo()->reserved() & ARMRelocator::ReserveGOT))
    927     return Relocator::BadReloc;
    928 
    929   Relocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), pParent);
    930   Relocator::DWord   A = pReloc.target() + pReloc.addend();
    931   Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
    932   // Apply relocation.
    933   pReloc.target() = GOT_S + A - GOT_ORG;
    934 
    935   // setup got entry value if needed
    936   ARMGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
    937   if (NULL != got_entry && ARMRelocator::SymVal == got_entry->getValue())
    938     got_entry->setValue(pReloc.symValue());
    939   return Relocator::OK;
    940 }
    941 
    942 // R_ARM_GOT_PREL: GOT(S) + A - P
    943 ARMRelocator::Result got_prel(Relocation& pReloc, ARMRelocator& pParent)
    944 {
    945   if (!(pReloc.symInfo()->reserved() & ARMRelocator::ReserveGOT)) {
    946     return Relocator::BadReloc;
    947   }
    948   Relocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), pParent);
    949   Relocator::DWord   A     = pReloc.target() + pReloc.addend();
    950   Relocator::Address P     = pReloc.place();
    951 
    952   // Apply relocation.
    953   pReloc.target() = GOT_S + A - P;
    954 
    955   // setup got entry value if needed
    956   ARMGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
    957   if (NULL != got_entry && ARMRelocator::SymVal == got_entry->getValue())
    958     got_entry->setValue(pReloc.symValue());
    959   return Relocator::OK;
    960 }
    961 
    962 // R_ARM_THM_JUMP8: S + A - P
    963 ARMRelocator::Result thm_jump8(Relocation& pReloc, ARMRelocator& pParent)
    964 {
    965   Relocator::DWord P = pReloc.place();
    966   Relocator::DWord A = helper_sign_extend((pReloc.target() & 0x00ff) << 1, 8) +
    967                        pReloc.addend();
    968   // S depends on PLT exists or not
    969   Relocator::Address S = pReloc.symValue();
    970   if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT)
    971     S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
    972 
    973   Relocator::DWord X = S + A - P;
    974   if (helper_check_signed_overflow(X, 9))
    975     return Relocator::Overflow;
    976   //                    Make sure the Imm is 0.          Result Mask.
    977   pReloc.target() = (pReloc.target() & 0xFFFFFF00u) | ((X & 0x01FEu) >> 1);
    978   return Relocator::OK;
    979 }
    980 
    981 // R_ARM_THM_JUMP11: S + A - P
    982 ARMRelocator::Result thm_jump11(Relocation& pReloc, ARMRelocator& pParent)
    983 {
    984   Relocator::DWord P = pReloc.place();
    985   Relocator::DWord A = helper_sign_extend((pReloc.target() & 0x07ff) << 1, 11) +
    986                        pReloc.addend();
    987   // S depends on PLT exists or not
    988   Relocator::Address S = pReloc.symValue();
    989   if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT)
    990     S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
    991 
    992   Relocator::DWord X = S + A - P;
    993   if (helper_check_signed_overflow(X, 12))
    994     return Relocator::Overflow;
    995   //                    Make sure the Imm is 0.          Result Mask.
    996   pReloc.target() = (pReloc.target() & 0xFFFFF800u) | ((X & 0x0FFEu) >> 1);
    997   return Relocator::OK;
    998 }
    999 
   1000 // R_ARM_THM_JUMP19: ((S + A) | T) - P
   1001 ARMRelocator::Result thm_jump19(Relocation& pReloc, ARMRelocator& pParent)
   1002 {
   1003   // get lower and upper 16 bit instructions from relocation targetData
   1004   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   1005   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
   1006 
   1007   Relocator::DWord T = getThumbBit(pReloc);
   1008   Relocator::DWord A = helper_thumb32_cond_branch_offset(upper_inst,
   1009                                                                     lower_inst);
   1010   Relocator::Address P = pReloc.place();
   1011   Relocator::Address S;
   1012   // if symbol has plt
   1013   if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) {
   1014     S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
   1015     T = 0;  // PLT is not thumb.
   1016   }
   1017   else {
   1018     S = pReloc.symValue();
   1019     if (T != 0x0)
   1020       helper_clear_thumb_bit(S);
   1021   }
   1022 
   1023   if (0x0 == T) {
   1024     // FIXME: conditional branch to PLT in THUMB-2 not supported yet
   1025     error(diag::unsupport_cond_branch_reloc) << (int)pReloc.type();
   1026     return Relocator::BadReloc;
   1027   }
   1028 
   1029   Relocator::DWord X = ((S + A) | T) - P;
   1030   if (helper_check_signed_overflow(X, 21))
   1031     return Relocator::Overflow;
   1032 
   1033   upper_inst = helper_thumb32_cond_branch_upper(upper_inst, X);
   1034   lower_inst = helper_thumb32_cond_branch_lower(lower_inst, X);
   1035 
   1036   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
   1037   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
   1038 
   1039   return Relocator::OK;
   1040 }
   1041 
   1042 // R_ARM_PC24: ((S + A) | T) - P
   1043 // R_ARM_PLT32: ((S + A) | T) - P
   1044 // R_ARM_JUMP24: ((S + A) | T) - P
   1045 // R_ARM_CALL: ((S + A) | T) - P
   1046 ARMRelocator::Result call(Relocation& pReloc, ARMRelocator& pParent)
   1047 {
   1048   // If target is undefined weak symbol, we only need to jump to the
   1049   // next instruction unless it has PLT entry. Rewrite instruction
   1050   // to NOP.
   1051   if (pReloc.symInfo()->isWeak() &&
   1052       pReloc.symInfo()->isUndef() &&
   1053       !pReloc.symInfo()->isDyn() &&
   1054       !(pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT)) {
   1055     // change target to NOP : mov r0, r0
   1056     pReloc.target() = (pReloc.target() & 0xf0000000U) | 0x01a00000;
   1057     return Relocator::OK;
   1058   }
   1059 
   1060   Relocator::DWord   T = getThumbBit(pReloc);
   1061   Relocator::DWord   A =
   1062     helper_sign_extend((pReloc.target() & 0x00FFFFFFu) << 2, 26) +
   1063     pReloc.addend();
   1064   Relocator::Address P = pReloc.place();
   1065   Relocator::Address S = pReloc.symValue();
   1066   if (T != 0x0)
   1067     helper_clear_thumb_bit(S);
   1068 
   1069   // S depends on PLT exists or not
   1070   if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) {
   1071     S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
   1072     T = 0;  // PLT is not thumb.
   1073   }
   1074 
   1075   // At this moment (after relaxation), if the jump target is thumb instruction,
   1076   // switch mode is needed, rewrite the instruction to BLX
   1077   // FIXME: check if we can use BLX instruction (check from .ARM.attribute
   1078   // CPU ARCH TAG, which should be ARMv5 or above)
   1079   if (T != 0) {
   1080     // cannot rewrite to blx for R_ARM_JUMP24
   1081     if (pReloc.type() == llvm::ELF::R_ARM_JUMP24)
   1082       return Relocator::BadReloc;
   1083     if (pReloc.type() == llvm::ELF::R_ARM_PC24)
   1084       return Relocator::BadReloc;
   1085 
   1086     pReloc.target() = (pReloc.target() & 0xffffff) |
   1087                       0xfa000000 |
   1088                       (((S + A - P) & 2) << 23);
   1089   }
   1090 
   1091   Relocator::DWord X = ((S + A) | T) - P;
   1092   // Check X is 24bit sign int. If not, we should use stub or PLT before apply.
   1093   if (helper_check_signed_overflow(X, 26))
   1094     return Relocator::Overflow;
   1095   //                    Make sure the Imm is 0.          Result Mask.
   1096   pReloc.target() = (pReloc.target() & 0xFF000000u) | ((X & 0x03FFFFFEu) >> 2);
   1097   return Relocator::OK;
   1098 }
   1099 
   1100 // R_ARM_THM_CALL: ((S + A) | T) - P
   1101 // R_ARM_THM_JUMP24: ((S + A) | T) - P
   1102 ARMRelocator::Result thm_call(Relocation& pReloc, ARMRelocator& pParent)
   1103 {
   1104   // If target is undefined weak symbol, we only need to jump to the
   1105   // next instruction unless it has PLT entry. Rewrite instruction
   1106   // to NOP.
   1107   if (pReloc.symInfo()->isWeak() &&
   1108       pReloc.symInfo()->isUndef() &&
   1109       !pReloc.symInfo()->isDyn() &&
   1110       !(pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT)) {
   1111     pReloc.target() = (0xe000U << 16) | 0xbf00U;
   1112     return Relocator::OK;
   1113   }
   1114 
   1115   // get lower and upper 16 bit instructions from relocation targetData
   1116   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   1117   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
   1118 
   1119   Relocator::DWord T = getThumbBit(pReloc);
   1120   Relocator::DWord A = helper_thumb32_branch_offset(upper_inst, lower_inst);
   1121   Relocator::Address P = pReloc.place();
   1122   Relocator::Address S;
   1123 
   1124   // if symbol has plt
   1125   if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) {
   1126     S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
   1127     T = 0;  // PLT is not thumb.
   1128   }
   1129   else {
   1130     S = pReloc.symValue();
   1131     if (T != 0x0)
   1132       helper_clear_thumb_bit(S);
   1133   }
   1134 
   1135   S = S + A;
   1136 
   1137   // At this moment (after relaxation), if the jump target is arm
   1138   // instruction, switch mode is needed, rewrite the instruction to BLX
   1139   // FIXME: check if we can use BLX instruction (check from .ARM.attribute
   1140   // CPU ARCH TAG, which should be ARMv5 or above)
   1141   if (T == 0) {
   1142     // cannot rewrite to blx for R_ARM_THM_JUMP24
   1143     if (pReloc.type() == llvm::ELF::R_ARM_THM_JUMP24)
   1144       return Relocator::BadReloc;
   1145 
   1146     // for BLX, select bit 1 from relocation base address to jump target
   1147     // address
   1148     S = helper_bit_select(S, P, 0x2);
   1149     // rewrite instruction to BLX
   1150     lower_inst &= ~0x1000U;
   1151   }
   1152   else {
   1153     // otherwise, the instruction should be BL
   1154     lower_inst |= 0x1000U;
   1155   }
   1156 
   1157   Relocator::DWord X = (S | T) - P;
   1158 
   1159   // FIXME: Check bit size is 24(thumb2) or 22?
   1160   if (helper_check_signed_overflow(X, 25)) {
   1161     return Relocator::Overflow;
   1162   }
   1163 
   1164   upper_inst = helper_thumb32_branch_upper(upper_inst, X);
   1165   lower_inst = helper_thumb32_branch_lower(lower_inst, X);
   1166 
   1167   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst;
   1168   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst;
   1169 
   1170   return Relocator::OK;
   1171 }
   1172 
   1173 // R_ARM_MOVW_ABS_NC: (S + A) | T
   1174 ARMRelocator::Result movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent)
   1175 {
   1176   ResolveInfo* rsym = pReloc.symInfo();
   1177   Relocator::Address S = pReloc.symValue();
   1178   Relocator::DWord T = getThumbBit(pReloc);
   1179   Relocator::DWord A =
   1180              helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
   1181   if (T != 0x0)
   1182     helper_clear_thumb_bit(S);
   1183 
   1184   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   1185 
   1186   // If the flag of target section is not ALLOC, we will not scan this
   1187   // relocation but perform static relocation. (e.g., applying .debug section)
   1188   if (0x0 != (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
   1189     // use plt
   1190     if (rsym->reserved() & ARMRelocator::ReservePLT) {
   1191       S = helper_get_PLT_address(*rsym, pParent);
   1192       T = 0 ; // PLT is not thumb
   1193     }
   1194   }
   1195 
   1196   // perform static relocation
   1197   Relocator::DWord X = (S + A) | T;
   1198   pReloc.target() = helper_insert_val_movw_movt_inst(
   1199                                          pReloc.target() + pReloc.addend(), X);
   1200   return Relocator::OK;
   1201 }
   1202 
   1203 // R_ARM_MOVW_PREL_NC: ((S + A) | T) - P
   1204 ARMRelocator::Result movw_prel_nc(Relocation& pReloc, ARMRelocator& pParent)
   1205 {
   1206   Relocator::Address S = pReloc.symValue();
   1207   Relocator::DWord T = getThumbBit(pReloc);
   1208   Relocator::DWord P = pReloc.place();
   1209   Relocator::DWord A =
   1210              helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
   1211   if (T != 0x0)
   1212     helper_clear_thumb_bit(S);
   1213   Relocator::DWord X = ((S + A) | T) - P;
   1214 
   1215   if (helper_check_signed_overflow(X, 16)) {
   1216     return Relocator::Overflow;
   1217   } else {
   1218     pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
   1219     return Relocator::OK;
   1220   }
   1221 }
   1222 
   1223 // R_ARM_MOVT_ABS: S + A
   1224 ARMRelocator::Result movt_abs(Relocation& pReloc, ARMRelocator& pParent)
   1225 {
   1226   ResolveInfo* rsym = pReloc.symInfo();
   1227   Relocator::Address S = pReloc.symValue();
   1228   Relocator::DWord A =
   1229              helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
   1230 
   1231   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   1232 
   1233   // If the flag of target section is not ALLOC, we will not scan this relocation
   1234   // but perform static relocation. (e.g., applying .debug section)
   1235   if (0x0 != (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
   1236     // use plt
   1237     if (rsym->reserved() & ARMRelocator::ReservePLT) {
   1238       S = helper_get_PLT_address(*rsym, pParent);
   1239     }
   1240   }
   1241 
   1242   Relocator::DWord X = S + A;
   1243   X >>= 16;
   1244   // perform static relocation
   1245   pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
   1246   return Relocator::OK;
   1247 }
   1248 
   1249 // R_ARM_MOVT_PREL: S + A - P
   1250 ARMRelocator::Result movt_prel(Relocation& pReloc, ARMRelocator& pParent)
   1251 {
   1252   Relocator::Address S = pReloc.symValue();
   1253   Relocator::DWord P = pReloc.place();
   1254   Relocator::DWord A =
   1255              helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
   1256   Relocator::DWord X = S + A - P;
   1257   X >>= 16;
   1258 
   1259   pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
   1260   return Relocator::OK;
   1261 }
   1262 
   1263 // R_ARM_THM_MOVW_ABS_NC: (S + A) | T
   1264 ARMRelocator::Result thm_movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent)
   1265 {
   1266   ResolveInfo* rsym = pReloc.symInfo();
   1267   Relocator::Address S = pReloc.symValue();
   1268   Relocator::DWord T = getThumbBit(pReloc);
   1269   if (T != 0x0)
   1270     helper_clear_thumb_bit(S);
   1271 
   1272   // get lower and upper 16 bit instructions from relocation targetData
   1273   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   1274   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
   1275   Relocator::DWord val = ((upper_inst) << 16) | (lower_inst);
   1276   Relocator::DWord A =
   1277                    helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
   1278 
   1279   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   1280   // If the flag of target section is not ALLOC, we will not scan this relocation
   1281   // but perform static relocation. (e.g., applying .debug section)
   1282   if (0x0 != (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
   1283     // use plt
   1284     if (rsym->reserved() & ARMRelocator::ReservePLT) {
   1285       S = helper_get_PLT_address(*rsym, pParent);
   1286       T = 0; // PLT is not thumb
   1287     }
   1288   }
   1289   Relocator::DWord X = (S + A) | T;
   1290 
   1291   val = helper_insert_val_thumb_movw_movt_inst(val, X);
   1292   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16;
   1293   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu;
   1294 
   1295   return Relocator::OK;
   1296 }
   1297 
   1298 // R_ARM_THM_MOVW_PREL_NC: ((S + A) | T) - P
   1299 ARMRelocator::Result thm_movw_prel_nc(Relocation& pReloc, ARMRelocator& pParent)
   1300 {
   1301   Relocator::Address S = pReloc.symValue();
   1302   Relocator::DWord T = getThumbBit(pReloc);
   1303   Relocator::DWord P = pReloc.place();
   1304   if (T != 0x0)
   1305     helper_clear_thumb_bit(S);
   1306 
   1307   // get lower and upper 16 bit instructions from relocation targetData
   1308   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   1309   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
   1310   Relocator::DWord val = ((upper_inst) << 16) | (lower_inst);
   1311   Relocator::DWord A =
   1312                    helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
   1313   Relocator::DWord X = ((S + A) | T) - P;
   1314 
   1315   val = helper_insert_val_thumb_movw_movt_inst(val, X);
   1316   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16;
   1317   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu;
   1318 
   1319   return Relocator::OK;
   1320 }
   1321 
   1322 // R_ARM_THM_MOVW_BREL_NC: ((S + A) | T) - B(S)
   1323 // R_ARM_THM_MOVW_BREL: ((S + A) | T) - B(S)
   1324 ARMRelocator::Result thm_movw_brel(Relocation& pReloc, ARMRelocator& pParent)
   1325 {
   1326   Relocator::Address S = pReloc.symValue();
   1327   Relocator::DWord T = getThumbBit(pReloc);
   1328   Relocator::DWord P = pReloc.place();
   1329   if (T != 0x0)
   1330     helper_clear_thumb_bit(S);
   1331 
   1332   // get lower and upper 16 bit instructions from relocation targetData
   1333   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   1334   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
   1335   Relocator::DWord val = ((upper_inst) << 16) | (lower_inst);
   1336   Relocator::DWord A =
   1337                    helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
   1338 
   1339   Relocator::DWord X = ((S + A) | T) - P;
   1340 
   1341   val = helper_insert_val_thumb_movw_movt_inst(val, X);
   1342   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16;
   1343   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu;
   1344 
   1345   return Relocator::OK;
   1346 }
   1347 
   1348 // R_ARM_THM_MOVT_ABS: S + A
   1349 ARMRelocator::Result thm_movt_abs(Relocation& pReloc, ARMRelocator& pParent)
   1350 {
   1351   ResolveInfo* rsym = pReloc.symInfo();
   1352   Relocator::Address S = pReloc.symValue();
   1353 
   1354   // get lower and upper 16 bit instructions from relocation targetData
   1355   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   1356   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
   1357   Relocator::DWord val = ((upper_inst) << 16) | (lower_inst);
   1358   Relocator::DWord A =
   1359                    helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
   1360 
   1361   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   1362   // If the flag of target section is not ALLOC, we will not scan this
   1363   // relocation but perform static relocation. (e.g., applying .debug section)
   1364   if (0x0 != (llvm::ELF::SHF_ALLOC & target_sect.flag())) {
   1365     // use plt
   1366     if (rsym->reserved() & ARMRelocator::ReservePLT) {
   1367       S = helper_get_PLT_address(*rsym, pParent);
   1368     }
   1369   }
   1370 
   1371   Relocator::DWord X = S + A;
   1372   X >>= 16;
   1373 
   1374   // check 16-bit overflow
   1375   if (helper_check_signed_overflow(X, 16))
   1376     return Relocator::Overflow;
   1377   val = helper_insert_val_thumb_movw_movt_inst(val, X);
   1378   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16;
   1379   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu;
   1380   return Relocator::OK;
   1381 
   1382 }
   1383 
   1384 // R_ARM_THM_MOVT_PREL: S + A - P
   1385 // R_ARM_THM_MOVT_BREL: S + A - B(S)
   1386 ARMRelocator::Result thm_movt_prel(Relocation& pReloc, ARMRelocator& pParent)
   1387 {
   1388   Relocator::Address S = pReloc.symValue();
   1389   Relocator::DWord P = pReloc.place();
   1390 
   1391   // get lower and upper 16 bit instructions from relocation targetData
   1392   uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()));
   1393   uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1);
   1394   Relocator::DWord val = ((upper_inst) << 16) | (lower_inst);
   1395   Relocator::DWord A =
   1396                    helper_extract_thumb_movw_movt_addend(val) + pReloc.addend();
   1397   Relocator::DWord X = S + A - P;
   1398   X >>= 16;
   1399 
   1400   val = helper_insert_val_thumb_movw_movt_inst(val, X);
   1401   *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16;
   1402   *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu;
   1403 
   1404   return Relocator::OK;
   1405 }
   1406 
   1407 // R_ARM_PREL31: ((S + A) | T) - P
   1408 ARMRelocator::Result prel31(Relocation& pReloc, ARMRelocator& pParent)
   1409 {
   1410   Relocator::DWord target = pReloc.target();
   1411   Relocator::DWord T = getThumbBit(pReloc);
   1412   Relocator::DWord A = helper_sign_extend(target, 31) + pReloc.addend();
   1413   Relocator::DWord P = pReloc.place();
   1414   Relocator::Address S = pReloc.symValue();
   1415   if (T != 0x0)
   1416     helper_clear_thumb_bit(S);
   1417 
   1418   // if symbol has plt
   1419   if ( pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) {
   1420     S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
   1421     T = 0;  // PLT is not thumb.
   1422   }
   1423 
   1424   Relocator::DWord X = ((S + A) | T) - P;
   1425   pReloc.target() = helper_bit_select(target, X, 0x7fffffffU);
   1426   if (helper_check_signed_overflow(X, 31))
   1427     return Relocator::Overflow;
   1428   return Relocator::OK;
   1429 }
   1430 
   1431 // R_ARM_TLS_GD32: GOT(S) + A - P
   1432 // R_ARM_TLS_IE32: GOT(S) + A - P
   1433 // R_ARM_TLS_LE32: S + A - tp
   1434 ARMRelocator::Result tls(Relocation& pReloc, ARMRelocator& pParent)
   1435 {
   1436   return Relocator::Unsupport;
   1437 }
   1438 
   1439 ARMRelocator::Result unsupport(Relocation& pReloc, ARMRelocator& pParent)
   1440 {
   1441   return Relocator::Unsupport;
   1442 }
   1443