Home | History | Annotate | Download | only in X86
      1 //===- X86LDBackend.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 "X86.h"
     10 #include "X86ELFDynamic.h"
     11 #include "X86LDBackend.h"
     12 #include "X86Relocator.h"
     13 #include "X86GNUInfo.h"
     14 
     15 #include <llvm/ADT/Triple.h>
     16 #include <llvm/Support/Casting.h>
     17 
     18 #include <mcld/LinkerConfig.h>
     19 #include <mcld/IRBuilder.h>
     20 #include <mcld/Fragment/FillFragment.h>
     21 #include <mcld/Fragment/RegionFragment.h>
     22 #include <mcld/Fragment/FragmentLinker.h>
     23 #include <mcld/Support/MemoryRegion.h>
     24 #include <mcld/Support/MsgHandling.h>
     25 #include <mcld/Support/TargetRegistry.h>
     26 #include <mcld/Object/ObjectBuilder.h>
     27 
     28 #include <cstring>
     29 
     30 using namespace mcld;
     31 
     32 //===----------------------------------------------------------------------===//
     33 // X86GNULDBackend
     34 //===----------------------------------------------------------------------===//
     35 X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig,
     36 				 GNUInfo* pInfo,
     37 				 Relocation::Type pCopyRel)
     38   : GNULDBackend(pConfig, pInfo),
     39     m_pRelocator(NULL),
     40     m_pPLT(NULL),
     41     m_pRelDyn(NULL),
     42     m_pRelPLT(NULL),
     43     m_pDynamic(NULL),
     44     m_pGOTSymbol(NULL),
     45     m_CopyRel(pCopyRel)
     46 {
     47   Triple::ArchType arch = pConfig.targets().triple().getArch();
     48   assert (arch == Triple::x86 || arch == Triple::x86_64);
     49   if (arch == Triple::x86 ||
     50       pConfig.targets().triple().getEnvironment() == Triple::GNUX32) {
     51     m_RelEntrySize = 8;
     52     m_RelaEntrySize = 12;
     53     if (arch == Triple::x86)
     54       m_PointerRel = llvm::ELF::R_386_32;
     55     else
     56       m_PointerRel = llvm::ELF::R_X86_64_32;
     57   }
     58   else {
     59     m_RelEntrySize = 16;
     60     m_RelaEntrySize = 24;
     61     m_PointerRel = llvm::ELF::R_X86_64_64;
     62   }
     63 }
     64 
     65 X86GNULDBackend::~X86GNULDBackend()
     66 {
     67   delete m_pRelocator;
     68   delete m_pPLT;
     69   delete m_pRelDyn;
     70   delete m_pRelPLT;
     71   delete m_pDynamic;
     72 }
     73 
     74 Relocator* X86GNULDBackend::getRelocator()
     75 {
     76   assert(NULL != m_pRelocator);
     77   return m_pRelocator;
     78 }
     79 
     80 void X86GNULDBackend::doPreLayout(IRBuilder& pBuilder)
     81 {
     82   // initialize .dynamic data
     83   if (!config().isCodeStatic() && NULL == m_pDynamic)
     84     m_pDynamic = new X86ELFDynamic(*this, config());
     85 
     86   // set .got.plt and .got sizes
     87   // when building shared object, the .got section is must
     88   if (LinkerConfig::Object != config().codeGenType()) {
     89     setGOTSectionSize(pBuilder);
     90 
     91     // set .plt size
     92     if (m_pPLT->hasPLT1())
     93       m_pPLT->finalizeSectionSize();
     94 
     95     // set .rel.dyn/.rela.dyn size
     96     if (!m_pRelDyn->empty()) {
     97       assert(!config().isCodeStatic() &&
     98             "static linkage should not result in a dynamic relocation section");
     99       setRelDynSize();
    100     }
    101     // set .rel.plt/.rela.plt size
    102     if (!m_pRelPLT->empty()) {
    103       assert(!config().isCodeStatic() &&
    104             "static linkage should not result in a dynamic relocation section");
    105       setRelPLTSize();
    106     }
    107   }
    108 }
    109 
    110 void X86GNULDBackend::doPostLayout(Module& pModule,
    111                                    IRBuilder& pBuilder)
    112 {
    113 }
    114 
    115 /// dynamic - the dynamic section of the target machine.
    116 /// Use co-variant return type to return its own dynamic section.
    117 X86ELFDynamic& X86GNULDBackend::dynamic()
    118 {
    119   assert(NULL != m_pDynamic);
    120   return *m_pDynamic;
    121 }
    122 
    123 /// dynamic - the dynamic section of the target machine.
    124 /// Use co-variant return type to return its own dynamic section.
    125 const X86ELFDynamic& X86GNULDBackend::dynamic() const
    126 {
    127   assert(NULL != m_pDynamic);
    128   return *m_pDynamic;
    129 }
    130 
    131 void X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder,
    132 				      Fragment& pFrag)
    133 {
    134   // define symbol _GLOBAL_OFFSET_TABLE_
    135   if (m_pGOTSymbol != NULL) {
    136     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
    137                      "_GLOBAL_OFFSET_TABLE_",
    138                      ResolveInfo::Object,
    139                      ResolveInfo::Define,
    140                      ResolveInfo::Local,
    141                      0x0, // size
    142                      0x0, // value
    143                      FragmentRef::Create(pFrag, 0x0),
    144                      ResolveInfo::Hidden);
    145   }
    146   else {
    147     m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    148                      "_GLOBAL_OFFSET_TABLE_",
    149                      ResolveInfo::Object,
    150                      ResolveInfo::Define,
    151                      ResolveInfo::Local,
    152                      0x0, // size
    153                      0x0, // value
    154                      FragmentRef::Create(pFrag, 0x0),
    155                      ResolveInfo::Hidden);
    156   }
    157 }
    158 
    159 void X86GNULDBackend::addCopyReloc(ResolveInfo& pSym)
    160 {
    161   Relocation& rel_entry = *m_pRelDyn->consumeEntry();
    162   rel_entry.setType(m_CopyRel);
    163   assert(pSym.outSymbol()->hasFragRef());
    164   rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
    165   rel_entry.setSymInfo(&pSym);
    166 }
    167 
    168 /// defineSymbolforCopyReloc
    169 /// For a symbol needing copy relocation, define a copy symbol in the BSS
    170 /// section and all other reference to this symbol should refer to this
    171 /// copy.
    172 /// @note This is executed at `scan relocation' stage.
    173 LDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(IRBuilder& pBuilder,
    174                                                     const ResolveInfo& pSym)
    175 {
    176   // get or create corresponding BSS LDSection
    177   LDSection* bss_sect_hdr = NULL;
    178   ELFFileFormat* file_format = getOutputFormat();
    179   if (ResolveInfo::ThreadLocal == pSym.type())
    180     bss_sect_hdr = &file_format->getTBSS();
    181   else
    182     bss_sect_hdr = &file_format->getBSS();
    183 
    184   // get or create corresponding BSS SectionData
    185   assert(NULL != bss_sect_hdr);
    186   SectionData* bss_section = NULL;
    187   if (bss_sect_hdr->hasSectionData())
    188     bss_section = bss_sect_hdr->getSectionData();
    189   else
    190     bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr);
    191 
    192   // Determine the alignment by the symbol value
    193   // FIXME: here we use the largest alignment
    194   uint32_t addralign = config().targets().bitclass() / 8;
    195 
    196   // allocate space in BSS for the copy symbol
    197   Fragment* frag = new FillFragment(0x0, 1, pSym.size());
    198   uint64_t size = ObjectBuilder::AppendFragment(*frag,
    199                                                 *bss_section,
    200                                                 addralign);
    201   bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
    202 
    203   // change symbol binding to Global if it's a weak symbol
    204   ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
    205   if (binding == ResolveInfo::Weak)
    206     binding = ResolveInfo::Global;
    207 
    208   // Define the copy symbol in the bss section and resolve it
    209   LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    210                       pSym.name(),
    211                       (ResolveInfo::Type)pSym.type(),
    212                       ResolveInfo::Define,
    213                       binding,
    214                       pSym.size(),  // size
    215                       0x0,          // value
    216                       FragmentRef::Create(*frag, 0x0),
    217                       (ResolveInfo::Visibility)pSym.other());
    218 
    219   return *cpy_sym;
    220 }
    221 
    222 void X86GNULDBackend::scanRelocation(Relocation& pReloc,
    223                                      IRBuilder& pLinker,
    224                                      Module& pModule,
    225                                      LDSection& pSection)
    226 {
    227   if (LinkerConfig::Object == config().codeGenType())
    228     return;
    229   // rsym - The relocation target symbol
    230   ResolveInfo* rsym = pReloc.symInfo();
    231   assert(NULL != rsym &&
    232          "ResolveInfo of relocation not set while scanRelocation");
    233 
    234   pReloc.updateAddend();
    235   assert(NULL != pSection.getLink());
    236   if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
    237     return;
    238 
    239   // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation
    240   // entries should be created.
    241   if (rsym->isLocal()) // rsym is local
    242     scanLocalReloc(pReloc, pLinker, pModule, pSection);
    243   else // rsym is external
    244     scanGlobalReloc(pReloc, pLinker, pModule, pSection);
    245 
    246   // check if we should issue undefined reference for the relocation target
    247   // symbol
    248   if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
    249     fatal(diag::undefined_reference) << rsym->name();
    250 }
    251 
    252 uint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection,
    253                                           MemoryRegion& pRegion) const
    254 {
    255   assert(pRegion.size() && "Size of MemoryRegion is zero!");
    256 
    257   const ELFFileFormat* FileFormat = getOutputFormat();
    258   assert(FileFormat &&
    259          "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
    260 
    261   unsigned int EntrySize = 0;
    262   uint64_t RegionSize = 0;
    263 
    264   if (&pSection == &(FileFormat->getPLT())) {
    265     assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
    266 
    267     unsigned char* buffer = pRegion.getBuffer();
    268 
    269     m_pPLT->applyPLT0();
    270     m_pPLT->applyPLT1();
    271     X86PLT::iterator it = m_pPLT->begin();
    272     unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
    273 
    274     memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
    275     RegionSize += plt0_size;
    276     ++it;
    277 
    278     PLTEntryBase* plt1 = 0;
    279     X86PLT::iterator ie = m_pPLT->end();
    280     while (it != ie) {
    281       plt1 = &(llvm::cast<PLTEntryBase>(*it));
    282       EntrySize = plt1->size();
    283       memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
    284       RegionSize += EntrySize;
    285       ++it;
    286     }
    287   }
    288 
    289   else if (&pSection == &(FileFormat->getGOT())) {
    290     RegionSize += emitGOTSectionData(pRegion);
    291   }
    292 
    293   else if (&pSection == &(FileFormat->getGOTPLT())) {
    294     RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
    295   }
    296 
    297   else {
    298     fatal(diag::unrecognized_output_sectoin)
    299             << pSection.name()
    300             << "mclinker (at) googlegroups.com";
    301   }
    302   return RegionSize;
    303 }
    304 
    305 X86PLT& X86GNULDBackend::getPLT()
    306 {
    307   assert(NULL != m_pPLT && "PLT section not exist");
    308   return *m_pPLT;
    309 }
    310 
    311 const X86PLT& X86GNULDBackend::getPLT() const
    312 {
    313   assert(NULL != m_pPLT && "PLT section not exist");
    314   return *m_pPLT;
    315 }
    316 
    317 OutputRelocSection& X86GNULDBackend::getRelDyn()
    318 {
    319   assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
    320   return *m_pRelDyn;
    321 }
    322 
    323 const OutputRelocSection& X86GNULDBackend::getRelDyn() const
    324 {
    325   assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist");
    326   return *m_pRelDyn;
    327 }
    328 
    329 OutputRelocSection& X86GNULDBackend::getRelPLT()
    330 {
    331   assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
    332   return *m_pRelPLT;
    333 }
    334 
    335 const OutputRelocSection& X86GNULDBackend::getRelPLT() const
    336 {
    337   assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist");
    338   return *m_pRelPLT;
    339 }
    340 
    341 unsigned int
    342 X86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
    343 {
    344   const ELFFileFormat* file_format = getOutputFormat();
    345 
    346   if (&pSectHdr == &file_format->getGOT()) {
    347     if (config().options().hasNow())
    348       return SHO_RELRO;
    349     return SHO_RELRO_LAST;
    350   }
    351 
    352   if (&pSectHdr == &file_format->getGOTPLT()) {
    353     if (config().options().hasNow())
    354       return SHO_RELRO;
    355     return SHO_NON_RELRO_FIRST;
    356   }
    357 
    358   if (&pSectHdr == &file_format->getPLT())
    359     return SHO_PLT;
    360 
    361   return SHO_UNDEFINED;
    362 }
    363 
    364 void X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
    365 {
    366   if (LinkerConfig::Object != config().codeGenType()) {
    367     // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
    368     // same name in input
    369     m_pGOTSymbol =
    370       pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    371                                                 "_GLOBAL_OFFSET_TABLE_",
    372                                                 ResolveInfo::Object,
    373                                                 ResolveInfo::Define,
    374                                                 ResolveInfo::Local,
    375                                                 0x0,  // size
    376                                                 0x0,  // value
    377                                                 FragmentRef::Null(), // FragRef
    378                                                 ResolveInfo::Hidden);
    379   }
    380 }
    381 
    382 /// finalizeSymbol - finalize the symbol value
    383 bool X86GNULDBackend::finalizeTargetSymbols()
    384 {
    385   return true;
    386 }
    387 
    388 /// doCreateProgramHdrs - backend can implement this function to create the
    389 /// target-dependent segments
    390 void X86GNULDBackend::doCreateProgramHdrs(Module& pModule)
    391 {
    392   // TODO
    393 }
    394 
    395 X86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig,
    396 				       GNUInfo* pInfo)
    397   : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY),
    398     m_pGOT (NULL),
    399     m_pGOTPLT (NULL) {
    400 }
    401 
    402 X86_32GNULDBackend::~X86_32GNULDBackend()
    403 {
    404   delete m_pGOT;
    405   delete m_pGOTPLT;
    406 }
    407 
    408 bool X86_32GNULDBackend::initRelocator()
    409 {
    410   if (NULL == m_pRelocator) {
    411     m_pRelocator = new X86_32Relocator(*this);
    412   }
    413   return true;
    414 }
    415 
    416 void X86_32GNULDBackend::scanLocalReloc(Relocation& pReloc,
    417 					IRBuilder& pBuilder,
    418 					Module& pModule,
    419 					LDSection& pSection)
    420 {
    421   // rsym - The relocation target symbol
    422   ResolveInfo* rsym = pReloc.symInfo();
    423 
    424   switch(pReloc.type()){
    425 
    426     case llvm::ELF::R_386_32:
    427     case llvm::ELF::R_386_16:
    428     case llvm::ELF::R_386_8:
    429       // If buiding PIC object (shared library or PIC executable),
    430       // a dynamic relocations with RELATIVE type to this location is needed.
    431       // Reserve an entry in .rel.dyn
    432       if (config().isCodeIndep()) {
    433         m_pRelDyn->reserveEntry();
    434         // set Rel bit
    435         rsym->setReserved(rsym->reserved() | ReserveRel);
    436         checkAndSetHasTextRel(*pSection.getLink());
    437       }
    438       return;
    439 
    440     case llvm::ELF::R_386_GOTOFF:
    441     case llvm::ELF::R_386_GOTPC:
    442       // FIXME: A GOT section is needed
    443       return;
    444 
    445     case llvm::ELF::R_386_GOT32:
    446       // Symbol needs GOT entry, reserve entry in .got
    447       // return if we already create GOT for this symbol
    448       if (rsym->reserved() & (ReserveGOT | GOTRel))
    449         return;
    450       // FIXME: check STT_GNU_IFUNC symbol
    451       m_pGOT->reserve();
    452 
    453       // If the GOT is used in statically linked binaries,
    454       // the GOT entry is enough and no relocation is needed.
    455       if (config().isCodeStatic()) {
    456         rsym->setReserved(rsym->reserved() | ReserveGOT);
    457         return;
    458       }
    459       // If building shared object or the symbol is undefined, a dynamic
    460       // relocation is needed to relocate this GOT entry. Reserve an
    461       // entry in .rel.dyn
    462       if (LinkerConfig::DynObj ==
    463                    config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
    464         m_pRelDyn->reserveEntry();
    465         // set GOTRel bit
    466         rsym->setReserved(rsym->reserved() | GOTRel);
    467         return;
    468       }
    469       // set GOT bit
    470       rsym->setReserved(rsym->reserved() | ReserveGOT);
    471       return;
    472 
    473     case llvm::ELF::R_386_PC32:
    474     case llvm::ELF::R_386_PC16:
    475     case llvm::ELF::R_386_PC8:
    476       return;
    477 
    478     case llvm::ELF::R_386_TLS_GD: {
    479       // FIXME: no linker optimization for TLS relocation
    480       if (rsym->reserved() & GOTRel)
    481         return;
    482       m_pGOT->reserve(2);
    483       // reserve an rel entry
    484       m_pRelDyn->reserveEntry();
    485       // set GOTRel bit
    486       rsym->setReserved(rsym->reserved() | GOTRel);
    487       // define the section symbol for .tdata or .tbss
    488       // the target symbol of the created dynamic relocation should be the
    489       // section symbol of the section which this symbol defined. so we
    490       // need to define that section symbol here
    491       ELFFileFormat* file_format = getOutputFormat();
    492       const LDSection* sym_sect =
    493                &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection();
    494       if (&file_format->getTData() == sym_sect) {
    495         if (NULL == f_pTDATA)
    496           f_pTDATA = pModule.getSectionSymbolSet().get(*sym_sect);
    497       }
    498       else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) {
    499         if (NULL == f_pTBSS)
    500           f_pTBSS = pModule.getSectionSymbolSet().get(*sym_sect);
    501       }
    502       else
    503         error(diag::invalid_tls) << rsym->name() << sym_sect->name();
    504       return;
    505     }
    506 
    507     case llvm::ELF::R_386_TLS_LDM:
    508       getTLSModuleID();
    509       return;
    510 
    511     case llvm::ELF::R_386_TLS_LDO_32:
    512       return;
    513 
    514     case llvm::ELF::R_386_TLS_IE:
    515       setHasStaticTLS();
    516       // if buildint shared object, a RELATIVE dynamic relocation is needed
    517       if (LinkerConfig::DynObj == config().codeGenType()) {
    518         m_pRelDyn->reserveEntry();
    519         rsym->setReserved(rsym->reserved() | ReserveRel);
    520         checkAndSetHasTextRel(*pSection.getLink());
    521       } else {
    522         // for local sym, we can convert ie to le if not building shared object
    523         convertTLSIEtoLE(pReloc, pSection);
    524         return;
    525       }
    526       if (rsym->reserved() & GOTRel)
    527         return;
    528       // reserve got and dyn relocation entries for tp-relative offset
    529       m_pGOT->reserve();
    530       m_pRelDyn->reserveEntry();
    531       // set GOTRel bit
    532       rsym->setReserved(rsym->reserved() | GOTRel);
    533       m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
    534       return;
    535 
    536     case llvm::ELF::R_386_TLS_GOTIE:
    537       setHasStaticTLS();
    538       if (rsym->reserved() & GOTRel)
    539         return;
    540       // reserve got and dyn relocation entries for tp-relative offset
    541       m_pGOT->reserve();
    542       m_pRelDyn->reserveEntry();
    543       // set GOTRel bit
    544       rsym->setReserved(rsym->reserved() | GOTRel);
    545       m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
    546       return;
    547 
    548     case llvm::ELF::R_386_TLS_LE:
    549     case llvm::ELF::R_386_TLS_LE_32:
    550       setHasStaticTLS();
    551       // if buildint shared object, a dynamic relocation is needed
    552       if (LinkerConfig::DynObj == config().codeGenType()) {
    553         m_pRelDyn->reserveEntry();
    554         rsym->setReserved(rsym->reserved() | ReserveRel);
    555         checkAndSetHasTextRel(*pSection.getLink());
    556         // the target symbol of the dynamic relocation is rsym, so we need to
    557         // emit it into .dynsym
    558         assert(NULL != rsym->outSymbol());
    559         m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol());
    560       }
    561       return;
    562 
    563     default:
    564       fatal(diag::unsupported_relocation) << (int)pReloc.type()
    565                                           << "mclinker (at) googlegroups.com";
    566       break;
    567   } // end switch
    568 }
    569 
    570 void X86_32GNULDBackend::scanGlobalReloc(Relocation& pReloc,
    571 					 IRBuilder& pBuilder,
    572 					 Module& pModule,
    573 					 LDSection& pSection)
    574 {
    575   // rsym - The relocation target symbol
    576   ResolveInfo* rsym = pReloc.symInfo();
    577 
    578   switch(pReloc.type()) {
    579     case llvm::ELF::R_386_32:
    580     case llvm::ELF::R_386_16:
    581     case llvm::ELF::R_386_8:
    582       // Absolute relocation type, symbol may needs PLT entry or
    583       // dynamic relocation entry
    584       if (symbolNeedsPLT(*rsym)) {
    585         // create plt for this symbol if it does not have one
    586         if (!(rsym->reserved() & ReservePLT)){
    587           // Symbol needs PLT entry, we need to reserve a PLT entry
    588           // and the corresponding GOT and dynamic relocation entry
    589           // in .got and .rel.plt. (GOT entry will be reserved simultaneously
    590           // when calling X86PLT->reserveEntry())
    591           m_pPLT->reserveEntry();
    592           m_pGOTPLT->reserve();
    593           m_pRelPLT->reserveEntry();
    594           // set PLT bit
    595           rsym->setReserved(rsym->reserved() | ReservePLT);
    596         }
    597       }
    598 
    599       if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
    600         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
    601         m_pRelDyn->reserveEntry();
    602         if (symbolNeedsCopyReloc(pReloc, *rsym)) {
    603           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
    604           addCopyReloc(*cpy_sym.resolveInfo());
    605         }
    606         else {
    607           // set Rel bit
    608           rsym->setReserved(rsym->reserved() | ReserveRel);
    609           checkAndSetHasTextRel(pSection);
    610         }
    611       }
    612       return;
    613 
    614     case llvm::ELF::R_386_GOTOFF:
    615     case llvm::ELF::R_386_GOTPC: {
    616       // FIXME: A GOT section is needed
    617       return;
    618     }
    619 
    620     case llvm::ELF::R_386_PLT32:
    621       // A PLT entry is needed when building shared library
    622 
    623       // return if we already create plt for this symbol
    624       if (rsym->reserved() & ReservePLT)
    625         return;
    626 
    627       // if the symbol's value can be decided at link time, then no need plt
    628       if (symbolFinalValueIsKnown(*rsym))
    629         return;
    630 
    631       // if symbol is defined in the ouput file and it's not
    632       // preemptible, no need plt
    633       if (rsym->isDefine() && !rsym->isDyn() &&
    634          !isSymbolPreemptible(*rsym)) {
    635         return;
    636       }
    637 
    638       // Symbol needs PLT entry, we need to reserve a PLT entry
    639       // and the corresponding GOT and dynamic relocation entry
    640       // in .got and .rel.plt. (GOT entry will be reserved simultaneously
    641       // when calling X86PLT->reserveEntry())
    642       m_pPLT->reserveEntry();
    643       m_pGOTPLT->reserve();
    644       m_pRelPLT->reserveEntry();
    645       // set PLT bit
    646       rsym->setReserved(rsym->reserved() | ReservePLT);
    647       return;
    648 
    649     case llvm::ELF::R_386_GOT32:
    650       // Symbol needs GOT entry, reserve entry in .got
    651       // return if we already create GOT for this symbol
    652       if (rsym->reserved() & (ReserveGOT | GOTRel))
    653         return;
    654       m_pGOT->reserve();
    655 
    656       // If the GOT is used in statically linked binaries,
    657       // the GOT entry is enough and no relocation is needed.
    658       if (config().isCodeStatic()) {
    659         rsym->setReserved(rsym->reserved() | ReserveGOT);
    660         return;
    661       }
    662       // If building shared object or the symbol is undefined, a dynamic
    663       // relocation is needed to relocate this GOT entry. Reserve an
    664       // entry in .rel.dyn
    665       if (LinkerConfig::DynObj ==
    666                    config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
    667         m_pRelDyn->reserveEntry();
    668         // set GOTRel bit
    669         rsym->setReserved(rsym->reserved() | GOTRel);
    670         return;
    671       }
    672       // set GOT bit
    673       rsym->setReserved(rsym->reserved() | ReserveGOT);
    674       return;
    675 
    676     case llvm::ELF::R_386_PC32:
    677     case llvm::ELF::R_386_PC16:
    678     case llvm::ELF::R_386_PC8:
    679 
    680       if (symbolNeedsPLT(*rsym) &&
    681           LinkerConfig::DynObj != config().codeGenType()) {
    682         // create plt for this symbol if it does not have one
    683         if (!(rsym->reserved() & ReservePLT)){
    684           // Symbol needs PLT entry, we need to reserve a PLT entry
    685           // and the corresponding GOT and dynamic relocation entry
    686           // in .got and .rel.plt. (GOT entry will be reserved simultaneously
    687           // when calling X86PLT->reserveEntry())
    688           m_pPLT->reserveEntry();
    689           m_pGOTPLT->reserve();
    690           m_pRelPLT->reserveEntry();
    691           // set PLT bit
    692           rsym->setReserved(rsym->reserved() | ReservePLT);
    693         }
    694       }
    695 
    696       if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false)) {
    697         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
    698         m_pRelDyn->reserveEntry();
    699         if (symbolNeedsCopyReloc(pReloc, *rsym)) {
    700           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
    701           addCopyReloc(*cpy_sym.resolveInfo());
    702         }
    703         else {
    704           // set Rel bit
    705           rsym->setReserved(rsym->reserved() | ReserveRel);
    706           checkAndSetHasTextRel(pSection);
    707         }
    708       }
    709       return;
    710 
    711     case llvm::ELF::R_386_TLS_GD: {
    712       // FIXME: no linker optimization for TLS relocation
    713       if (rsym->reserved() & GOTRel)
    714         return;
    715       // reserve two pairs of got entry and dynamic relocation
    716       m_pGOT->reserve(2);
    717       m_pRelDyn->reserveEntry(2);
    718       // set GOTRel bit
    719       rsym->setReserved(rsym->reserved() | GOTRel);
    720       return;
    721     }
    722 
    723     case llvm::ELF::R_386_TLS_LDM:
    724       getTLSModuleID();
    725       return;
    726 
    727     case llvm::ELF::R_386_TLS_LDO_32:
    728       return;
    729 
    730     case llvm::ELF::R_386_TLS_IE:
    731       setHasStaticTLS();
    732       // if buildint shared object, a RELATIVE dynamic relocation is needed
    733       if (LinkerConfig::DynObj == config().codeGenType()) {
    734         m_pRelDyn->reserveEntry();
    735         rsym->setReserved(rsym->reserved() | ReserveRel);
    736         checkAndSetHasTextRel(*pSection.getLink());
    737       } else {
    738         // for global sym, we can convert ie to le if its final value is known
    739         if (symbolFinalValueIsKnown(*rsym)) {
    740           convertTLSIEtoLE(pReloc, pSection);
    741           return;
    742         }
    743       }
    744       if (rsym->reserved() & GOTRel)
    745         return;
    746       // reserve got and dyn relocation entries for tp-relative offset
    747       m_pGOT->reserve();
    748       m_pRelDyn->reserveEntry();
    749       // set GOTRel bit
    750       rsym->setReserved(rsym->reserved() | GOTRel);
    751       return;
    752 
    753     case llvm::ELF::R_386_TLS_GOTIE:
    754       setHasStaticTLS();
    755       if (rsym->reserved() & GOTRel)
    756         return;
    757       // reserve got and dyn relocation entries for tp-relative offset
    758       m_pGOT->reserve();
    759       m_pRelDyn->reserveEntry();
    760       // set GOTRel bit
    761       rsym->setReserved(rsym->reserved() | GOTRel);
    762       return;
    763 
    764     case llvm::ELF::R_386_TLS_LE:
    765     case llvm::ELF::R_386_TLS_LE_32:
    766       setHasStaticTLS();
    767       // if buildint shared object, a dynamic relocation is needed
    768       if (LinkerConfig::DynObj == config().codeGenType()) {
    769         m_pRelDyn->reserveEntry();
    770         rsym->setReserved(rsym->reserved() | ReserveRel);
    771         checkAndSetHasTextRel(*pSection.getLink());
    772       }
    773       return;
    774 
    775     default: {
    776       fatal(diag::unsupported_relocation) << (int)pReloc.type()
    777                                           << "mclinker (at) googlegroups.com";
    778       break;
    779     }
    780   } // end switch
    781 }
    782 
    783 void X86_32GNULDBackend::initTargetSections(Module& pModule,
    784 					    ObjectBuilder& pBuilder)
    785 {
    786   if (LinkerConfig::Object != config().codeGenType()) {
    787     ELFFileFormat* file_format = getOutputFormat();
    788     // initialize .got
    789     LDSection& got = file_format->getGOT();
    790     m_pGOT = new X86_32GOT(got);
    791 
    792     // initialize .got.plt
    793     LDSection& gotplt = file_format->getGOTPLT();
    794     m_pGOTPLT = new X86_32GOTPLT(gotplt);
    795 
    796     // initialize .plt
    797     LDSection& plt = file_format->getPLT();
    798     m_pPLT = new X86_32PLT(plt,
    799 			   *m_pGOTPLT,
    800 			   config());
    801 
    802     // initialize .rel.plt
    803     LDSection& relplt = file_format->getRelPlt();
    804     relplt.setLink(&plt);
    805     m_pRelPLT = new OutputRelocSection(pModule, relplt);
    806 
    807     // initialize .rel.dyn
    808     LDSection& reldyn = file_format->getRelDyn();
    809     m_pRelDyn = new OutputRelocSection(pModule, reldyn);
    810 
    811   }
    812 }
    813 
    814 X86_32GOT& X86_32GNULDBackend::getGOT()
    815 {
    816   assert(NULL != m_pGOT);
    817   return *m_pGOT;
    818 }
    819 
    820 const X86_32GOT& X86_32GNULDBackend::getGOT() const
    821 {
    822   assert(NULL != m_pGOT);
    823   return *m_pGOT;
    824 }
    825 
    826 X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT()
    827 {
    828   assert(NULL != m_pGOTPLT);
    829   return *m_pGOTPLT;
    830 }
    831 
    832 const X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const
    833 {
    834   assert(NULL != m_pGOTPLT);
    835   return *m_pGOTPLT;
    836 }
    837 
    838 void X86_32GNULDBackend::setRelDynSize()
    839 {
    840   ELFFileFormat* file_format = getOutputFormat();
    841   file_format->getRelDyn().setSize
    842     (m_pRelDyn->numOfRelocs() * getRelEntrySize());
    843 }
    844 
    845 void X86_32GNULDBackend::setRelPLTSize()
    846 {
    847   ELFFileFormat* file_format = getOutputFormat();
    848   file_format->getRelPlt().setSize
    849     (m_pRelPLT->numOfRelocs() * getRelEntrySize());
    850 }
    851 
    852 void X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
    853 {
    854   // set .got.plt size
    855   if (LinkerConfig::DynObj == config().codeGenType() ||
    856       m_pGOTPLT->hasGOT1() ||
    857       NULL != m_pGOTSymbol) {
    858     m_pGOTPLT->finalizeSectionSize();
    859     defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
    860   }
    861 
    862   // set .got size
    863   if (!m_pGOT->empty())
    864     m_pGOT->finalizeSectionSize();
    865 }
    866 
    867 uint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
    868 {
    869   assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
    870 
    871   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
    872 
    873   X86_32GOTEntry* got = 0;
    874   unsigned int EntrySize = X86_32GOTEntry::EntrySize;
    875   uint64_t RegionSize = 0;
    876 
    877   for (X86_32GOT::iterator it = m_pGOT->begin(),
    878        ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
    879     got = &(llvm::cast<X86_32GOTEntry>((*it)));
    880     *buffer = static_cast<uint32_t>(got->getValue());
    881     RegionSize += EntrySize;
    882   }
    883 
    884   return RegionSize;
    885 }
    886 
    887 uint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
    888 						   const ELFFileFormat* FileFormat) const
    889 {
    890   assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
    891   m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
    892   m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
    893 
    894   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
    895 
    896   X86_32GOTEntry* got = 0;
    897   unsigned int EntrySize = X86_32GOTEntry::EntrySize;
    898   uint64_t RegionSize = 0;
    899 
    900   for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(),
    901        ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
    902     got = &(llvm::cast<X86_32GOTEntry>((*it)));
    903     *buffer = static_cast<uint32_t>(got->getValue());
    904     RegionSize += EntrySize;
    905   }
    906 
    907   return RegionSize;
    908 }
    909 
    910 /// convert R_386_TLS_IE to R_386_TLS_LE
    911 void X86_32GNULDBackend::convertTLSIEtoLE(Relocation& pReloc,
    912 					  LDSection& pSection)
    913 {
    914   assert(pReloc.type() == llvm::ELF::R_386_TLS_IE);
    915   assert(NULL != pReloc.targetRef().frag());
    916 
    917   // 1. create the fragment references and new relocs
    918   uint64_t off = pReloc.targetRef().offset();
    919   if (off >= 4)
    920     off -= 4;
    921   else
    922     off = 0;
    923 
    924   FragmentRef* fragref = FragmentRef::Create(*pReloc.targetRef().frag(), off);
    925   // TODO: add symbols for R_386_TLS_OPT relocs
    926   Relocation* reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT,
    927                                          *fragref,
    928                                          0x0);
    929 
    930   // 2. modify the opcodes to the appropriate ones
    931   uint8_t* op =  (reinterpret_cast<uint8_t*>(&reloc->target()));
    932   off = pReloc.targetRef().offset() - reloc->targetRef().offset() - 1;
    933   if (op[off] == 0xa1) {
    934     op[off] = 0xb8;
    935   } else {
    936     switch (op[off - 1]) {
    937       case 0x8b:
    938         assert((op[off] & 0xc7) == 0x05);
    939         op[off - 1] = 0xc7;
    940         op[off]     = 0xc0 | ((op[off] >> 3) & 7);
    941         break;
    942       case 0x03:
    943         assert((op[off] & 0xc7) == 0x05);
    944         op[off - 1] = 0x81;
    945         op[off]     = 0xc0 | ((op[off] >> 3) & 7);
    946         break;
    947       default:
    948         assert(0);
    949         break;
    950     }
    951   }
    952 
    953   // 3. insert the new relocs "BEFORE" the original reloc.
    954   pSection.getRelocData()->getRelocationList().insert(
    955     RelocData::iterator(pReloc), reloc);
    956 
    957   // 4. change the type of the original reloc
    958   pReloc.setType(llvm::ELF::R_386_TLS_LE);
    959 }
    960 
    961 // Create a GOT entry for the TLS module index
    962 X86_32GOTEntry& X86_32GNULDBackend::getTLSModuleID()
    963 {
    964   static X86_32GOTEntry* got_entry = NULL;
    965   if (NULL != got_entry)
    966     return *got_entry;
    967 
    968   // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
    969   m_pGOT->reserve(2);
    970   got_entry = m_pGOT->consume();
    971   m_pGOT->consume()->setValue(0x0);
    972 
    973   m_pRelDyn->reserveEntry();
    974   Relocation* rel_entry = m_pRelDyn->consumeEntry();
    975   rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32);
    976   rel_entry->targetRef().assign(*got_entry, 0x0);
    977   rel_entry->setSymInfo(NULL);
    978 
    979   return *got_entry;
    980 }
    981 
    982 X86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig,
    983 				       GNUInfo* pInfo)
    984   : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY),
    985     m_pGOT (NULL),
    986     m_pGOTPLT (NULL) {
    987 }
    988 
    989 X86_64GNULDBackend::~X86_64GNULDBackend()
    990 {
    991   delete m_pGOT;
    992   delete m_pGOTPLT;
    993 }
    994 
    995 bool X86_64GNULDBackend::initRelocator()
    996 {
    997   if (NULL == m_pRelocator) {
    998     m_pRelocator = new X86_64Relocator(*this);
    999   }
   1000   return true;
   1001 }
   1002 
   1003 X86_64GOT& X86_64GNULDBackend::getGOT()
   1004 {
   1005   assert(NULL != m_pGOT);
   1006   return *m_pGOT;
   1007 }
   1008 
   1009 const X86_64GOT& X86_64GNULDBackend::getGOT() const
   1010 {
   1011   assert(NULL != m_pGOT);
   1012   return *m_pGOT;
   1013 }
   1014 
   1015 X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT()
   1016 {
   1017   assert(NULL != m_pGOTPLT);
   1018   return *m_pGOTPLT;
   1019 }
   1020 
   1021 const X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const
   1022 {
   1023   assert(NULL != m_pGOTPLT);
   1024   return *m_pGOTPLT;
   1025 }
   1026 
   1027 void X86_64GNULDBackend::setRelDynSize()
   1028 {
   1029   ELFFileFormat* file_format = getOutputFormat();
   1030   file_format->getRelaDyn().setSize
   1031     (m_pRelDyn->numOfRelocs() * getRelaEntrySize());
   1032 }
   1033 
   1034 void X86_64GNULDBackend::setRelPLTSize()
   1035 {
   1036   ELFFileFormat* file_format = getOutputFormat();
   1037   file_format->getRelaPlt().setSize
   1038     (m_pRelPLT->numOfRelocs() * getRelaEntrySize());
   1039 }
   1040 
   1041 void X86_64GNULDBackend::scanLocalReloc(Relocation& pReloc,
   1042 					IRBuilder& pBuilder,
   1043 					Module& pModule,
   1044 					LDSection& pSection)
   1045 {
   1046   // rsym - The relocation target symbol
   1047   ResolveInfo* rsym = pReloc.symInfo();
   1048 
   1049   switch(pReloc.type()){
   1050     case llvm::ELF::R_X86_64_64:
   1051     case llvm::ELF::R_X86_64_32:
   1052     case llvm::ELF::R_X86_64_16:
   1053     case llvm::ELF::R_X86_64_8:
   1054     case llvm::ELF::R_X86_64_32S:
   1055       // If buiding PIC object (shared library or PIC executable),
   1056       // a dynamic relocations with RELATIVE type to this location is needed.
   1057       // Reserve an entry in .rela.dyn
   1058       if (config().isCodeIndep()) {
   1059         m_pRelDyn->reserveEntry();
   1060         // set Rel bit
   1061         rsym->setReserved(rsym->reserved() | ReserveRel);
   1062         checkAndSetHasTextRel(*pSection.getLink());
   1063       }
   1064       return;
   1065 
   1066     case llvm::ELF::R_X86_64_PC32:
   1067     case llvm::ELF::R_X86_64_PC16:
   1068     case llvm::ELF::R_X86_64_PC8:
   1069       return;
   1070 
   1071     case llvm::ELF::R_X86_64_GOTPCREL:
   1072       // Symbol needs GOT entry, reserve entry in .got
   1073       // return if we already create GOT for this symbol
   1074       if (rsym->reserved() & (ReserveGOT | GOTRel))
   1075         return;
   1076       m_pGOT->reserve();
   1077 
   1078       // If the GOT is used in statically linked binaries,
   1079       // the GOT entry is enough and no relocation is needed.
   1080       if (config().isCodeStatic()) {
   1081         rsym->setReserved(rsym->reserved() | ReserveGOT);
   1082         return;
   1083       }
   1084       // If building shared object or the symbol is undefined, a dynamic
   1085       // relocation is needed to relocate this GOT entry. Reserve an
   1086       // entry in .rela.dyn
   1087       if (LinkerConfig::DynObj ==
   1088                    config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
   1089         m_pRelDyn->reserveEntry();
   1090         // set GOTRel bit
   1091         rsym->setReserved(rsym->reserved() | GOTRel);
   1092         return;
   1093       }
   1094       // set GOT bit
   1095       rsym->setReserved(rsym->reserved() | ReserveGOT);
   1096       return;
   1097 
   1098     default:
   1099       fatal(diag::unsupported_relocation) << (int)pReloc.type()
   1100                                           << "mclinker (at) googlegroups.com";
   1101       break;
   1102   } // end switch
   1103 }
   1104 
   1105 void X86_64GNULDBackend::scanGlobalReloc(Relocation& pReloc,
   1106 					 IRBuilder& pBuilder,
   1107 					 Module& pModule,
   1108 					 LDSection& pSection)
   1109 {
   1110   // rsym - The relocation target symbol
   1111   ResolveInfo* rsym = pReloc.symInfo();
   1112 
   1113   switch(pReloc.type()) {
   1114     case llvm::ELF::R_X86_64_64:
   1115     case llvm::ELF::R_X86_64_32:
   1116     case llvm::ELF::R_X86_64_16:
   1117     case llvm::ELF::R_X86_64_8:
   1118     case llvm::ELF::R_X86_64_32S:
   1119       // Absolute relocation type, symbol may needs PLT entry or
   1120       // dynamic relocation entry
   1121       if (symbolNeedsPLT(*rsym)) {
   1122         // create plt for this symbol if it does not have one
   1123         if (!(rsym->reserved() & ReservePLT)){
   1124           // Symbol needs PLT entry, we need to reserve a PLT entry
   1125           // and the corresponding GOT and dynamic relocation entry
   1126           // in .got and .rela.plt. (GOT entry will be reserved simultaneously
   1127           // when calling X86PLT->reserveEntry())
   1128           m_pPLT->reserveEntry();
   1129           m_pGOTPLT->reserve();
   1130           m_pRelPLT->reserveEntry();
   1131           // set PLT bit
   1132           rsym->setReserved(rsym->reserved() | ReservePLT);
   1133         }
   1134       }
   1135 
   1136       if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
   1137         // symbol needs dynamic relocation entry, reserve an entry in .rela.dyn
   1138         m_pRelDyn->reserveEntry();
   1139         if (symbolNeedsCopyReloc(pReloc, *rsym)) {
   1140           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
   1141           addCopyReloc(*cpy_sym.resolveInfo());
   1142         }
   1143         else {
   1144           // set Rel bit
   1145           rsym->setReserved(rsym->reserved() | ReserveRel);
   1146 	  checkAndSetHasTextRel(*pSection.getLink());
   1147         }
   1148       }
   1149       return;
   1150 
   1151     case llvm::ELF::R_X86_64_GOTPCREL:
   1152       // Symbol needs GOT entry, reserve entry in .got
   1153       // return if we already create GOT for this symbol
   1154       if (rsym->reserved() & (ReserveGOT | GOTRel))
   1155         return;
   1156       m_pGOT->reserve();
   1157 
   1158       // If the GOT is used in statically linked binaries,
   1159       // the GOT entry is enough and no relocation is needed.
   1160       if (config().isCodeStatic()) {
   1161         rsym->setReserved(rsym->reserved() | ReserveGOT);
   1162         return;
   1163       }
   1164       // If building shared object or the symbol is undefined, a dynamic
   1165       // relocation is needed to relocate this GOT entry. Reserve an
   1166       // entry in .rela.dyn
   1167       if (LinkerConfig::DynObj ==
   1168                    config().codeGenType() || rsym->isUndef() || rsym->isDyn()) {
   1169         m_pRelDyn->reserveEntry();
   1170         // set GOTRel bit
   1171         rsym->setReserved(rsym->reserved() | GOTRel);
   1172         return;
   1173       }
   1174       // set GOT bit
   1175       rsym->setReserved(rsym->reserved() | ReserveGOT);
   1176       return;
   1177 
   1178     case llvm::ELF::R_X86_64_PLT32:
   1179       // A PLT entry is needed when building shared library
   1180 
   1181       // return if we already create plt for this symbol
   1182       if (rsym->reserved() & ReservePLT)
   1183         return;
   1184 
   1185       // if the symbol's value can be decided at link time, then no need plt
   1186       if (symbolFinalValueIsKnown(*rsym))
   1187         return;
   1188 
   1189       // if symbol is defined in the ouput file and it's not
   1190       // preemptible, no need plt
   1191       if (rsym->isDefine() && !rsym->isDyn() &&
   1192          !isSymbolPreemptible(*rsym)) {
   1193         return;
   1194       }
   1195 
   1196       // Symbol needs PLT entry, we need to reserve a PLT entry
   1197       // and the corresponding GOT and dynamic relocation entry
   1198       // in .got and .rel.plt. (GOT entry will be reserved simultaneously
   1199       // when calling X86PLT->reserveEntry())
   1200       m_pPLT->reserveEntry();
   1201       m_pGOTPLT->reserve();
   1202       m_pRelPLT->reserveEntry();
   1203       // set PLT bit
   1204       rsym->setReserved(rsym->reserved() | ReservePLT);
   1205       return;
   1206 
   1207     case llvm::ELF::R_X86_64_PC32:
   1208     case llvm::ELF::R_X86_64_PC16:
   1209     case llvm::ELF::R_X86_64_PC8:
   1210       if (symbolNeedsPLT(*rsym) &&
   1211           LinkerConfig::DynObj != config().codeGenType()) {
   1212         // create plt for this symbol if it does not have one
   1213         if (!(rsym->reserved() & ReservePLT)){
   1214           // Symbol needs PLT entry, we need to reserve a PLT entry
   1215           // and the corresponding GOT and dynamic relocation entry
   1216           // in .got and .rel.plt. (GOT entry will be reserved simultaneously
   1217           // when calling X86PLT->reserveEntry())
   1218           m_pPLT->reserveEntry();
   1219           m_pGOTPLT->reserve();
   1220           m_pRelPLT->reserveEntry();
   1221           // set PLT bit
   1222           rsym->setReserved(rsym->reserved() | ReservePLT);
   1223         }
   1224       }
   1225 
   1226       // Only PC relative relocation against dynamic symbol needs a
   1227       // dynamic relocation.  Only dynamic copy relocation is allowed
   1228       // and PC relative relocation will be resolved to the local copy.
   1229       // All other dynamic relocations may lead to run-time relocation
   1230       // overflow.
   1231       if (isDynamicSymbol(*rsym) &&
   1232 	  symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false) &&
   1233 	  symbolNeedsCopyReloc(pReloc, *rsym)) {
   1234         m_pRelDyn->reserveEntry();
   1235 	LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
   1236 	addCopyReloc(*cpy_sym.resolveInfo());
   1237       }
   1238       return;
   1239 
   1240     default:
   1241       fatal(diag::unsupported_relocation) << (int)pReloc.type()
   1242                                           << "mclinker (at) googlegroups.com";
   1243       break;
   1244   } // end switch
   1245 }
   1246 
   1247 void X86_64GNULDBackend::initTargetSections(Module& pModule,
   1248 					    ObjectBuilder& pBuilder)
   1249 {
   1250   if (LinkerConfig::Object != config().codeGenType()) {
   1251     ELFFileFormat* file_format = getOutputFormat();
   1252     // initialize .got
   1253     LDSection& got = file_format->getGOT();
   1254     m_pGOT = new X86_64GOT(got);
   1255 
   1256     // initialize .got.plt
   1257     LDSection& gotplt = file_format->getGOTPLT();
   1258     m_pGOTPLT = new X86_64GOTPLT(gotplt);
   1259 
   1260     // initialize .plt
   1261     LDSection& plt = file_format->getPLT();
   1262     m_pPLT = new X86_64PLT(plt,
   1263 			   *m_pGOTPLT,
   1264 			   config());
   1265 
   1266     // initialize .rela.plt
   1267     LDSection& relplt = file_format->getRelaPlt();
   1268     relplt.setLink(&plt);
   1269     m_pRelPLT = new OutputRelocSection(pModule, relplt);
   1270 
   1271     // initialize .rela.dyn
   1272     LDSection& reldyn = file_format->getRelaDyn();
   1273     m_pRelDyn = new OutputRelocSection(pModule, reldyn);
   1274 
   1275   }
   1276 }
   1277 
   1278 void X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder)
   1279 {
   1280   // set .got.plt size
   1281   if (LinkerConfig::DynObj == config().codeGenType() ||
   1282       m_pGOTPLT->hasGOT1() ||
   1283       NULL != m_pGOTSymbol) {
   1284     m_pGOTPLT->finalizeSectionSize();
   1285     defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
   1286   }
   1287 
   1288   // set .got size
   1289   if (!m_pGOT->empty())
   1290     m_pGOT->finalizeSectionSize();
   1291 }
   1292 
   1293 uint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const
   1294 {
   1295   assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
   1296 
   1297   uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
   1298 
   1299   X86_64GOTEntry* got = 0;
   1300   unsigned int EntrySize = X86_64GOTEntry::EntrySize;
   1301   uint64_t RegionSize = 0;
   1302 
   1303   for (X86_64GOT::iterator it = m_pGOT->begin(),
   1304        ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
   1305     got = &(llvm::cast<X86_64GOTEntry>((*it)));
   1306     *buffer = static_cast<uint64_t>(got->getValue());
   1307     RegionSize += EntrySize;
   1308   }
   1309 
   1310   return RegionSize;
   1311 }
   1312 
   1313 uint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
   1314 						   const ELFFileFormat* FileFormat) const
   1315 {
   1316   assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
   1317   m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
   1318   m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
   1319 
   1320   uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer());
   1321 
   1322   X86_64GOTEntry* got = 0;
   1323   unsigned int EntrySize = X86_64GOTEntry::EntrySize;
   1324   uint64_t RegionSize = 0;
   1325 
   1326   for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(),
   1327        ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
   1328     got = &(llvm::cast<X86_64GOTEntry>((*it)));
   1329     *buffer = static_cast<uint64_t>(got->getValue());
   1330     RegionSize += EntrySize;
   1331   }
   1332 
   1333   return RegionSize;
   1334 }
   1335 
   1336 namespace mcld {
   1337 
   1338 //===----------------------------------------------------------------------===//
   1339 /// createX86LDBackend - the help funtion to create corresponding X86LDBackend
   1340 ///
   1341 TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
   1342                                     const LinkerConfig& pConfig)
   1343 {
   1344   if (pConfig.targets().triple().isOSDarwin()) {
   1345     assert(0 && "MachO linker is not supported yet");
   1346     /**
   1347     return new X86MachOLDBackend(createX86MachOArchiveReader,
   1348                                createX86MachOObjectReader,
   1349                                createX86MachOObjectWriter);
   1350     **/
   1351   }
   1352   if (pConfig.targets().triple().isOSWindows()) {
   1353     assert(0 && "COFF linker is not supported yet");
   1354     /**
   1355     return new X86COFFLDBackend(createX86COFFArchiveReader,
   1356                                createX86COFFObjectReader,
   1357                                createX86COFFObjectWriter);
   1358     **/
   1359   }
   1360   Triple::ArchType arch = pConfig.targets().triple().getArch();
   1361   if (arch == Triple::x86)
   1362     return new X86_32GNULDBackend(pConfig,
   1363 				  new X86_32GNUInfo(pConfig.targets().triple()));
   1364   assert (arch == Triple::x86_64);
   1365   return new X86_64GNULDBackend(pConfig,
   1366 				new X86_64GNUInfo(pConfig.targets().triple()));
   1367 }
   1368 
   1369 } // namespace of mcld
   1370 
   1371 //===----------------------------------------------------------------------===//
   1372 // Force static initialization.
   1373 //===----------------------------------------------------------------------===//
   1374 extern "C" void MCLDInitializeX86LDBackend() {
   1375   // Register the linker backend
   1376   mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend);
   1377   mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend);
   1378 }
   1379