Home | History | Annotate | Download | only in X86
      1 //===- X86Relocator.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 #include "X86Relocator.h"
     10 #include "X86RelocationFunctions.h"
     11 
     12 #include "mcld/IRBuilder.h"
     13 #include "mcld/LinkerConfig.h"
     14 #include "mcld/LD/ELFFileFormat.h"
     15 #include "mcld/LD/ELFSegmentFactory.h"
     16 #include "mcld/LD/ELFSegment.h"
     17 #include "mcld/LD/LDSymbol.h"
     18 #include "mcld/Object/ObjectBuilder.h"
     19 #include "mcld/Support/MsgHandling.h"
     20 
     21 #include <llvm/ADT/Twine.h>
     22 #include <llvm/Support/DataTypes.h>
     23 #include <llvm/Support/ELF.h>
     24 
     25 namespace mcld {
     26 
     27 //===--------------------------------------------------------------------===//
     28 // X86_32 Relocation helper function
     29 //===--------------------------------------------------------------------===//
     30 /// helper_DynRel - Get an relocation entry in .rel.dyn
     31 static Relocation& helper_DynRel_init(ResolveInfo* pSym,
     32                                       Fragment& pFrag,
     33                                       uint64_t pOffset,
     34                                       Relocator::Type pType,
     35                                       X86_32Relocator& pParent) {
     36   X86_32GNULDBackend& ld_backend = pParent.getTarget();
     37   Relocation& rel_entry = *ld_backend.getRelDyn().create();
     38   rel_entry.setType(pType);
     39   rel_entry.targetRef().assign(pFrag, pOffset);
     40   if (pType == llvm::ELF::R_386_RELATIVE || pSym == NULL)
     41     rel_entry.setSymInfo(NULL);
     42   else
     43     rel_entry.setSymInfo(pSym);
     44 
     45   return rel_entry;
     46 }
     47 
     48 /// helper_use_relative_reloc - Check if symbol ceuse relocation
     49 /// R_386_RELATIVE
     50 static bool helper_use_relative_reloc(const ResolveInfo& pSym,
     51                                       const X86_32Relocator& pFactory) {
     52   // if symbol is dynamic or undefine or preemptible
     53   if (pSym.isDyn() || pSym.isUndef() ||
     54       pFactory.getTarget().isSymbolPreemptible(pSym))
     55     return false;
     56   return true;
     57 }
     58 
     59 static X86_32GOTEntry& helper_GOT_init(Relocation& pReloc,
     60                                        bool pHasRel,
     61                                        X86_32Relocator& pParent) {
     62   // rsym - The relocation target symbol
     63   ResolveInfo* rsym = pReloc.symInfo();
     64   X86_32GNULDBackend& ld_backend = pParent.getTarget();
     65   assert(pParent.getSymGOTMap().lookUp(*rsym) == NULL);
     66 
     67   X86_32GOTEntry* got_entry = ld_backend.getGOT().create();
     68   pParent.getSymGOTMap().record(*rsym, *got_entry);
     69 
     70   if (!pHasRel) {
     71     // No corresponding dynamic relocation, initialize to the symbol value.
     72     got_entry->setValue(X86Relocator::SymVal);
     73   } else {
     74     // Initialize got_entry content and the corresponding dynamic relocation.
     75     if (helper_use_relative_reloc(*rsym, pParent)) {
     76       helper_DynRel_init(
     77           rsym, *got_entry, 0x0, llvm::ELF::R_386_RELATIVE, pParent);
     78       got_entry->setValue(X86Relocator::SymVal);
     79     } else {
     80       helper_DynRel_init(
     81           rsym, *got_entry, 0x0, llvm::ELF::R_386_GLOB_DAT, pParent);
     82       got_entry->setValue(0x0);
     83     }
     84   }
     85   return *got_entry;
     86 }
     87 
     88 static Relocator::Address helper_GOT_ORG(X86_32Relocator& pParent) {
     89   return pParent.getTarget().getGOTPLT().addr();
     90 }
     91 
     92 static Relocator::Address helper_get_GOT_address(Relocation& pReloc,
     93                                                  X86_32Relocator& pParent) {
     94   X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
     95   assert(got_entry != NULL);
     96   return pParent.getTarget().getGOT().addr() + got_entry->getOffset();
     97 }
     98 
     99 static PLTEntryBase& helper_PLT_init(Relocation& pReloc,
    100                                      X86_32Relocator& pParent) {
    101   // rsym - The relocation target symbol
    102   ResolveInfo* rsym = pReloc.symInfo();
    103   X86_32GNULDBackend& ld_backend = pParent.getTarget();
    104   assert(pParent.getSymPLTMap().lookUp(*rsym) == NULL);
    105 
    106   PLTEntryBase* plt_entry = ld_backend.getPLT().create();
    107   pParent.getSymPLTMap().record(*rsym, *plt_entry);
    108 
    109   // initialize plt and the corresponding gotplt and dyn rel entry.
    110   assert(pParent.getSymGOTPLTMap().lookUp(*rsym) == NULL &&
    111          "PLT entry not exist, but GOTPLT entry exist!");
    112   X86_32GOTEntry* gotplt_entry = ld_backend.getGOTPLT().create();
    113   pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
    114 
    115   // init the corresponding rel entry in .rel.plt
    116   Relocation& rel_entry = *ld_backend.getRelPLT().create();
    117   rel_entry.setType(llvm::ELF::R_386_JUMP_SLOT);
    118   rel_entry.targetRef().assign(*gotplt_entry);
    119   rel_entry.setSymInfo(rsym);
    120   return *plt_entry;
    121 }
    122 
    123 static Relocator::Address helper_get_PLT_address(ResolveInfo& pSym,
    124                                                  X86_32Relocator& pParent) {
    125   PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym);
    126   assert(plt_entry != NULL);
    127   return pParent.getTarget().getPLT().addr() + plt_entry->getOffset();
    128 }
    129 
    130 //===--------------------------------------------------------------------===//
    131 // X86_32 Relocation Functions and Tables
    132 //===--------------------------------------------------------------------===//
    133 DECL_X86_32_APPLY_RELOC_FUNCS
    134 
    135 /// the prototype of applying function
    136 typedef Relocator::Result (*X86_32ApplyFunctionType)(Relocation& pReloc,
    137                                                      X86_32Relocator& pParent);
    138 
    139 // the table entry of applying functions
    140 struct X86_32ApplyFunctionTriple {
    141   X86_32ApplyFunctionType func;
    142   unsigned int type;
    143   const char* name;
    144   unsigned int size;
    145 };
    146 
    147 // declare the table of applying functions
    148 static const X86_32ApplyFunctionTriple X86_32ApplyFunctions[] = {
    149     DECL_X86_32_APPLY_RELOC_FUNC_PTRS};
    150 
    151 //===--------------------------------------------------------------------===//
    152 // X86Relocator
    153 //===--------------------------------------------------------------------===//
    154 X86Relocator::X86Relocator(const LinkerConfig& pConfig) : Relocator(pConfig) {
    155 }
    156 
    157 X86Relocator::~X86Relocator() {
    158 }
    159 
    160 void X86Relocator::scanRelocation(Relocation& pReloc,
    161                                   IRBuilder& pLinker,
    162                                   Module& pModule,
    163                                   LDSection& pSection,
    164                                   Input& pInput) {
    165   if (LinkerConfig::Object == config().codeGenType())
    166     return;
    167   // rsym - The relocation target symbol
    168   ResolveInfo* rsym = pReloc.symInfo();
    169   assert(rsym != NULL &&
    170          "ResolveInfo of relocation not set while scanRelocation");
    171 
    172   assert(pSection.getLink() != NULL);
    173   if ((pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC) == 0)
    174     return;
    175 
    176   // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation
    177   // entries should be created.
    178   if (rsym->isLocal())  // rsym is local
    179     scanLocalReloc(pReloc, pLinker, pModule, pSection);
    180   else  // rsym is external
    181     scanGlobalReloc(pReloc, pLinker, pModule, pSection);
    182 
    183   // check if we should issue undefined reference for the relocation target
    184   // symbol
    185   if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
    186     issueUndefRef(pReloc, pSection, pInput);
    187 }
    188 
    189 void X86Relocator::addCopyReloc(ResolveInfo& pSym, X86GNULDBackend& pTarget) {
    190   Relocation& rel_entry = *pTarget.getRelDyn().create();
    191   rel_entry.setType(pTarget.getCopyRelType());
    192   assert(pSym.outSymbol()->hasFragRef());
    193   rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
    194   rel_entry.setSymInfo(&pSym);
    195 }
    196 
    197 /// defineSymbolforCopyReloc
    198 /// For a symbol needing copy relocation, define a copy symbol in the BSS
    199 /// section and all other reference to this symbol should refer to this
    200 /// copy.
    201 /// @note This is executed at `scan relocation' stage.
    202 LDSymbol& X86Relocator::defineSymbolforCopyReloc(IRBuilder& pBuilder,
    203                                                  const ResolveInfo& pSym,
    204                                                  X86GNULDBackend& pTarget) {
    205   // get or create corresponding BSS LDSection
    206   LDSection* bss_sect_hdr = NULL;
    207   ELFFileFormat* file_format = pTarget.getOutputFormat();
    208   if (ResolveInfo::ThreadLocal == pSym.type())
    209     bss_sect_hdr = &file_format->getTBSS();
    210   else
    211     bss_sect_hdr = &file_format->getBSS();
    212 
    213   // get or create corresponding BSS SectionData
    214   assert(bss_sect_hdr != NULL);
    215   SectionData* bss_section = NULL;
    216   if (bss_sect_hdr->hasSectionData())
    217     bss_section = bss_sect_hdr->getSectionData();
    218   else
    219     bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr);
    220 
    221   // Determine the alignment by the symbol value
    222   // FIXME: here we use the largest alignment
    223   uint32_t addralign = config().targets().bitclass() / 8;
    224 
    225   // allocate space in BSS for the copy symbol
    226   Fragment* frag = new FillFragment(0x0, 1, pSym.size());
    227   uint64_t size = ObjectBuilder::AppendFragment(*frag, *bss_section, addralign);
    228   bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
    229 
    230   // change symbol binding to Global if it's a weak symbol
    231   ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
    232   if (binding == ResolveInfo::Weak)
    233     binding = ResolveInfo::Global;
    234 
    235   // Define the copy symbol in the bss section and resolve it
    236   LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    237       pSym.name(),
    238       (ResolveInfo::Type)pSym.type(),
    239       ResolveInfo::Define,
    240       binding,
    241       pSym.size(),  // size
    242       0x0,          // value
    243       FragmentRef::Create(*frag, 0x0),
    244       (ResolveInfo::Visibility)pSym.other());
    245 
    246   // output all other alias symbols if any
    247   Module& pModule = pBuilder.getModule();
    248   Module::AliasList* alias_list = pModule.getAliasList(pSym);
    249   if (alias_list != NULL) {
    250     Module::alias_iterator it, it_e = alias_list->end();
    251     for (it = alias_list->begin(); it != it_e; ++it) {
    252       const ResolveInfo* alias = *it;
    253       if (alias != &pSym && alias->isDyn()) {
    254         pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    255             alias->name(),
    256             (ResolveInfo::Type)alias->type(),
    257             ResolveInfo::Define,
    258             binding,
    259             alias->size(),  // size
    260             0x0,            // value
    261             FragmentRef::Create(*frag, 0x0),
    262             (ResolveInfo::Visibility)alias->other());
    263       }
    264     }
    265   }
    266 
    267   return *cpy_sym;
    268 }
    269 
    270 //===----------------------------------------------------------------------===//
    271 // X86_32Relocator
    272 //===----------------------------------------------------------------------===//
    273 X86_32Relocator::X86_32Relocator(X86_32GNULDBackend& pParent,
    274                                  const LinkerConfig& pConfig)
    275     : X86Relocator(pConfig), m_Target(pParent) {
    276 }
    277 
    278 Relocator::Result X86_32Relocator::applyRelocation(Relocation& pRelocation) {
    279   Relocation::Type type = pRelocation.type();
    280 
    281   if (type >= sizeof(X86_32ApplyFunctions) / sizeof(X86_32ApplyFunctions[0])) {
    282     return Unknown;
    283   }
    284 
    285   // apply the relocation
    286   return X86_32ApplyFunctions[type].func(pRelocation, *this);
    287 }
    288 
    289 const char* X86_32Relocator::getName(Relocation::Type pType) const {
    290   return X86_32ApplyFunctions[pType].name;
    291 }
    292 
    293 Relocator::Size X86_32Relocator::getSize(Relocation::Type pType) const {
    294   return X86_32ApplyFunctions[pType].size;
    295 }
    296 
    297 bool X86_32Relocator::mayHaveFunctionPointerAccess(
    298     const Relocation& pReloc) const {
    299   switch (pReloc.type()) {
    300     case llvm::ELF::R_386_32:
    301     case llvm::ELF::R_386_16:
    302     case llvm::ELF::R_386_8:
    303     case llvm::ELF::R_386_GOTOFF:
    304     case llvm::ELF::R_386_GOT32: {
    305       return true;
    306     }
    307     default: { return false; }
    308   }
    309 }
    310 
    311 void X86_32Relocator::scanLocalReloc(Relocation& pReloc,
    312                                      IRBuilder& pBuilder,
    313                                      Module& pModule,
    314                                      LDSection& pSection) {
    315   // rsym - The relocation target symbol
    316   ResolveInfo* rsym = pReloc.symInfo();
    317 
    318   switch (pReloc.type()) {
    319     case llvm::ELF::R_386_32:
    320       // If buiding PIC object (shared library or PIC executable),
    321       // a dynamic relocations with RELATIVE type to this location is needed.
    322       // Reserve an entry in .rel.dyn
    323       if (config().isCodeIndep()) {
    324         // set Rel bit
    325         rsym->setReserved(rsym->reserved() | ReserveRel);
    326         getTarget().checkAndSetHasTextRel(*pSection.getLink());
    327         // set up the dyn rel directly
    328         helper_DynRel_init(rsym,
    329                            *pReloc.targetRef().frag(),
    330                            pReloc.targetRef().offset(),
    331                            llvm::ELF::R_386_RELATIVE,
    332                            *this);
    333       }
    334       return;
    335 
    336     case llvm::ELF::R_386_16:
    337     case llvm::ELF::R_386_8:
    338       // If buiding PIC object (shared library or PIC executable),
    339       // a dynamic relocations with RELATIVE type to this location is needed.
    340       // Reserve an entry in .rel.dyn
    341       if (config().isCodeIndep()) {
    342         // set up the dyn rel directly
    343         helper_DynRel_init(rsym,
    344                            *pReloc.targetRef().frag(),
    345                            pReloc.targetRef().offset(),
    346                            pReloc.type(),
    347                            *this);
    348         // set Rel bit
    349         rsym->setReserved(rsym->reserved() | ReserveRel);
    350         getTarget().checkAndSetHasTextRel(*pSection.getLink());
    351       }
    352       return;
    353 
    354     case llvm::ELF::R_386_PLT32:
    355       return;
    356 
    357     case llvm::ELF::R_386_GOTOFF:
    358     case llvm::ELF::R_386_GOTPC:
    359       // FIXME: A GOT section is needed
    360       return;
    361 
    362     case llvm::ELF::R_386_GOT32:
    363       // Symbol needs GOT entry, reserve entry in .got
    364       // return if we already create GOT for this symbol
    365       if (rsym->reserved() & ReserveGOT)
    366         return;
    367 
    368       // FIXME: check STT_GNU_IFUNC symbol
    369 
    370       // If building PIC object, a dynamic relocation with
    371       // type RELATIVE is needed to relocate this GOT entry.
    372       if (config().isCodeIndep())
    373         helper_GOT_init(pReloc, true, *this);
    374       else
    375         helper_GOT_init(pReloc, false, *this);
    376 
    377       // set GOT bit
    378       rsym->setReserved(rsym->reserved() | ReserveGOT);
    379       return;
    380 
    381     case llvm::ELF::R_386_PC32:
    382     case llvm::ELF::R_386_PC16:
    383     case llvm::ELF::R_386_PC8:
    384       return;
    385 
    386     case llvm::ELF::R_386_TLS_GD: {
    387       // FIXME: no linker optimization for TLS relocation
    388       if (rsym->reserved() & ReserveGOT)
    389         return;
    390 
    391       // define the section symbol for .tdata or .tbss
    392       // the target symbol of the created dynamic relocation should be the
    393       // section symbol of the section which this symbol defined. so we
    394       // need to define that section symbol here
    395       ELFFileFormat* file_format = getTarget().getOutputFormat();
    396       const LDSection* sym_sect =
    397           &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection();
    398       LDSymbol* sect_sym = NULL;
    399       if (&file_format->getTData() == sym_sect) {
    400         if (!getTarget().hasTDATASymbol()) {
    401           sect_sym = pModule.getSectionSymbolSet().get(*sym_sect);
    402           getTarget().setTDATASymbol(*sect_sym);
    403         }
    404       } else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) {
    405         if (!getTarget().hasTBSSSymbol()) {
    406           sect_sym = pModule.getSectionSymbolSet().get(*sym_sect);
    407           getTarget().setTBSSSymbol(*sect_sym);
    408         }
    409       } else {
    410         error(diag::invalid_tls) << rsym->name() << sym_sect->name();
    411       }
    412 
    413       // set up a pair of got entries and a dyn rel
    414       // set GOT bit
    415       rsym->setReserved(rsym->reserved() | ReserveGOT);
    416       X86_32GOTEntry* got_entry1 = getTarget().getGOT().create();
    417       X86_32GOTEntry* got_entry2 = getTarget().getGOT().create();
    418       getSymGOTMap().record(*rsym, *got_entry1, *got_entry2);
    419       // set up value of got entries, the value of got_entry2 should be the
    420       // symbol value, which has to be set during apply relocation
    421       got_entry1->setValue(0x0);
    422 
    423       // setup dyn rel for got_entry1
    424       Relocation& rel_entry1 = helper_DynRel_init(
    425           rsym, *got_entry1, 0x0, llvm::ELF::R_386_TLS_DTPMOD32, *this);
    426       // for local tls symbol, add rel entry against the section symbol this
    427       // symbol belong to (.tdata or .tbss)
    428       rel_entry1.setSymInfo(sect_sym->resolveInfo());
    429       return;
    430     }
    431     case llvm::ELF::R_386_TLS_LDM:
    432       getTLSModuleID();
    433       return;
    434 
    435     case llvm::ELF::R_386_TLS_LDO_32:
    436       return;
    437 
    438     case llvm::ELF::R_386_TLS_IE: {
    439       getTarget().setHasStaticTLS();
    440 
    441       // if building shared object, a RELATIVE dynamic relocation is needed
    442       if (LinkerConfig::DynObj == config().codeGenType()) {
    443         helper_DynRel_init(rsym,
    444                            *pReloc.targetRef().frag(),
    445                            pReloc.targetRef().offset(),
    446                            llvm::ELF::R_386_RELATIVE,
    447                            *this);
    448         rsym->setReserved(rsym->reserved() | ReserveRel);
    449         getTarget().checkAndSetHasTextRel(*pSection.getLink());
    450       } else {
    451         // for local sym, we can convert ie to le if not building shared object
    452         convertTLSIEtoLE(pReloc, pSection);
    453         return;
    454       }
    455 
    456       if (rsym->reserved() & ReserveGOT)
    457         return;
    458 
    459       // set up the got and the corresponding rel entry
    460       X86_32GOTEntry* got_entry = getTarget().getGOT().create();
    461       getSymGOTMap().record(*rsym, *got_entry);
    462       got_entry->setValue(0x0);
    463       helper_DynRel_init(
    464           rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, *this);
    465       // set GOT bit
    466       rsym->setReserved(rsym->reserved() | ReserveGOT);
    467       // add symbol to dyn sym table
    468       getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
    469       return;
    470     }
    471 
    472     case llvm::ELF::R_386_TLS_GOTIE: {
    473       getTarget().setHasStaticTLS();
    474       if (rsym->reserved() & ReserveGOT)
    475         return;
    476       // set up the got and the corresponding dyn rel
    477       X86_32GOTEntry* got_entry = getTarget().getGOT().create();
    478       getSymGOTMap().record(*rsym, *got_entry);
    479       got_entry->setValue(0x0);
    480       helper_DynRel_init(
    481           rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, *this);
    482       // set GOT bit
    483       rsym->setReserved(rsym->reserved() | ReserveGOT);
    484       getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
    485       return;
    486     }
    487 
    488     case llvm::ELF::R_386_TLS_LE:
    489     case llvm::ELF::R_386_TLS_LE_32:
    490       getTarget().setHasStaticTLS();
    491       // if buildint shared object, a dynamic relocation is needed
    492       if (LinkerConfig::DynObj == config().codeGenType()) {
    493         helper_DynRel_init(rsym,
    494                            *pReloc.targetRef().frag(),
    495                            pReloc.targetRef().offset(),
    496                            llvm::ELF::R_386_TLS_TPOFF,
    497                            *this);
    498         rsym->setReserved(rsym->reserved() | ReserveRel);
    499         getTarget().checkAndSetHasTextRel(*pSection.getLink());
    500         // the target symbol of the dynamic relocation is rsym, so we need to
    501         // emit it into .dynsym
    502         assert(rsym->outSymbol() != NULL);
    503         getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
    504       }
    505       return;
    506 
    507     default:
    508       fatal(diag::unsupported_relocation) << static_cast<int>(pReloc.type())
    509                                           << "mclinker (at) googlegroups.com";
    510       break;
    511   }  // end switch
    512 }
    513 
    514 void X86_32Relocator::scanGlobalReloc(Relocation& pReloc,
    515                                       IRBuilder& pBuilder,
    516                                       Module& pModule,
    517                                       LDSection& pSection) {
    518   // rsym - The relocation target symbol
    519   ResolveInfo* rsym = pReloc.symInfo();
    520 
    521   switch (pReloc.type()) {
    522     case llvm::ELF::R_386_32:
    523     case llvm::ELF::R_386_16:
    524     case llvm::ELF::R_386_8:
    525       // Absolute relocation type, symbol may needs PLT entry or
    526       // dynamic relocation entry
    527       if (getTarget().symbolNeedsPLT(*rsym)) {
    528         // create plt for this symbol if it does not have one
    529         if (!(rsym->reserved() & ReservePLT)) {
    530           // Symbol needs PLT entry, we need a PLT entry
    531           // and the corresponding GOT and dynamic relocation entry
    532           // in .got and .rel.plt.
    533           helper_PLT_init(pReloc, *this);
    534           // set PLT bit
    535           rsym->setReserved(rsym->reserved() | ReservePLT);
    536         }
    537       }
    538 
    539       if (getTarget()
    540               .symbolNeedsDynRel(
    541                   *rsym, (rsym->reserved() & ReservePLT), true)) {
    542         // symbol needs dynamic relocation entry, set up the dynrel entry
    543         if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
    544           LDSymbol& cpy_sym =
    545               defineSymbolforCopyReloc(pBuilder, *rsym, getTarget());
    546           addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
    547         } else {
    548           // set Rel bit and the dyn rel
    549           rsym->setReserved(rsym->reserved() | ReserveRel);
    550           getTarget().checkAndSetHasTextRel(*pSection.getLink());
    551           if (llvm::ELF::R_386_32 == pReloc.type() &&
    552               helper_use_relative_reloc(*rsym, *this)) {
    553             helper_DynRel_init(rsym,
    554                                *pReloc.targetRef().frag(),
    555                                pReloc.targetRef().offset(),
    556                                llvm::ELF::R_386_RELATIVE,
    557                                *this);
    558           } else {
    559             helper_DynRel_init(rsym,
    560                                *pReloc.targetRef().frag(),
    561                                pReloc.targetRef().offset(),
    562                                pReloc.type(),
    563                                *this);
    564           }
    565         }
    566       }
    567       return;
    568 
    569     case llvm::ELF::R_386_GOTOFF:
    570     case llvm::ELF::R_386_GOTPC: {
    571       // FIXME: A GOT section is needed
    572       return;
    573     }
    574 
    575     case llvm::ELF::R_386_PLT32:
    576       // A PLT entry is needed when building shared library
    577 
    578       // return if we already create plt for this symbol
    579       if (rsym->reserved() & ReservePLT)
    580         return;
    581 
    582       // if the symbol's value can be decided at link time, then no need plt
    583       if (getTarget().symbolFinalValueIsKnown(*rsym))
    584         return;
    585 
    586       // if symbol is defined in the ouput file and it's not
    587       // preemptible, no need plt
    588       if (rsym->isDefine() && !rsym->isDyn() &&
    589           !getTarget().isSymbolPreemptible(*rsym))
    590         return;
    591 
    592       // Symbol needs PLT entry, we need a PLT entry
    593       // and the corresponding GOT and dynamic relocation entry
    594       // in .got and .rel.plt
    595       helper_PLT_init(pReloc, *this);
    596       // set PLT bit
    597       rsym->setReserved(rsym->reserved() | ReservePLT);
    598       return;
    599 
    600     case llvm::ELF::R_386_GOT32:
    601       // Symbol needs GOT entry, reserve entry in .got
    602       // return if we already create GOT for this symbol
    603       if (rsym->reserved() & ReserveGOT)
    604         return;
    605       // if the symbol cannot be fully resolved at link time, then we need a
    606       // dynamic relocation
    607       if (!getTarget().symbolFinalValueIsKnown(*rsym))
    608         helper_GOT_init(pReloc, true, *this);
    609       else
    610         helper_GOT_init(pReloc, false, *this);
    611       // set GOT bit
    612       rsym->setReserved(rsym->reserved() | ReserveGOT);
    613       return;
    614 
    615     case llvm::ELF::R_386_PC32:
    616     case llvm::ELF::R_386_PC16:
    617     case llvm::ELF::R_386_PC8:
    618 
    619       if (getTarget().symbolNeedsPLT(*rsym) &&
    620           LinkerConfig::DynObj != config().codeGenType()) {
    621         // create plt for this symbol if it does not have one
    622         if (!(rsym->reserved() & ReservePLT)) {
    623           // Symbol needs PLT entry, we need a PLT entry
    624           // and the corresponding GOT and dynamic relocation entry
    625           // in .got and .rel.plt.
    626           // set PLT bit
    627           helper_PLT_init(pReloc, *this);
    628           rsym->setReserved(rsym->reserved() | ReservePLT);
    629         }
    630       }
    631 
    632       if (getTarget()
    633               .symbolNeedsDynRel(
    634                   *rsym, (rsym->reserved() & ReservePLT), false)) {
    635         // symbol needs dynamic relocation entry, setup an entry in .rel.dyn
    636         if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
    637           LDSymbol& cpy_sym =
    638               defineSymbolforCopyReloc(pBuilder, *rsym, getTarget());
    639           addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
    640         } else {
    641           // set Rel bit and the dyn rel
    642           rsym->setReserved(rsym->reserved() | ReserveRel);
    643           getTarget().checkAndSetHasTextRel(*pSection.getLink());
    644           if (llvm::ELF::R_386_32 == pReloc.type() &&
    645               helper_use_relative_reloc(*rsym, *this)) {
    646             helper_DynRel_init(rsym,
    647                                *pReloc.targetRef().frag(),
    648                                pReloc.targetRef().offset(),
    649                                llvm::ELF::R_386_RELATIVE,
    650                                *this);
    651           } else {
    652             helper_DynRel_init(rsym,
    653                                *pReloc.targetRef().frag(),
    654                                pReloc.targetRef().offset(),
    655                                pReloc.type(),
    656                                *this);
    657           }
    658         }
    659       }
    660       return;
    661 
    662     case llvm::ELF::R_386_TLS_GD: {
    663       // FIXME: no linker optimization for TLS relocation
    664       if (rsym->reserved() & ReserveGOT)
    665         return;
    666 
    667       // set up a pair of got entries and a pair of dyn rel
    668       X86_32GOTEntry* got_entry1 = getTarget().getGOT().create();
    669       X86_32GOTEntry* got_entry2 = getTarget().getGOT().create();
    670       getSymGOTMap().record(*rsym, *got_entry1, *got_entry2);
    671       got_entry1->setValue(0x0);
    672       got_entry2->setValue(0x0);
    673       // setup dyn rel for got entries against rsym
    674       helper_DynRel_init(
    675           rsym, *got_entry1, 0x0, llvm::ELF::R_386_TLS_DTPMOD32, *this);
    676       helper_DynRel_init(
    677           rsym, *got_entry2, 0x0, llvm::ELF::R_386_TLS_DTPOFF32, *this);
    678 
    679       // add the rsym to dynamic symbol table
    680       getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
    681       // set GOT bit
    682       rsym->setReserved(rsym->reserved() | ReserveGOT);
    683       return;
    684     }
    685 
    686     case llvm::ELF::R_386_TLS_LDM:
    687       getTLSModuleID();
    688       return;
    689 
    690     case llvm::ELF::R_386_TLS_LDO_32:
    691       return;
    692 
    693     case llvm::ELF::R_386_TLS_IE: {
    694       getTarget().setHasStaticTLS();
    695       // if buildint shared object, a RELATIVE dynamic relocation is needed
    696       if (LinkerConfig::DynObj == config().codeGenType()) {
    697         helper_DynRel_init(rsym,
    698                            *pReloc.targetRef().frag(),
    699                            pReloc.targetRef().offset(),
    700                            llvm::ELF::R_386_RELATIVE,
    701                            *this);
    702         rsym->setReserved(rsym->reserved() | ReserveRel);
    703         getTarget().checkAndSetHasTextRel(*pSection.getLink());
    704       } else {
    705         // for global sym, we can convert ie to le if its final value is known
    706         if (getTarget().symbolFinalValueIsKnown(*rsym)) {
    707           convertTLSIEtoLE(pReloc, pSection);
    708           return;
    709         }
    710       }
    711       if (rsym->reserved() & ReserveGOT)
    712         return;
    713       // set up the got and the corresponding rel entry
    714       X86_32GOTEntry* got_entry = getTarget().getGOT().create();
    715       getSymGOTMap().record(*rsym, *got_entry);
    716       got_entry->setValue(0x0);
    717       helper_DynRel_init(
    718           rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, *this);
    719       // set GOT bit
    720       rsym->setReserved(rsym->reserved() | ReserveGOT);
    721       return;
    722     }
    723 
    724     case llvm::ELF::R_386_TLS_GOTIE: {
    725       getTarget().setHasStaticTLS();
    726       if (rsym->reserved() & ReserveGOT)
    727         return;
    728       // set up the got and the corresponding dyn rel
    729       X86_32GOTEntry* got_entry = getTarget().getGOT().create();
    730       getSymGOTMap().record(*rsym, *got_entry);
    731       got_entry->setValue(0x0);
    732       helper_DynRel_init(
    733           rsym, *got_entry, 0x0, llvm::ELF::R_386_TLS_TPOFF, *this);
    734       getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
    735       // set GOT bit
    736       rsym->setReserved(rsym->reserved() | ReserveGOT);
    737       return;
    738     }
    739 
    740     case llvm::ELF::R_386_TLS_LE:
    741     case llvm::ELF::R_386_TLS_LE_32:
    742       getTarget().setHasStaticTLS();
    743       // if buildint shared object, a dynamic relocation is needed
    744       if (LinkerConfig::DynObj == config().codeGenType()) {
    745         helper_DynRel_init(rsym,
    746                            *pReloc.targetRef().frag(),
    747                            pReloc.targetRef().offset(),
    748                            llvm::ELF::R_386_TLS_TPOFF,
    749                            *this);
    750         getTarget().getRelDyn().addSymbolToDynSym(*rsym->outSymbol());
    751         rsym->setReserved(rsym->reserved() | ReserveRel);
    752         getTarget().checkAndSetHasTextRel(*pSection.getLink());
    753       }
    754       return;
    755 
    756     default: {
    757       fatal(diag::unsupported_relocation) << static_cast<int>(pReloc.type())
    758                                           << "mclinker (at) googlegroups.com";
    759       break;
    760     }
    761   }  // end switch
    762 }
    763 
    764 // Create a GOT entry for the TLS module index
    765 X86_32GOTEntry& X86_32Relocator::getTLSModuleID() {
    766   static X86_32GOTEntry* got_entry = NULL;
    767   if (got_entry != NULL)
    768     return *got_entry;
    769 
    770   // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
    771   got_entry = getTarget().getGOT().create();
    772   getTarget().getGOT().create()->setValue(0x0);
    773 
    774   helper_DynRel_init(
    775       NULL, *got_entry, 0x0, llvm::ELF::R_386_TLS_DTPMOD32, *this);
    776   return *got_entry;
    777 }
    778 
    779 /// convert R_386_TLS_IE to R_386_TLS_LE
    780 void X86_32Relocator::convertTLSIEtoLE(Relocation& pReloc,
    781                                        LDSection& pSection) {
    782   assert(pReloc.type() == llvm::ELF::R_386_TLS_IE);
    783   assert(pReloc.targetRef().frag() != NULL);
    784 
    785   // 1. create the new relocs
    786   Relocation* reloc =
    787       Relocation::Create(X86_32Relocator::R_386_TLS_OPT,
    788                          *FragmentRef::Create(*pReloc.targetRef().frag(),
    789                                               pReloc.targetRef().offset() - 1),
    790                          0x0);
    791   // FIXME: should we create a special symbol for the tls opt instead?
    792   reloc->setSymInfo(pReloc.symInfo());
    793 
    794   // 2. modify the opcodes to the appropriate ones
    795   uint8_t* op = (reinterpret_cast<uint8_t*>(&reloc->target()));
    796   if (op[0] == 0xa1) {
    797     op[0] = 0xb8;
    798   } else {
    799     // create the new reloc (move 1 byte forward).
    800     reloc = Relocation::Create(
    801         X86_32Relocator::R_386_TLS_OPT,
    802         *FragmentRef::Create(*pReloc.targetRef().frag(),
    803                              pReloc.targetRef().offset() - 2),
    804         0x0);
    805     reloc->setSymInfo(pReloc.symInfo());
    806     op = (reinterpret_cast<uint8_t*>(&reloc->target()));
    807     switch (op[0]) {
    808       case 0x8b:
    809         assert((op[1] & 0xc7) == 0x05);
    810         op[0] = 0xc7;
    811         op[1] = 0xc0 | ((op[1] >> 3) & 7);
    812         break;
    813       case 0x03:
    814         assert((op[1] & 0xc7) == 0x05);
    815         op[0] = 0x81;
    816         op[1] = 0xc0 | ((op[1] >> 3) & 7);
    817         break;
    818       default:
    819         assert(0);
    820         break;
    821     }
    822   }
    823 
    824   // 3. insert the new relocs "BEFORE" the original reloc.
    825   assert(reloc != NULL);
    826   pSection.getRelocData()->getRelocationList().insert(
    827       RelocData::iterator(pReloc), reloc);
    828 
    829   // 4. change the type of the original reloc
    830   pReloc.setType(llvm::ELF::R_386_TLS_LE);
    831 }
    832 
    833 uint32_t X86_32Relocator::getDebugStringOffset(Relocation& pReloc) const {
    834   if (pReloc.type() != llvm::ELF::R_386_32)
    835     error(diag::unsupport_reloc_for_debug_string)
    836         << getName(pReloc.type()) << "mclinker (at) googlegroups.com";
    837 
    838   if (pReloc.symInfo()->type() == ResolveInfo::Section)
    839     return pReloc.target() + pReloc.addend();
    840   else
    841     return pReloc.symInfo()->outSymbol()->fragRef()->offset() +
    842                pReloc.target() + pReloc.addend();
    843 }
    844 
    845 void X86_32Relocator::applyDebugStringOffset(Relocation& pReloc,
    846                                              uint32_t pOffset) {
    847   pReloc.target() = pOffset;
    848 }
    849 
    850 //================================================//
    851 // X86_32 Each relocation function implementation //
    852 //================================================//
    853 
    854 // R_386_NONE
    855 Relocator::Result none(Relocation& pReloc, X86_32Relocator& pParent) {
    856   return Relocator::OK;
    857 }
    858 
    859 // R_386_32: S + A
    860 // R_386_16
    861 // R_386_8
    862 Relocator::Result abs(Relocation& pReloc, X86_32Relocator& pParent) {
    863   ResolveInfo* rsym = pReloc.symInfo();
    864   Relocator::DWord A = pReloc.target() + pReloc.addend();
    865   Relocator::DWord S = pReloc.symValue();
    866   bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel(
    867       *rsym, (rsym->reserved() & X86Relocator::ReservePLT), true);
    868 
    869   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
    870   // If the flag of target section is not ALLOC, we will not scan this
    871   // relocation but perform static relocation. (e.g., applying .debug section)
    872   if ((llvm::ELF::SHF_ALLOC & target_sect.flag()) == 0x0) {
    873     pReloc.target() = S + A;
    874     return Relocator::OK;
    875   }
    876 
    877   // An external symbol may need PLT and dynamic relocation
    878   if (!rsym->isLocal()) {
    879     if (rsym->reserved() & X86Relocator::ReservePLT) {
    880       S = helper_get_PLT_address(*rsym, pParent);
    881     }
    882     // If we generate a dynamic relocation (except R_386_RELATIVE)
    883     // for a place, we should not perform static relocation on it
    884     // in order to keep the addend store in the place correct.
    885     if (has_dyn_rel)
    886       if (llvm::ELF::R_386_32 != pReloc.type() ||
    887           (!helper_use_relative_reloc(*rsym, pParent)))
    888         return Relocator::OK;
    889   }
    890 
    891   // perform static relocation
    892   pReloc.target() = S + A;
    893   return Relocator::OK;
    894 }
    895 
    896 // R_386_PC32: S + A - P
    897 // R_386_PC16
    898 // R_386_PC8
    899 Relocator::Result rel(Relocation& pReloc, X86_32Relocator& pParent) {
    900   ResolveInfo* rsym = pReloc.symInfo();
    901   Relocator::DWord A = pReloc.target() + pReloc.addend();
    902   Relocator::DWord S = pReloc.symValue();
    903   Relocator::DWord P = pReloc.place();
    904   bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel(
    905       *rsym, (rsym->reserved() & X86Relocator::ReservePLT), true);
    906 
    907   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
    908   // If the flag of target section is not ALLOC, we will not scan this
    909   // relocation
    910   // but perform static relocation. (e.g., applying .debug section)
    911   if ((llvm::ELF::SHF_ALLOC & target_sect.flag()) == 0x0) {
    912     pReloc.target() = S + A - P;
    913     return Relocator::OK;
    914   }
    915 
    916   // An external symbol may need PLT and dynamic relocation
    917   if (!rsym->isLocal()) {
    918     if (rsym->reserved() & X86Relocator::ReservePLT) {
    919       S = helper_get_PLT_address(*rsym, pParent);
    920       pReloc.target() = S + A - P;
    921     }
    922     if (has_dyn_rel)
    923       if (!helper_use_relative_reloc(*rsym, pParent))
    924         return Relocator::OK;
    925   }
    926 
    927   // perform static relocation
    928   pReloc.target() = S + A - P;
    929   return Relocator::OK;
    930 }
    931 
    932 // R_386_GOTOFF: S + A - GOT_ORG
    933 Relocator::Result gotoff32(Relocation& pReloc, X86_32Relocator& pParent) {
    934   Relocator::DWord A = pReloc.target() + pReloc.addend();
    935   Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
    936   Relocator::Address S = pReloc.symValue();
    937 
    938   pReloc.target() = S + A - GOT_ORG;
    939   return Relocator::OK;
    940 }
    941 
    942 // R_386_GOTPC: GOT_ORG + A - P
    943 Relocator::Result gotpc32(Relocation& pReloc, X86_32Relocator& pParent) {
    944   Relocator::DWord A = pReloc.target() + pReloc.addend();
    945   Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
    946   // Apply relocation.
    947   pReloc.target() = GOT_ORG + A - pReloc.place();
    948   return Relocator::OK;
    949 }
    950 
    951 // R_386_GOT32: GOT(S) + A - GOT_ORG
    952 Relocator::Result got32(Relocation& pReloc, X86_32Relocator& pParent) {
    953   ResolveInfo* rsym = pReloc.symInfo();
    954   if (!(rsym->reserved() & (X86Relocator::ReserveGOT)))
    955     return Relocator::BadReloc;
    956 
    957   // set up got entry value if the got has no dyn rel or
    958   // the dyn rel is RELATIVE
    959   X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
    960   assert(got_entry != NULL);
    961   if (got_entry->getValue() == X86Relocator::SymVal)
    962     got_entry->setValue(pReloc.symValue());
    963 
    964   Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent);
    965   Relocator::DWord A = pReloc.target() + pReloc.addend();
    966   Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
    967   // Apply relocation.
    968   pReloc.target() = GOT_S + A - GOT_ORG;
    969   return Relocator::OK;
    970 }
    971 
    972 // R_386_PLT32: PLT(S) + A - P
    973 Relocator::Result plt32(Relocation& pReloc, X86_32Relocator& pParent) {
    974   // PLT_S depends on if there is a PLT entry.
    975   Relocator::Address PLT_S;
    976   if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT))
    977     PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
    978   else
    979     PLT_S = pReloc.symValue();
    980   Relocator::DWord A = pReloc.target() + pReloc.addend();
    981   Relocator::Address P = pReloc.place();
    982   pReloc.target() = PLT_S + A - P;
    983   return Relocator::OK;
    984 }
    985 
    986 // R_386_TLS_GD:
    987 Relocator::Result tls_gd(Relocation& pReloc, X86_32Relocator& pParent) {
    988   // global-dynamic
    989   ResolveInfo* rsym = pReloc.symInfo();
    990   // must reserve two pairs of got and dynamic relocation
    991   if (!(rsym->reserved() & X86Relocator::ReserveGOT))
    992     return Relocator::BadReloc;
    993 
    994   ELFFileFormat* file_format = pParent.getTarget().getOutputFormat();
    995   // setup corresponding got and dynamic relocatio entries:
    996   // get first got entry, if there is already a got entry for rsym, then apply
    997   // this relocation to the got entry directly. If not, setup the corresponding
    998   // got and dyn relocation entries
    999   X86_32GOTEntry* got_entry1 = pParent.getSymGOTMap().lookUpFirstEntry(*rsym);
   1000 
   1001   // set the got_entry2 value to symbol value
   1002   if (rsym->isLocal())
   1003     pParent.getSymGOTMap().lookUpSecondEntry(*rsym)->setValue(
   1004         pReloc.symValue());
   1005 
   1006   // perform relocation to the first got entry
   1007   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1008   // GOT_OFF - the offset between the got_entry1 and _GLOBAL_OFFSET_TABLE (the
   1009   // .got.plt section)
   1010   Relocator::Address GOT_OFF = file_format->getGOT().addr() +
   1011                                got_entry1->getOffset() -
   1012                                file_format->getGOTPLT().addr();
   1013   pReloc.target() = GOT_OFF + A;
   1014   return Relocator::OK;
   1015 }
   1016 
   1017 // R_386_TLS_LDM
   1018 Relocator::Result tls_ldm(Relocation& pReloc, X86_32Relocator& pParent) {
   1019   // FIXME: no linker optimization for TLS relocation
   1020   const X86_32GOTEntry& got_entry = pParent.getTLSModuleID();
   1021 
   1022   // All GOT offsets are relative to the end of the GOT.
   1023   X86Relocator::SWord GOT_S =
   1024       got_entry.getOffset() - (pParent.getTarget().getGOTPLT().addr() -
   1025                                pParent.getTarget().getGOT().addr());
   1026   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1027   pReloc.target() = GOT_S + A;
   1028 
   1029   return Relocator::OK;
   1030 }
   1031 
   1032 // R_386_TLS_LDO_32
   1033 Relocator::Result tls_ldo_32(Relocation& pReloc, X86_32Relocator& pParent) {
   1034   // FIXME: no linker optimization for TLS relocation
   1035   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1036   Relocator::Address S = pReloc.symValue();
   1037   pReloc.target() = S + A;
   1038   return Relocator::OK;
   1039 }
   1040 
   1041 // R_X86_TLS_IE
   1042 Relocator::Result tls_ie(Relocation& pReloc, X86_32Relocator& pParent) {
   1043   ResolveInfo* rsym = pReloc.symInfo();
   1044   if (!(rsym->reserved() & X86Relocator::ReserveGOT)) {
   1045     return Relocator::BadReloc;
   1046   }
   1047 
   1048   // set up the got and dynamic relocation entries if not exist
   1049   X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
   1050   assert(got_entry != NULL);
   1051   // perform relocation to the absolute address of got_entry
   1052   Relocator::Address GOT_S =
   1053       pParent.getTarget().getGOT().addr() + got_entry->getOffset();
   1054 
   1055   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1056   pReloc.target() = GOT_S + A;
   1057 
   1058   return Relocator::OK;
   1059 }
   1060 
   1061 // R_386_TLS_GOTIE
   1062 Relocator::Result tls_gotie(Relocation& pReloc, X86_32Relocator& pParent) {
   1063   ResolveInfo* rsym = pReloc.symInfo();
   1064   if (!(rsym->reserved() & X86Relocator::ReserveGOT)) {
   1065     return Relocator::BadReloc;
   1066   }
   1067 
   1068   // set up the got and dynamic relocation entries if not exist
   1069   X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym);
   1070   assert(got_entry != NULL);
   1071 
   1072   // All GOT offsets are relative to the end of the GOT.
   1073   X86Relocator::SWord GOT_S =
   1074       got_entry->getOffset() - (pParent.getTarget().getGOTPLT().addr() -
   1075                                 pParent.getTarget().getGOT().addr());
   1076   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1077   pReloc.target() = GOT_S + A;
   1078 
   1079   return Relocator::OK;
   1080 }
   1081 
   1082 // R_X86_TLS_LE
   1083 Relocator::Result tls_le(Relocation& pReloc, X86_32Relocator& pParent) {
   1084   if (pReloc.symInfo()->reserved() & X86Relocator::ReserveRel)
   1085     return Relocator::OK;
   1086 
   1087   // perform static relocation
   1088   // get TLS segment
   1089   ELFSegmentFactory::const_iterator tls_seg =
   1090       pParent.getTarget().elfSegmentTable().find(
   1091           llvm::ELF::PT_TLS, llvm::ELF::PF_R, 0x0);
   1092   assert(tls_seg != pParent.getTarget().elfSegmentTable().end());
   1093   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1094   Relocator::Address S = pReloc.symValue();
   1095   pReloc.target() = S + A - (*tls_seg)->memsz();
   1096   return Relocator::OK;
   1097 }
   1098 
   1099 Relocator::Result unsupported(Relocation& pReloc, X86_32Relocator& pParent) {
   1100   return Relocator::Unsupported;
   1101 }
   1102 
   1103 //===--------------------------------------------------------------------===//
   1104 // X86_64 Relocation helper function
   1105 //===--------------------------------------------------------------------===//
   1106 /// helper_DynRel - Get an relocation entry in .rela.dyn
   1107 static Relocation& helper_DynRel_init(ResolveInfo* pSym,
   1108                                       Fragment& pFrag,
   1109                                       uint64_t pOffset,
   1110                                       Relocator::Type pType,
   1111                                       X86_64Relocator& pParent) {
   1112   X86_64GNULDBackend& ld_backend = pParent.getTarget();
   1113   Relocation& rel_entry = *ld_backend.getRelDyn().create();
   1114   rel_entry.setType(pType);
   1115   rel_entry.targetRef().assign(pFrag, pOffset);
   1116   if (pType == llvm::ELF::R_X86_64_RELATIVE || pSym == NULL)
   1117     rel_entry.setSymInfo(NULL);
   1118   else
   1119     rel_entry.setSymInfo(pSym);
   1120 
   1121   return rel_entry;
   1122 }
   1123 
   1124 /// helper_use_relative_reloc - Check if symbol can use relocation
   1125 /// R_X86_64_RELATIVE
   1126 static bool helper_use_relative_reloc(const ResolveInfo& pSym,
   1127                                       const X86_64Relocator& pFactory) {
   1128   // if symbol is dynamic or undefine or preemptible
   1129   if (pSym.isDyn() || pSym.isUndef() ||
   1130       pFactory.getTarget().isSymbolPreemptible(pSym))
   1131     return false;
   1132   return true;
   1133 }
   1134 
   1135 static X86_64GOTEntry& helper_GOT_init(Relocation& pReloc,
   1136                                        bool pHasRel,
   1137                                        X86_64Relocator& pParent) {
   1138   // rsym - The relocation target symbol
   1139   ResolveInfo* rsym = pReloc.symInfo();
   1140   X86_64GNULDBackend& ld_backend = pParent.getTarget();
   1141   assert(pParent.getSymGOTMap().lookUp(*rsym) == NULL);
   1142 
   1143   X86_64GOTEntry* got_entry = ld_backend.getGOT().create();
   1144   pParent.getSymGOTMap().record(*rsym, *got_entry);
   1145 
   1146   // If we first get this GOT entry, we should initialize it.
   1147   if (!pHasRel) {
   1148     // No corresponding dynamic relocation, initialize to the symbol value.
   1149     got_entry->setValue(X86Relocator::SymVal);
   1150   } else {
   1151     // Initialize got_entry content and the corresponding dynamic relocation.
   1152     if (helper_use_relative_reloc(*rsym, pParent)) {
   1153       Relocation& rel_entry = helper_DynRel_init(
   1154           rsym, *got_entry, 0x0, llvm::ELF::R_X86_64_RELATIVE, pParent);
   1155       rel_entry.setAddend(X86Relocator::SymVal);
   1156       pParent.getRelRelMap().record(pReloc, rel_entry);
   1157     } else {
   1158       helper_DynRel_init(
   1159           rsym, *got_entry, 0x0, llvm::ELF::R_X86_64_GLOB_DAT, pParent);
   1160     }
   1161     got_entry->setValue(0);
   1162   }
   1163   return *got_entry;
   1164 }
   1165 
   1166 static Relocator::Address helper_GOT_ORG(X86_64Relocator& pParent) {
   1167   return pParent.getTarget().getGOT().addr();
   1168 }
   1169 
   1170 static Relocator::Address helper_get_GOT_address(Relocation& pReloc,
   1171                                                  X86_64Relocator& pParent) {
   1172   X86_64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
   1173   assert(got_entry != NULL);
   1174   return got_entry->getOffset();
   1175 }
   1176 
   1177 static Relocator::Address helper_get_PLT_address(ResolveInfo& pSym,
   1178                                                  X86_64Relocator& pParent) {
   1179   PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym);
   1180   assert(plt_entry != NULL);
   1181   return pParent.getTarget().getPLT().addr() + plt_entry->getOffset();
   1182 }
   1183 
   1184 static PLTEntryBase& helper_PLT_init(Relocation& pReloc,
   1185                                      X86_64Relocator& pParent) {
   1186   // rsym - The relocation target symbol
   1187   ResolveInfo* rsym = pReloc.symInfo();
   1188   X86_64GNULDBackend& ld_backend = pParent.getTarget();
   1189   assert(pParent.getSymPLTMap().lookUp(*rsym) == NULL);
   1190 
   1191   PLTEntryBase* plt_entry = ld_backend.getPLT().create();
   1192   pParent.getSymPLTMap().record(*rsym, *plt_entry);
   1193 
   1194   // initialize plt and the corresponding gotplt and dyn rel entry.
   1195   assert(pParent.getSymGOTPLTMap().lookUp(*rsym) == NULL &&
   1196          "PLT entry not exist, but DynRel entry exist!");
   1197   X86_64GOTEntry* gotplt_entry = ld_backend.getGOTPLT().create();
   1198   pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
   1199 
   1200   // init the corresponding rel entry in .rel.plt
   1201   Relocation& rel_entry = *ld_backend.getRelPLT().create();
   1202   rel_entry.setType(llvm::ELF::R_X86_64_JUMP_SLOT);
   1203   rel_entry.targetRef().assign(*gotplt_entry);
   1204   rel_entry.setSymInfo(rsym);
   1205   return *plt_entry;
   1206 }
   1207 
   1208 //===----------------------------------------------------------------------===//
   1209 // X86_64 Relocation Functions and Tables
   1210 //===----------------------------------------------------------------------===//
   1211 DECL_X86_64_APPLY_RELOC_FUNCS
   1212 
   1213 /// the prototype of applying function
   1214 typedef Relocator::Result (*X86_64ApplyFunctionType)(Relocation& pReloc,
   1215                                                      X86_64Relocator& pParent);
   1216 
   1217 // the table entry of applying functions
   1218 struct X86_64ApplyFunctionTriple {
   1219   X86_64ApplyFunctionType func;
   1220   unsigned int type;
   1221   const char* name;
   1222   unsigned int size;
   1223 };
   1224 
   1225 // declare the table of applying functions
   1226 static const X86_64ApplyFunctionTriple X86_64ApplyFunctions[] = {
   1227     DECL_X86_64_APPLY_RELOC_FUNC_PTRS};
   1228 
   1229 //===--------------------------------------------------------------------===//
   1230 // X86_64Relocator
   1231 //===--------------------------------------------------------------------===//
   1232 X86_64Relocator::X86_64Relocator(X86_64GNULDBackend& pParent,
   1233                                  const LinkerConfig& pConfig)
   1234     : X86Relocator(pConfig), m_Target(pParent) {
   1235 }
   1236 
   1237 Relocator::Result X86_64Relocator::applyRelocation(Relocation& pRelocation) {
   1238   Relocation::Type type = pRelocation.type();
   1239 
   1240   if (type >= sizeof(X86_64ApplyFunctions) / sizeof(X86_64ApplyFunctions[0])) {
   1241     return Unknown;
   1242   }
   1243 
   1244   // apply the relocation
   1245   return X86_64ApplyFunctions[type].func(pRelocation, *this);
   1246 }
   1247 
   1248 const char* X86_64Relocator::getName(Relocation::Type pType) const {
   1249   return X86_64ApplyFunctions[pType].name;
   1250 }
   1251 
   1252 Relocator::Size X86_64Relocator::getSize(Relocation::Type pType) const {
   1253   return X86_64ApplyFunctions[pType].size;
   1254 }
   1255 
   1256 bool X86_64Relocator::mayHaveFunctionPointerAccess(
   1257     const Relocation& pReloc) const {
   1258   bool possible_funcptr_reloc = false;
   1259   switch (pReloc.type()) {
   1260     case llvm::ELF::R_X86_64_64:
   1261     case llvm::ELF::R_X86_64_32:
   1262     case llvm::ELF::R_X86_64_32S:
   1263     case llvm::ELF::R_X86_64_16:
   1264     case llvm::ELF::R_X86_64_8:
   1265     case llvm::ELF::R_X86_64_GOT64:
   1266     case llvm::ELF::R_X86_64_GOT32:
   1267     case llvm::ELF::R_X86_64_GOTPCREL64:
   1268     case llvm::ELF::R_X86_64_GOTPCREL:
   1269     case llvm::ELF::R_X86_64_GOTPLT64: {
   1270       possible_funcptr_reloc = true;
   1271       break;
   1272     }
   1273     default: {
   1274       possible_funcptr_reloc = false;
   1275       break;
   1276     }
   1277   }
   1278 
   1279   if (pReloc.symInfo()->isGlobal()) {
   1280     return (config().codeGenType() == LinkerConfig::DynObj) &&
   1281            ((pReloc.symInfo()->visibility() != ResolveInfo::Default) ||
   1282             possible_funcptr_reloc);
   1283   } else {
   1284     return (config().codeGenType() == LinkerConfig::DynObj) ||
   1285            possible_funcptr_reloc;
   1286   }
   1287 }
   1288 
   1289 void X86_64Relocator::scanLocalReloc(Relocation& pReloc,
   1290                                      IRBuilder& pBuilder,
   1291                                      Module& pModule,
   1292                                      LDSection& pSection) {
   1293   // rsym - The relocation target symbol
   1294   ResolveInfo* rsym = pReloc.symInfo();
   1295 
   1296   switch (pReloc.type()) {
   1297     case llvm::ELF::R_X86_64_64:
   1298       // If buiding PIC object (shared library or PIC executable),
   1299       // a dynamic relocations with RELATIVE type to this location is needed.
   1300       // Reserve an entry in .rela.dyn
   1301       if (config().isCodeIndep()) {
   1302         Relocation& reloc = helper_DynRel_init(rsym,
   1303                                                *pReloc.targetRef().frag(),
   1304                                                pReloc.targetRef().offset(),
   1305                                                llvm::ELF::R_X86_64_RELATIVE,
   1306                                                *this);
   1307         getRelRelMap().record(pReloc, reloc);
   1308         // set Rel bit
   1309         rsym->setReserved(rsym->reserved() | ReserveRel);
   1310         getTarget().checkAndSetHasTextRel(*pSection.getLink());
   1311       }
   1312       return;
   1313 
   1314     case llvm::ELF::R_X86_64_32:
   1315     case llvm::ELF::R_X86_64_16:
   1316     case llvm::ELF::R_X86_64_8:
   1317     case llvm::ELF::R_X86_64_32S:
   1318       // If buiding PIC object (shared library or PIC executable),
   1319       // a dynamic relocations with RELATIVE type to this location is needed.
   1320       // Reserve an entry in .rela.dyn
   1321       if (config().isCodeIndep()) {
   1322         Relocation& reloc = helper_DynRel_init(rsym,
   1323                                                *pReloc.targetRef().frag(),
   1324                                                pReloc.targetRef().offset(),
   1325                                                pReloc.type(),
   1326                                                *this);
   1327         getRelRelMap().record(pReloc, reloc);
   1328         // set Rel bit
   1329         rsym->setReserved(rsym->reserved() | ReserveRel);
   1330         getTarget().checkAndSetHasTextRel(*pSection.getLink());
   1331       }
   1332       return;
   1333 
   1334     case llvm::ELF::R_X86_64_PC32:
   1335     case llvm::ELF::R_X86_64_PC16:
   1336     case llvm::ELF::R_X86_64_PC8:
   1337       return;
   1338 
   1339     case llvm::ELF::R_X86_64_GOTPCREL:
   1340       // Symbol needs GOT entry, reserve entry in .got
   1341       // return if we already create GOT for this symbol
   1342       if (rsym->reserved() & ReserveGOT)
   1343         return;
   1344 
   1345       // If building PIC object, a dynamic relocation with
   1346       // type RELATIVE is needed to relocate this GOT entry.
   1347       if (config().isCodeIndep())
   1348         helper_GOT_init(pReloc, true, *this);
   1349       else
   1350         helper_GOT_init(pReloc, false, *this);
   1351       rsym->setReserved(rsym->reserved() | ReserveGOT);
   1352       return;
   1353 
   1354     default:
   1355       fatal(diag::unsupported_relocation) << static_cast<int>(pReloc.type())
   1356                                           << "mclinker (at) googlegroups.com";
   1357       break;
   1358   }  // end switch
   1359 }
   1360 
   1361 void X86_64Relocator::scanGlobalReloc(Relocation& pReloc,
   1362                                       IRBuilder& pBuilder,
   1363                                       Module& pModule,
   1364                                       LDSection& pSection) {
   1365   // rsym - The relocation target symbol
   1366   ResolveInfo* rsym = pReloc.symInfo();
   1367 
   1368   switch (pReloc.type()) {
   1369     case llvm::ELF::R_X86_64_64:
   1370     case llvm::ELF::R_X86_64_32:
   1371     case llvm::ELF::R_X86_64_16:
   1372     case llvm::ELF::R_X86_64_8:
   1373     case llvm::ELF::R_X86_64_32S:
   1374       // Absolute relocation type, symbol may needs PLT entry or
   1375       // dynamic relocation entry
   1376       if (getTarget().symbolNeedsPLT(*rsym)) {
   1377         // create plt for this symbol if it does not have one
   1378         if (!(rsym->reserved() & ReservePLT)) {
   1379           // Symbol needs PLT entry, we need to reserve a PLT entry
   1380           // and the corresponding GOT and dynamic relocation entry
   1381           // in .got and .rela.plt.
   1382           helper_PLT_init(pReloc, *this);
   1383           // set PLT bit
   1384           rsym->setReserved(rsym->reserved() | ReservePLT);
   1385         }
   1386       }
   1387 
   1388       if (getTarget()
   1389               .symbolNeedsDynRel(
   1390                   *rsym, (rsym->reserved() & ReservePLT), true)) {
   1391         // symbol needs dynamic relocation entry, set up the dynrel entry
   1392         if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
   1393           LDSymbol& cpy_sym =
   1394               defineSymbolforCopyReloc(pBuilder, *rsym, getTarget());
   1395           addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
   1396         } else {
   1397           // set Rel bit and the dyn rel
   1398           rsym->setReserved(rsym->reserved() | ReserveRel);
   1399           getTarget().checkAndSetHasTextRel(*pSection.getLink());
   1400           if (llvm::ELF::R_386_32 == pReloc.type() &&
   1401               helper_use_relative_reloc(*rsym, *this)) {
   1402             Relocation& reloc = helper_DynRel_init(rsym,
   1403                                                    *pReloc.targetRef().frag(),
   1404                                                    pReloc.targetRef().offset(),
   1405                                                    llvm::ELF::R_X86_64_RELATIVE,
   1406                                                    *this);
   1407             getRelRelMap().record(pReloc, reloc);
   1408           } else {
   1409             Relocation& reloc = helper_DynRel_init(rsym,
   1410                                                    *pReloc.targetRef().frag(),
   1411                                                    pReloc.targetRef().offset(),
   1412                                                    pReloc.type(),
   1413                                                    *this);
   1414             getRelRelMap().record(pReloc, reloc);
   1415           }
   1416           getTarget().checkAndSetHasTextRel(*pSection.getLink());
   1417         }
   1418       }
   1419       return;
   1420 
   1421     case llvm::ELF::R_X86_64_GOTPCREL:
   1422       // Symbol needs GOT entry, reserve entry in .got
   1423       // return if we already create GOT for this symbol
   1424       if (rsym->reserved() & ReserveGOT)
   1425         return;
   1426 
   1427       // if the symbol cannot be fully resolved at link time, then we need a
   1428       // dynamic relocation
   1429       if (!getTarget().symbolFinalValueIsKnown(*rsym))
   1430         helper_GOT_init(pReloc, true, *this);
   1431       else
   1432         helper_GOT_init(pReloc, false, *this);
   1433       // set GOT bit
   1434       rsym->setReserved(rsym->reserved() | ReserveGOT);
   1435       return;
   1436 
   1437     case llvm::ELF::R_X86_64_PLT32:
   1438       // A PLT entry is needed when building shared library
   1439 
   1440       // return if we already create plt for this symbol
   1441       if (rsym->reserved() & ReservePLT)
   1442         return;
   1443 
   1444       // if the symbol's value can be decided at link time, then no need plt
   1445       if (getTarget().symbolFinalValueIsKnown(*rsym))
   1446         return;
   1447 
   1448       // if symbol is defined in the ouput file and it's not
   1449       // preemptible, no need plt
   1450       if (rsym->isDefine() && !rsym->isDyn() &&
   1451           !getTarget().isSymbolPreemptible(*rsym)) {
   1452         return;
   1453       }
   1454 
   1455       // Symbol needs PLT entry, we need a PLT entry
   1456       // and the corresponding GOT and dynamic relocation entry
   1457       // in .got and .rel.plt.
   1458       helper_PLT_init(pReloc, *this);
   1459       // set PLT bit
   1460       rsym->setReserved(rsym->reserved() | ReservePLT);
   1461       return;
   1462 
   1463     case llvm::ELF::R_X86_64_PC32:
   1464     case llvm::ELF::R_X86_64_PC16:
   1465     case llvm::ELF::R_X86_64_PC8:
   1466       if (getTarget().symbolNeedsPLT(*rsym) &&
   1467           LinkerConfig::DynObj != config().codeGenType()) {
   1468         // create plt for this symbol if it does not have one
   1469         if (!(rsym->reserved() & ReservePLT)) {
   1470           // Symbol needs PLT entry, we need a PLT entry
   1471           // and the corresponding GOT and dynamic relocation entry
   1472           // in .got and .rel.plt.
   1473           helper_PLT_init(pReloc, *this);
   1474           // set PLT bit
   1475           rsym->setReserved(rsym->reserved() | ReservePLT);
   1476         }
   1477       }
   1478 
   1479       // Only PC relative relocation against dynamic symbol needs a
   1480       // dynamic relocation.  Only dynamic copy relocation is allowed
   1481       // and PC relative relocation will be resolved to the local copy.
   1482       // All other dynamic relocations may lead to run-time relocation
   1483       // overflow.
   1484       if (getTarget().isDynamicSymbol(*rsym) &&
   1485           getTarget()
   1486               .symbolNeedsDynRel(
   1487                   *rsym, (rsym->reserved() & ReservePLT), false) &&
   1488           getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) {
   1489         LDSymbol& cpy_sym =
   1490             defineSymbolforCopyReloc(pBuilder, *rsym, getTarget());
   1491         addCopyReloc(*cpy_sym.resolveInfo(), getTarget());
   1492       }
   1493       return;
   1494 
   1495     default:
   1496       fatal(diag::unsupported_relocation) << static_cast<int>(pReloc.type())
   1497                                           << "mclinker (at) googlegroups.com";
   1498       break;
   1499   }  // end switch
   1500 }
   1501 
   1502 uint32_t X86_64Relocator::getDebugStringOffset(Relocation& pReloc) const {
   1503   if (pReloc.type() != llvm::ELF::R_X86_64_32)
   1504     error(diag::unsupport_reloc_for_debug_string)
   1505         << getName(pReloc.type()) << "mclinker (at) googlegroups.com";
   1506 
   1507   if (pReloc.symInfo()->type() == ResolveInfo::Section)
   1508     return pReloc.target() + pReloc.addend();
   1509   else
   1510     return pReloc.symInfo()->outSymbol()->fragRef()->offset() +
   1511                pReloc.target() + pReloc.addend();
   1512 }
   1513 
   1514 void X86_64Relocator::applyDebugStringOffset(Relocation& pReloc,
   1515                                              uint32_t pOffset) {
   1516   pReloc.target() = pOffset;
   1517 }
   1518 
   1519 //------------------------------------------------//
   1520 // X86_64 Each relocation function implementation //
   1521 //------------------------------------------------//
   1522 // R_X86_64_NONE
   1523 Relocator::Result none(Relocation& pReloc, X86_64Relocator& pParent) {
   1524   return Relocator::OK;
   1525 }
   1526 
   1527 // R_X86_64_64: S + A
   1528 // R_X86_64_32:
   1529 // R_X86_64_16:
   1530 // R_X86_64_8
   1531 Relocator::Result abs(Relocation& pReloc, X86_64Relocator& pParent) {
   1532   ResolveInfo* rsym = pReloc.symInfo();
   1533   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1534   Relocator::DWord S = pReloc.symValue();
   1535   Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc);
   1536   bool has_dyn_rel = (dyn_rel != NULL);
   1537 
   1538   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   1539   // If the flag of target section is not ALLOC, we will not scan this
   1540   // relocation but perform static relocation. (e.g., applying .debug section)
   1541   if ((llvm::ELF::SHF_ALLOC & target_sect.flag()) == 0x0) {
   1542     pReloc.target() = S + A;
   1543     return Relocator::OK;
   1544   }
   1545 
   1546   // A local symbol may need RELA Type dynamic relocation
   1547   if (rsym->isLocal() && has_dyn_rel) {
   1548     dyn_rel->setAddend(S + A);
   1549     return Relocator::OK;
   1550   }
   1551 
   1552   // An external symbol may need PLT and dynamic relocation
   1553   if (!rsym->isLocal()) {
   1554     if (rsym->reserved() & X86Relocator::ReservePLT) {
   1555       S = helper_get_PLT_address(*rsym, pParent);
   1556     }
   1557     // If we generate a dynamic relocation (except R_X86_64_RELATIVE)
   1558     // for a place, we should not perform static relocation on it
   1559     // in order to keep the addend store in the place correct.
   1560     if (has_dyn_rel) {
   1561       if (llvm::ELF::R_X86_64_64 == pReloc.type() &&
   1562           helper_use_relative_reloc(*rsym, pParent)) {
   1563         dyn_rel->setAddend(S + A);
   1564       } else {
   1565         dyn_rel->setAddend(A);
   1566         return Relocator::OK;
   1567       }
   1568     }
   1569   }
   1570 
   1571   // perform static relocation
   1572   pReloc.target() = S + A;
   1573   return Relocator::OK;
   1574 }
   1575 
   1576 // R_X86_64_32S: S + A
   1577 Relocator::Result signed32(Relocation& pReloc, X86_64Relocator& pParent) {
   1578   ResolveInfo* rsym = pReloc.symInfo();
   1579   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1580   Relocator::DWord S = pReloc.symValue();
   1581 
   1582   // There should be no dynamic relocations for R_X86_64_32S.
   1583   if (pParent.getRelRelMap().lookUp(pReloc) != NULL)
   1584     return Relocator::BadReloc;
   1585 
   1586   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   1587   // If the flag of target section is not ALLOC, we will not scan this
   1588   // relocation but perform static relocation. (e.g., applying .debug section)
   1589   // An external symbol may need PLT and dynamic relocation
   1590   if ((llvm::ELF::SHF_ALLOC & target_sect.flag()) != 0x0 && !rsym->isLocal() &&
   1591       rsym->reserved() & X86Relocator::ReservePLT)
   1592     S = helper_get_PLT_address(*rsym, pParent);
   1593 
   1594 #if notyet
   1595   // Check 32-bit signed overflow.
   1596   Relocator::SWord V = S + A;
   1597   if (V > INT64_C(0x7fffffff) || V < INT64_C(-0x80000000))
   1598     return Relocator::Overflow;
   1599 #endif
   1600 
   1601   // perform static relocation
   1602   pReloc.target() = S + A;
   1603   return Relocator::OK;
   1604 }
   1605 
   1606 // R_X86_64_GOTPCREL: GOT(S) + GOT_ORG + A - P
   1607 Relocator::Result gotpcrel(Relocation& pReloc, X86_64Relocator& pParent) {
   1608   if (!(pReloc.symInfo()->reserved() & X86Relocator::ReserveGOT)) {
   1609     return Relocator::BadReloc;
   1610   }
   1611 
   1612   // set symbol value of the got entry if needed
   1613   X86_64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo());
   1614   if (X86Relocator::SymVal == got_entry->getValue())
   1615     got_entry->setValue(pReloc.symValue());
   1616 
   1617   // setup relocation addend if needed
   1618   Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc);
   1619   if ((dyn_rel != NULL) && (X86Relocator::SymVal == dyn_rel->addend())) {
   1620     dyn_rel->setAddend(pReloc.symValue());
   1621   }
   1622 
   1623   Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent);
   1624   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1625   Relocator::Address GOT_ORG = helper_GOT_ORG(pParent);
   1626   // Apply relocation.
   1627   pReloc.target() = GOT_S + GOT_ORG + A - pReloc.place();
   1628   return Relocator::OK;
   1629 }
   1630 
   1631 // R_X86_64_PLT32: PLT(S) + A - P
   1632 Relocator::Result plt32(Relocation& pReloc, X86_64Relocator& pParent) {
   1633   // PLT_S depends on if there is a PLT entry.
   1634   Relocator::Address PLT_S;
   1635   if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT))
   1636     PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent);
   1637   else
   1638     PLT_S = pReloc.symValue();
   1639   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1640   Relocator::Address P = pReloc.place();
   1641   pReloc.target() = PLT_S + A - P;
   1642   return Relocator::OK;
   1643 }
   1644 
   1645 // R_X86_64_PC32: S + A - P
   1646 // R_X86_64_PC16
   1647 // R_X86_64_PC8
   1648 Relocator::Result rel(Relocation& pReloc, X86_64Relocator& pParent) {
   1649   ResolveInfo* rsym = pReloc.symInfo();
   1650   Relocator::DWord A = pReloc.target() + pReloc.addend();
   1651   Relocator::DWord S = pReloc.symValue();
   1652   Relocator::DWord P = pReloc.place();
   1653 
   1654   LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection();
   1655   // If the flag of target section is not ALLOC, we will not scan this
   1656   // relocation but perform static relocation. (e.g., applying .debug section)
   1657   if ((llvm::ELF::SHF_ALLOC & target_sect.flag()) == 0x0) {
   1658     pReloc.target() = S + A - P;
   1659     return Relocator::OK;
   1660   }
   1661 
   1662   // setup relocation addend if needed
   1663   Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc);
   1664   if ((dyn_rel != NULL) && (X86Relocator::SymVal == dyn_rel->addend())) {
   1665     dyn_rel->setAddend(S);
   1666   }
   1667 
   1668   // An external symbol may need PLT and dynamic relocation
   1669   if (!rsym->isLocal()) {
   1670     if (rsym->reserved() & X86Relocator::ReservePLT) {
   1671       S = helper_get_PLT_address(*rsym, pParent);
   1672     }
   1673     if (pParent.getTarget()
   1674             .symbolNeedsDynRel(
   1675                 *rsym, (rsym->reserved() & X86Relocator::ReservePLT), false)) {
   1676       return Relocator::Overflow;
   1677     }
   1678   }
   1679 
   1680   // perform static relocation
   1681   pReloc.target() = S + A - P;
   1682   return Relocator::OK;
   1683 }
   1684 
   1685 Relocator::Result unsupported(Relocation& pReloc, X86_64Relocator& pParent) {
   1686   return Relocator::Unsupported;
   1687 }
   1688 
   1689 }  // namespace mcld
   1690