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 
     10 #include "X86.h"
     11 #include "X86ELFDynamic.h"
     12 #include "X86LDBackend.h"
     13 #include "X86RelocationFactory.h"
     14 
     15 #include <llvm/ADT/Triple.h>
     16 #include <mcld/Support/MemoryRegion.h>
     17 #include <mcld/Support/TargetRegistry.h>
     18 #include <mcld/MC/MCLDInfo.h>
     19 #include <mcld/MC/MCLDOutput.h>
     20 #include <mcld/MC/MCLinker.h>
     21 #include <mcld/LD/SectionMap.h>
     22 #include <mcld/MC/MCRegionFragment.h>
     23 
     24 #include <cstring>
     25 
     26 using namespace mcld;
     27 
     28 X86GNULDBackend::X86GNULDBackend()
     29   : m_pRelocFactory(NULL),
     30     m_pGOT(NULL),
     31     m_pPLT(NULL),
     32     m_pRelDyn(NULL),
     33     m_pRelPLT(NULL),
     34     m_pDynamic(NULL) {
     35 }
     36 
     37 X86GNULDBackend::~X86GNULDBackend()
     38 {
     39   if (NULL != m_pRelocFactory)
     40     delete m_pRelocFactory;
     41   if (NULL != m_pGOT)
     42     delete m_pGOT;
     43   if (NULL != m_pPLT)
     44     delete m_pPLT;
     45   if (NULL !=m_pRelDyn)
     46     delete m_pRelDyn;
     47   if (NULL != m_pRelPLT)
     48     delete m_pRelPLT;
     49   if (NULL != m_pDynamic)
     50     delete m_pDynamic;
     51 }
     52 
     53 RelocationFactory* X86GNULDBackend::getRelocFactory()
     54 {
     55   assert(NULL != m_pRelocFactory);
     56   return m_pRelocFactory;
     57 }
     58 
     59 bool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker)
     60 {
     61   if (NULL == m_pRelocFactory) {
     62     m_pRelocFactory = new X86RelocationFactory(1024, *this);
     63     m_pRelocFactory->setLayout(pLinker.getLayout());
     64   }
     65   return true;
     66 }
     67 
     68 void X86GNULDBackend::doPreLayout(const Output& pOutput,
     69                                   const MCLDInfo& pInfo,
     70                                   MCLinker& pLinker)
     71 {
     72   // when building shared object, the .got section is needed
     73   if(pOutput.type() == Output::DynObj && (NULL == m_pGOT))
     74       createX86GOT(pLinker, pOutput);
     75 }
     76 
     77 void X86GNULDBackend::doPostLayout(const Output& pOutput,
     78                                    const MCLDInfo& pInfo,
     79                                    MCLinker& pLinker)
     80 {
     81   // emit program headers
     82   if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec)
     83     emitProgramHdrs(pLinker.getLDInfo().output());
     84 }
     85 
     86 /// dynamic - the dynamic section of the target machine.
     87 /// Use co-variant return type to return its own dynamic section.
     88 X86ELFDynamic& X86GNULDBackend::dynamic()
     89 {
     90   if (NULL == m_pDynamic)
     91     m_pDynamic = new X86ELFDynamic(*this);
     92 
     93   return *m_pDynamic;
     94 }
     95 
     96 /// dynamic - the dynamic section of the target machine.
     97 /// Use co-variant return type to return its own dynamic section.
     98 const X86ELFDynamic& X86GNULDBackend::dynamic() const
     99 {
    100   assert( NULL != m_pDynamic);
    101   return *m_pDynamic;
    102 }
    103 
    104 void X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput)
    105 {
    106   // get .got LDSection and create MCSectionData
    107   ELFFileFormat* file_format = getOutputFormat(pOutput);
    108 
    109   LDSection& got = file_format->getGOT();
    110   m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got));
    111 
    112   // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
    113   if( m_pGOTSymbol != NULL ) {
    114     pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
    115                      "_GLOBAL_OFFSET_TABLE_",
    116                      false,
    117                      ResolveInfo::Object,
    118                      ResolveInfo::Define,
    119                      ResolveInfo::Local,
    120                      0x0, // size
    121                      0x0, // value
    122                      pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
    123                      ResolveInfo::Hidden);
    124   }
    125   else {
    126     m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
    127                      "_GLOBAL_OFFSET_TABLE_",
    128                      false,
    129                      ResolveInfo::Object,
    130                      ResolveInfo::Define,
    131                      ResolveInfo::Local,
    132                      0x0, // size
    133                      0x0, // value
    134                      pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
    135                      ResolveInfo::Hidden);
    136   }
    137 }
    138 
    139 void X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker,
    140                                             const Output& pOutput)
    141 {
    142   ELFFileFormat* file_format = getOutputFormat(pOutput);
    143 
    144   LDSection& plt = file_format->getPLT();
    145   LDSection& relplt = file_format->getRelPlt();
    146   // create MCSectionData and X86PLT
    147   m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOT, pOutput);
    148 
    149   // set info of .rel.plt to .plt
    150   relplt.setLink(&plt);
    151   // create MCSectionData and X86RelDynSection
    152   m_pRelPLT = new OutputRelocSection(relplt,
    153                                      pLinker.getOrCreateSectData(relplt),
    154                                      8);
    155 }
    156 
    157 void X86GNULDBackend::createX86RelDyn(MCLinker& pLinker,
    158                                       const Output& pOutput)
    159 {
    160   // get .rel.dyn LDSection and create MCSectionData
    161   ELFFileFormat* file_format = getOutputFormat(pOutput);
    162 
    163   LDSection& reldyn = file_format->getRelDyn();
    164   // create MCSectionData and X86RelDynSection
    165   m_pRelDyn = new OutputRelocSection(reldyn,
    166                                      pLinker.getOrCreateSectData(reldyn),
    167                                      8);
    168 }
    169 
    170 ELFFileFormat* X86GNULDBackend::getOutputFormat(const Output& pOutput) const
    171 {
    172   switch (pOutput.type()) {
    173     case Output::DynObj:
    174       return getDynObjFileFormat();
    175     case Output::Exec:
    176       return getExecFileFormat();
    177     // FIXME: We do not support building .o now
    178     case Output::Object:
    179     default:
    180       llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") +
    181                                llvm::Twine(pOutput.type()));
    182       return NULL;
    183   }
    184 }
    185 
    186 bool X86GNULDBackend::isSymbolNeedsPLT(const ResolveInfo& pSym,
    187                                        const MCLDInfo& pLDInfo,
    188                                        const Output& pOutput) const
    189 {
    190   return((Output::DynObj == pOutput.type())
    191          &&(ResolveInfo::Function == pSym.type())
    192          &&(pSym.isDyn() || pSym.isUndef() ||
    193             isSymbolPreemptible(pSym, pLDInfo, pOutput))
    194         );
    195 }
    196 
    197 bool X86GNULDBackend::isSymbolNeedsDynRel(const ResolveInfo& pSym,
    198                                           const Output& pOutput,
    199                                           bool isAbsReloc) const
    200 {
    201   if(pSym.isUndef() && (pOutput.type()==Output::Exec))
    202     return false;
    203   if(pSym.isAbsolute())
    204     return false;
    205   if(pOutput.type()==Output::DynObj && isAbsReloc)
    206     return true;
    207   if(pSym.isDyn() || pSym.isUndef())
    208     return true;
    209 
    210   return false;
    211 }
    212 
    213 bool X86GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym,
    214                                          const MCLDInfo& pLDInfo,
    215                                          const Output& pOutput) const
    216 {
    217   if(pSym.other() != ResolveInfo::Default)
    218     return false;
    219 
    220   if(pOutput.type() != Output::DynObj)
    221     return false;
    222 
    223   if(pLDInfo.options().Bsymbolic())
    224     return false;
    225 
    226   return true;
    227 }
    228 
    229 void X86GNULDBackend::updateAddend(Relocation& pReloc,
    230                                    const LDSymbol& pInputSym,
    231                                    const Layout& pLayout) const
    232 {
    233   // Update value keep in addend if we meet a section symbol
    234   if(pReloc.symInfo()->type() == ResolveInfo::Section) {
    235     pReloc.setAddend(pLayout.getOutputOffset(
    236                      *pInputSym.fragRef()) + pReloc.addend());
    237   }
    238 }
    239 
    240 void X86GNULDBackend::scanLocalReloc(Relocation& pReloc,
    241                                      const LDSymbol& pInputSym,
    242                                      MCLinker& pLinker,
    243                                      const MCLDInfo& pLDInfo,
    244                                      const Output& pOutput)
    245 {
    246   // rsym - The relocation target symbol
    247   ResolveInfo* rsym = pReloc.symInfo();
    248 
    249   updateAddend(pReloc, pInputSym, pLinker.getLayout());
    250 
    251   switch(pReloc.type()){
    252 
    253     case llvm::ELF::R_386_32:
    254       // If buiding PIC object (shared library or PIC executable),
    255       // a dynamic relocations with RELATIVE type to this location is needed.
    256       // Reserve an entry in .rel.dyn
    257       if(Output::DynObj == pOutput.type()) {
    258         // create .rel.dyn section if not exist
    259         if(NULL == m_pRelDyn)
    260           createX86RelDyn(pLinker, pOutput);
    261         m_pRelDyn->reserveEntry(*m_pRelocFactory);
    262         // set Rel bit
    263         rsym->setReserved(rsym->reserved() | ReserveRel);
    264       }
    265       return;
    266 
    267     case llvm::ELF::R_386_GOTOFF:
    268     case llvm::ELF::R_386_GOTPC:
    269       // A GOT section is needed
    270       if(NULL == m_pGOT)
    271         createX86GOT(pLinker, pOutput);
    272       return;
    273 
    274     case llvm::ELF::R_386_PC32:
    275       return;
    276 
    277     default:
    278       llvm::report_fatal_error(llvm::Twine("unexpected reloc ") +
    279                                llvm::Twine((int) pReloc.type()) +
    280                                llvm::Twine(" in object file"));
    281       break;
    282   } // end switch
    283 }
    284 
    285 void X86GNULDBackend::scanGlobalReloc(Relocation& pReloc,
    286                                       const LDSymbol& pInputSym,
    287                                       MCLinker& pLinker,
    288                                       const MCLDInfo& pLDInfo,
    289                                       const Output& pOutput)
    290 {
    291   // rsym - The relocation target symbol
    292   ResolveInfo* rsym = pReloc.symInfo();
    293 
    294   switch(pReloc.type()) {
    295     case llvm::ELF::R_386_32:
    296       // Absolute relocation type, symbol may needs PLT entry or
    297       // dynamic relocation entry
    298       if(isSymbolNeedsPLT(*rsym, pLDInfo, pOutput)) {
    299         // create plt for this symbol if it does not have one
    300         if(!(rsym->reserved() & ReservePLT)){
    301           // Create .got section if it dosen't exist
    302           if(NULL == m_pGOT)
    303              createX86GOT(pLinker, pOutput);
    304           // create .plt and .rel.plt if not exist
    305           if(NULL == m_pPLT)
    306             createX86PLTandRelPLT(pLinker, pOutput);
    307           // Symbol needs PLT entry, we need to reserve a PLT entry
    308           // and the corresponding GOT and dynamic relocation entry
    309           // in .got and .rel.plt. (GOT entry will be reserved simultaneously
    310           // when calling X86PLT->reserveEntry())
    311           m_pPLT->reserveEntry();
    312           m_pRelPLT->reserveEntry(*m_pRelocFactory);
    313           // set PLT bit
    314           rsym->setReserved(rsym->reserved() | ReservePLT);
    315         }
    316       }
    317 
    318       if(isSymbolNeedsDynRel(*rsym, pOutput, true)) {
    319         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
    320         // create .rel.dyn section if not exist
    321         if(NULL == m_pRelDyn)
    322           createX86RelDyn(pLinker, pOutput);
    323         m_pRelDyn->reserveEntry(*m_pRelocFactory);
    324         // set Rel bit
    325         rsym->setReserved(rsym->reserved() | ReserveRel);
    326       }
    327       return;
    328 
    329     case llvm::ELF::R_386_GOTOFF:
    330     case llvm::ELF::R_386_GOTPC: {
    331       // A GOT section is needed
    332       if(NULL == m_pGOT)
    333         createX86GOT(pLinker, pOutput);
    334       return;
    335     }
    336 
    337     case llvm::ELF::R_386_PLT32:
    338       // A PLT entry is needed when building shared library
    339 
    340       // return if we already create plt for this symbol
    341       if(rsym->reserved() & ReservePLT)
    342         return;
    343 
    344       // if symbol is defined in the ouput file and it's not
    345       // preemptible, no need plt
    346       if(rsym->isDefine() && !rsym->isDyn() &&
    347          !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) {
    348         return;
    349       }
    350 
    351       // Create .got section if it dosen't exist
    352       if(NULL == m_pGOT)
    353          createX86GOT(pLinker, pOutput);
    354       // create .plt and .rel.plt if not exist
    355       if(NULL == m_pPLT)
    356          createX86PLTandRelPLT(pLinker, pOutput);
    357       // Symbol needs PLT entry, we need to reserve a PLT entry
    358       // and the corresponding GOT and dynamic relocation entry
    359       // in .got and .rel.plt. (GOT entry will be reserved simultaneously
    360       // when calling X86PLT->reserveEntry())
    361       m_pPLT->reserveEntry();
    362       m_pRelPLT->reserveEntry(*m_pRelocFactory);
    363       // set PLT bit
    364       rsym->setReserved(rsym->reserved() | ReservePLT);
    365       return;
    366 
    367     case llvm::ELF::R_386_GOT32:
    368       // Symbol needs GOT entry, reserve entry in .got
    369       // return if we already create GOT for this symbol
    370       if(rsym->reserved() & (ReserveGOT | GOTRel))
    371         return;
    372       if(NULL == m_pGOT)
    373         createX86GOT(pLinker, pOutput);
    374       m_pGOT->reserveEntry();
    375       // If building shared object or the symbol is undefined, a dynamic
    376       // relocation is needed to relocate this GOT entry. Reserve an
    377       // entry in .rel.dyn
    378       if(Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) {
    379         // create .rel.dyn section if not exist
    380         if(NULL == m_pRelDyn)
    381           createX86RelDyn(pLinker, pOutput);
    382         m_pRelDyn->reserveEntry(*m_pRelocFactory);
    383         // set GOTRel bit
    384         rsym->setReserved(rsym->reserved() | GOTRel);
    385         return;
    386       }
    387       // set GOT bit
    388       rsym->setReserved(rsym->reserved() | ReserveGOT);
    389       return;
    390 
    391     case llvm::ELF::R_386_PC32:
    392       // We allow R_386_PC32 only if it isn't preemptible.  Otherwise
    393       // we will generate writable text section in output.
    394       if (!isSymbolPreemptible(*rsym, pLDInfo, pOutput))
    395 	return;
    396 
    397     default: {
    398       llvm::report_fatal_error(llvm::Twine("Unexpected reloc ") +
    399                                llvm::Twine((int) pReloc.type()) +
    400                                llvm::Twine(" in object file"));
    401       break;
    402     }
    403   } // end switch
    404 }
    405 
    406 void X86GNULDBackend::scanRelocation(Relocation& pReloc,
    407                                      const LDSymbol& pInputSym,
    408                                      MCLinker& pLinker,
    409                                      const MCLDInfo& pLDInfo,
    410                                      const Output& pOutput)
    411 {
    412   // rsym - The relocation target symbol
    413   ResolveInfo* rsym = pReloc.symInfo();
    414   assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
    415 
    416   // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
    417   // entries should be created.
    418   // FIXME: Below judgements concern only .so is generated as output
    419   // FIXME: Below judgements concren nothing about TLS related relocation
    420 
    421   // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got section
    422   // is needed
    423   if(NULL == m_pGOT && NULL != m_pGOTSymbol) {
    424     if(rsym == m_pGOTSymbol->resolveInfo()) {
    425       createX86GOT(pLinker, pOutput);
    426     }
    427   }
    428 
    429   // rsym is local
    430   if(rsym->isLocal())
    431     scanLocalReloc(pReloc, pInputSym,  pLinker, pLDInfo, pOutput);
    432 
    433   // rsym is external
    434   else
    435     scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput);
    436 
    437 }
    438 
    439 uint64_t X86GNULDBackend::emitSectionData(const Output& pOutput,
    440                                           const LDSection& pSection,
    441                                           const MCLDInfo& pInfo,
    442                                           MemoryRegion& pRegion) const
    443 {
    444   assert(pRegion.size() && "Size of MemoryRegion is zero!");
    445 
    446   ELFFileFormat* FileFormat = getOutputFormat(pOutput);
    447   assert(FileFormat &&
    448          "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
    449 
    450   unsigned int EntrySize = 0;
    451   uint64_t RegionSize = 0;
    452 
    453   if (&pSection == &(FileFormat->getPLT())) {
    454     assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
    455 
    456     unsigned char* buffer = pRegion.getBuffer();
    457 
    458     m_pPLT->applyPLT0();
    459     m_pPLT->applyPLT1();
    460 
    461     X86PLT::iterator it = m_pPLT->begin();
    462     unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize();
    463 
    464     memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size);
    465     RegionSize += plt0_size;
    466     ++it;
    467 
    468     X86PLT1* plt1 = 0;
    469     X86PLT::iterator ie = m_pPLT->end();
    470     while (it != ie) {
    471       plt1 = &(llvm::cast<X86PLT1>(*it));
    472       EntrySize = plt1->getEntrySize();
    473       memcpy(buffer + RegionSize, plt1->getContent(), EntrySize);
    474       RegionSize += EntrySize;
    475       ++it;
    476     }
    477   }
    478 
    479   else if (&pSection == &(FileFormat->getGOT())) {
    480     assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
    481 
    482     m_pGOT->applyGOT0(FileFormat->getDynamic().addr());
    483 
    484     uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
    485 
    486     GOTEntry* got = 0;
    487     EntrySize = m_pGOT->getEntrySize();
    488 
    489     for (X86GOT::iterator it = m_pGOT->begin(),
    490          ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
    491       got = &(llvm::cast<GOTEntry>((*it)));
    492       *buffer = static_cast<uint32_t>(got->getContent());
    493       RegionSize += EntrySize;
    494     }
    495   }
    496 
    497   else
    498     llvm::report_fatal_error("unsupported section name "
    499                              + pSection.name() + " !");
    500 
    501   return RegionSize;
    502 }
    503 uint32_t X86GNULDBackend::machine() const
    504 {
    505   return llvm::ELF::EM_386;
    506 }
    507 
    508 X86GOT& X86GNULDBackend::getGOT()
    509 {
    510   assert(NULL != m_pGOT);
    511   return *m_pGOT;
    512 }
    513 
    514 const X86GOT& X86GNULDBackend::getGOT() const
    515 {
    516   assert(NULL != m_pGOT);
    517   return *m_pGOT;
    518 }
    519 
    520 X86PLT& X86GNULDBackend::getPLT()
    521 {
    522   assert(NULL != m_pPLT && "PLT section not exist");
    523   return *m_pPLT;
    524 }
    525 
    526 const X86PLT& X86GNULDBackend::getPLT() const
    527 {
    528   assert(NULL != m_pPLT && "PLT section not exist");
    529   return *m_pPLT;
    530 }
    531 
    532 OutputRelocSection& X86GNULDBackend::getRelDyn()
    533 {
    534   assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
    535   return *m_pRelDyn;
    536 }
    537 
    538 const OutputRelocSection& X86GNULDBackend::getRelDyn() const
    539 {
    540   assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
    541   return *m_pRelDyn;
    542 }
    543 
    544 OutputRelocSection& X86GNULDBackend::getRelPLT()
    545 {
    546   assert(NULL != m_pRelPLT && ".rel.plt section not exist");
    547   return *m_pRelPLT;
    548 }
    549 
    550 const OutputRelocSection& X86GNULDBackend::getRelPLT() const
    551 {
    552   assert(NULL != m_pRelPLT && ".rel.plt section not exist");
    553   return *m_pRelPLT;
    554 }
    555 
    556 unsigned int
    557 X86GNULDBackend::getTargetSectionOrder(const Output& pOutput,
    558                                        const LDSection& pSectHdr) const
    559 {
    560   ELFFileFormat* file_format = getOutputFormat(pOutput);
    561 
    562   // FIXME: if command line option, "-z now", is given, we can let the order of
    563   // .got and .got.plt be the same as RELRO sections
    564   if (&pSectHdr == &file_format->getGOT())
    565     return SHO_RELRO_LAST;
    566 
    567   if (&pSectHdr == &file_format->getGOTPLT())
    568     return SHO_NON_RELRO_FIRST;
    569 
    570   if (&pSectHdr == &file_format->getPLT())
    571     return SHO_PLT;
    572 
    573   return SHO_UNDEFINED;
    574 }
    575 
    576 unsigned int X86GNULDBackend::bitclass() const
    577 {
    578   return 32;
    579 }
    580 
    581 bool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
    582 {
    583   return true;
    584 }
    585 
    586 void X86GNULDBackend::initTargetSections(MCLinker& pLinker)
    587 {
    588 }
    589 
    590 void X86GNULDBackend::initTargetSymbols(MCLinker& pLinker)
    591 {
    592   // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
    593   // same name in input
    594   m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
    595                    "_GLOBAL_OFFSET_TABLE_",
    596                    false,
    597                    ResolveInfo::Object,
    598                    ResolveInfo::Define,
    599                    ResolveInfo::Local,
    600                    0x0,  // size
    601                    0x0,  // value
    602                    NULL, // FragRef
    603                    ResolveInfo::Hidden);
    604 }
    605 
    606 /// finalizeSymbol - finalize the symbol value
    607 /// If the symbol's reserved field is not zero, MCLinker will call back this
    608 /// function to ask the final value of the symbol
    609 bool X86GNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const
    610 {
    611   return false;
    612 }
    613 
    614 /// allocateCommonSymbols - allocate common symbols in the corresponding
    615 /// sections.
    616 /// @refer Google gold linker: common.cc: 214
    617 bool
    618 X86GNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
    619 {
    620   // SymbolCategory contains all symbols that must emit to the output files.
    621   // We are not like Google gold linker, we don't remember symbols before symbol
    622   // resolution. All symbols in SymbolCategory are already resolved. Therefore, we
    623   // don't need to care about some symbols may be changed its category due to symbol
    624   // resolution.
    625   SymbolCategory& symbol_list = pLinker.getOutputSymbols();
    626 
    627   if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
    628     return true;
    629 
    630   // addralign := max value of all common symbols
    631   uint64_t addralign = 0x0;
    632 
    633   // Due to the visibility, some common symbols may be forcefully local.
    634   SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd();
    635   for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
    636     if (ResolveInfo::Common == (*com_sym)->desc()) {
    637       if ((*com_sym)->value() > addralign)
    638         addralign = (*com_sym)->value();
    639     }
    640   }
    641 
    642   // global common symbols.
    643   com_end = symbol_list.commonEnd();
    644   for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
    645     if ((*com_sym)->value() > addralign)
    646       addralign = (*com_sym)->value();
    647   }
    648 
    649   // FIXME: If the order of common symbols is defined, then sort common symbols
    650   // com_sym = symbol_list.commonBegin();
    651   // std::sort(com_sym, com_end, some kind of order);
    652 
    653   // get or create corresponding BSS LDSection
    654   LDSection* bss_sect_hdr = NULL;
    655   if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
    656     bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
    657                                    ".tbss",
    658                                    LDFileFormat::BSS,
    659                                    llvm::ELF::SHT_NOBITS,
    660                                    llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
    661   }
    662   else {
    663     bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
    664                                    LDFileFormat::BSS,
    665                                    llvm::ELF::SHT_NOBITS,
    666                                    llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
    667   }
    668 
    669   // get or create corresponding BSS MCSectionData
    670   assert(NULL != bss_sect_hdr);
    671   llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr);
    672 
    673   // allocate all common symbols
    674   uint64_t offset = bss_sect_hdr->size();
    675 
    676   // allocate all local common symbols
    677   com_end = symbol_list.localEnd();
    678   for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
    679     if (ResolveInfo::Common == (*com_sym)->desc()) {
    680       // We have to reset the description of the symbol here. When doing
    681       // incremental linking, the output relocatable object may have common
    682       // symbols. Therefore, we can not treat common symbols as normal symbols
    683       // when emitting the regular name pools. We must change the symbols'
    684       // description here.
    685       (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    686       llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
    687       (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
    688       uint64_t size = pLinker.getLayout().appendFragment(*frag,
    689                                                          bss_section,
    690                                                          (*com_sym)->value());
    691       offset += size;
    692     }
    693   }
    694 
    695   // allocate all global common symbols
    696   com_end = symbol_list.commonEnd();
    697   for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
    698     // We have to reset the description of the symbol here. When doing
    699     // incremental linking, the output relocatable object may have common
    700     // symbols. Therefore, we can not treat common symbols as normal symbols
    701     // when emitting the regular name pools. We must change the symbols'
    702     // description here.
    703     (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    704     llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
    705     (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
    706     uint64_t size = pLinker.getLayout().appendFragment(*frag,
    707                                                        bss_section,
    708                                                        (*com_sym)->value());
    709     offset += size;
    710   }
    711 
    712   bss_sect_hdr->setSize(offset);
    713   symbol_list.changeCommonsToGlobal();
    714   return true;
    715 }
    716 
    717 namespace mcld {
    718 
    719 //===----------------------------------------------------------------------===//
    720 /// createX86LDBackend - the help funtion to create corresponding X86LDBackend
    721 ///
    722 TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
    723                                     const std::string& pTriple)
    724 {
    725   Triple theTriple(pTriple);
    726   if (theTriple.isOSDarwin()) {
    727     assert(0 && "MachO linker is not supported yet");
    728     /**
    729     return new X86MachOLDBackend(createX86MachOArchiveReader,
    730                                createX86MachOObjectReader,
    731                                createX86MachOObjectWriter);
    732     **/
    733   }
    734   if (theTriple.isOSWindows()) {
    735     assert(0 && "COFF linker is not supported yet");
    736     /**
    737     return new X86COFFLDBackend(createX86COFFArchiveReader,
    738                                createX86COFFObjectReader,
    739                                createX86COFFObjectWriter);
    740     **/
    741   }
    742   return new X86GNULDBackend();
    743 }
    744 
    745 } // namespace of mcld
    746 
    747 //=============================
    748 // Force static initialization.
    749 extern "C" void LLVMInitializeX86LDBackend() {
    750   // Register the linker backend
    751   mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend);
    752 }
    753