Home | History | Annotate | Download | only in Mips
      1 //===- MipsLDBackend.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 "Mips.h"
     10 #include "MipsGNUInfo.h"
     11 #include "MipsELFDynamic.h"
     12 #include "MipsLA25Stub.h"
     13 #include "MipsLDBackend.h"
     14 #include "MipsRelocator.h"
     15 
     16 #include <llvm/ADT/Triple.h>
     17 #include <llvm/Support/Casting.h>
     18 #include <llvm/Support/ELF.h>
     19 #include <llvm/Support/Host.h>
     20 
     21 #include <mcld/Module.h>
     22 #include <mcld/LinkerConfig.h>
     23 #include <mcld/IRBuilder.h>
     24 #include <mcld/LD/BranchIslandFactory.h>
     25 #include <mcld/LD/LDContext.h>
     26 #include <mcld/LD/StubFactory.h>
     27 #include <mcld/LD/ELFFileFormat.h>
     28 #include <mcld/MC/Attribute.h>
     29 #include <mcld/Fragment/FillFragment.h>
     30 #include <mcld/Support/MemoryRegion.h>
     31 #include <mcld/Support/MemoryArea.h>
     32 #include <mcld/Support/MsgHandling.h>
     33 #include <mcld/Support/TargetRegistry.h>
     34 #include <mcld/Target/OutputRelocSection.h>
     35 #include <mcld/Object/ObjectBuilder.h>
     36 
     37 using namespace mcld;
     38 
     39 //===----------------------------------------------------------------------===//
     40 // MipsGNULDBackend
     41 //===----------------------------------------------------------------------===//
     42 MipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig,
     43                                    MipsGNUInfo* pInfo)
     44   : GNULDBackend(pConfig, pInfo),
     45     m_pRelocator(NULL),
     46     m_pGOT(NULL),
     47     m_pPLT(NULL),
     48     m_pGOTPLT(NULL),
     49     m_pInfo(*pInfo),
     50     m_pRelPlt(NULL),
     51     m_pRelDyn(NULL),
     52     m_pDynamic(NULL),
     53     m_pGOTSymbol(NULL),
     54     m_pPLTSymbol(NULL),
     55     m_pGpDispSymbol(NULL)
     56 {
     57 }
     58 
     59 MipsGNULDBackend::~MipsGNULDBackend()
     60 {
     61   delete m_pRelocator;
     62   delete m_pPLT;
     63   delete m_pRelPlt;
     64   delete m_pRelDyn;
     65   delete m_pDynamic;
     66 }
     67 
     68 bool MipsGNULDBackend::needsLA25Stub(Relocation::Type pType,
     69                                      const mcld::ResolveInfo* pSym)
     70 {
     71   if (config().isCodeIndep())
     72     return false;
     73 
     74   if (llvm::ELF::R_MIPS_26 != pType)
     75     return false;
     76 
     77   if (pSym->isLocal())
     78     return false;
     79 
     80   return true;
     81 }
     82 
     83 void MipsGNULDBackend::addNonPICBranchSym(ResolveInfo* rsym)
     84 {
     85   m_HasNonPICBranchSyms.insert(rsym);
     86 }
     87 
     88 bool MipsGNULDBackend::hasNonPICBranch(const ResolveInfo* rsym) const
     89 {
     90   return m_HasNonPICBranchSyms.count(rsym);
     91 }
     92 
     93 void MipsGNULDBackend::initTargetSections(Module& pModule,
     94                                             ObjectBuilder& pBuilder)
     95 {
     96   if (LinkerConfig::Object == config().codeGenType())
     97     return;
     98 
     99   ELFFileFormat* file_format = getOutputFormat();
    100 
    101   // initialize .rel.plt
    102   LDSection& relplt = file_format->getRelPlt();
    103   m_pRelPlt = new OutputRelocSection(pModule, relplt);
    104 
    105   // initialize .rel.dyn
    106   LDSection& reldyn = file_format->getRelDyn();
    107   m_pRelDyn = new OutputRelocSection(pModule, reldyn);
    108 }
    109 
    110 void MipsGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
    111 {
    112   // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
    113   // same name in input
    114   m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    115                    "_GLOBAL_OFFSET_TABLE_",
    116                    ResolveInfo::Object,
    117                    ResolveInfo::Define,
    118                    ResolveInfo::Local,
    119                    0x0,  // size
    120                    0x0,  // value
    121                    FragmentRef::Null(), // FragRef
    122                    ResolveInfo::Hidden);
    123 
    124   // Define the symbol _PROCEDURE_LINKAGE_TABLE_ if there is a symbol with the
    125   // same name in input
    126   m_pPLTSymbol =
    127     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    128                    "_PROCEDURE_LINKAGE_TABLE_",
    129                    ResolveInfo::Object,
    130                    ResolveInfo::Define,
    131                    ResolveInfo::Local,
    132                    0x0,  // size
    133                    0x0,  // value
    134                    FragmentRef::Null(), // FragRef
    135                    ResolveInfo::Hidden);
    136 
    137   m_pGpDispSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    138                    "_gp_disp",
    139                    ResolveInfo::Section,
    140                    ResolveInfo::Define,
    141                    ResolveInfo::Absolute,
    142                    0x0,  // size
    143                    0x0,  // value
    144                    FragmentRef::Null(), // FragRef
    145                    ResolveInfo::Default);
    146   pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
    147                    "_gp",
    148                    ResolveInfo::NoType,
    149                    ResolveInfo::Define,
    150                    ResolveInfo::Absolute,
    151                    0x0,  // size
    152                    0x0,  // value
    153                    FragmentRef::Null(), // FragRef
    154                    ResolveInfo::Default);
    155 }
    156 
    157 const Relocator* MipsGNULDBackend::getRelocator() const
    158 {
    159   assert(NULL != m_pRelocator);
    160   return m_pRelocator;
    161 }
    162 
    163 Relocator* MipsGNULDBackend::getRelocator()
    164 {
    165   assert(NULL != m_pRelocator);
    166   return m_pRelocator;
    167 }
    168 
    169 void MipsGNULDBackend::doPreLayout(IRBuilder& pBuilder)
    170 {
    171   // initialize .dynamic data
    172   if (!config().isCodeStatic() && NULL == m_pDynamic)
    173     m_pDynamic = new MipsELFDynamic(*this, config());
    174 
    175   // set .got size
    176   // when building shared object, the .got section is must.
    177   if (LinkerConfig::Object != config().codeGenType()) {
    178     if (LinkerConfig::DynObj == config().codeGenType() ||
    179         m_pGOT->hasGOT1() ||
    180         NULL != m_pGOTSymbol) {
    181       m_pGOT->finalizeScanning(*m_pRelDyn);
    182       m_pGOT->finalizeSectionSize();
    183 
    184       defineGOTSymbol(pBuilder);
    185     }
    186 
    187     if (m_pGOTPLT->hasGOT1()) {
    188       m_pGOTPLT->finalizeSectionSize();
    189 
    190       defineGOTPLTSymbol(pBuilder);
    191     }
    192 
    193     if (m_pPLT->hasPLT1())
    194       m_pPLT->finalizeSectionSize();
    195 
    196     ELFFileFormat* file_format = getOutputFormat();
    197 
    198     // set .rel.plt size
    199     if (!m_pRelPlt->empty()) {
    200       assert(!config().isCodeStatic() &&
    201             "static linkage should not result in a dynamic relocation section");
    202       file_format->getRelPlt().setSize(
    203                                   m_pRelPlt->numOfRelocs() * getRelEntrySize());
    204     }
    205 
    206     // set .rel.dyn size
    207     if (!m_pRelDyn->empty()) {
    208       assert(!config().isCodeStatic() &&
    209             "static linkage should not result in a dynamic relocation section");
    210       file_format->getRelDyn().setSize(
    211                                   m_pRelDyn->numOfRelocs() * getRelEntrySize());
    212     }
    213   }
    214 }
    215 
    216 void MipsGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder)
    217 {
    218   const ELFFileFormat *format = getOutputFormat();
    219 
    220   if (format->hasGOTPLT()) {
    221     assert(m_pGOTPLT && "doPostLayout failed, m_pGOTPLT is NULL!");
    222     m_pGOTPLT->applyAllGOTPLT(m_pPLT->addr());
    223   }
    224 
    225   if (format->hasPLT()) {
    226     assert(m_pPLT && "doPostLayout failed, m_pPLT is NULL!");
    227     m_pPLT->applyAllPLT(*m_pGOTPLT);
    228   }
    229 
    230   m_pInfo.setABIVersion(m_pPLT && m_pPLT->hasPLT1() ? 1 : 0);
    231 
    232   // FIXME: (simon) We need to iterate all input sections
    233   // check that flags are consistent and merge them properly.
    234   uint64_t picFlags = llvm::ELF::EF_MIPS_CPIC;
    235   if (config().targets().triple().isArch64Bit()) {
    236     picFlags |= llvm::ELF::EF_MIPS_PIC;
    237   }
    238   else {
    239     if (LinkerConfig::DynObj == config().codeGenType())
    240       picFlags |= llvm::ELF::EF_MIPS_PIC;
    241   }
    242 
    243   m_pInfo.setPICFlags(picFlags);
    244 }
    245 
    246 /// dynamic - the dynamic section of the target machine.
    247 /// Use co-variant return type to return its own dynamic section.
    248 MipsELFDynamic& MipsGNULDBackend::dynamic()
    249 {
    250   assert(NULL != m_pDynamic);
    251   return *m_pDynamic;
    252 }
    253 
    254 /// dynamic - the dynamic section of the target machine.
    255 /// Use co-variant return type to return its own dynamic section.
    256 const MipsELFDynamic& MipsGNULDBackend::dynamic() const
    257 {
    258   assert(NULL != m_pDynamic);
    259   return *m_pDynamic;
    260 }
    261 
    262 uint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection,
    263                                            MemoryRegion& pRegion) const
    264 {
    265   assert(pRegion.size() && "Size of MemoryRegion is zero!");
    266 
    267   const ELFFileFormat* file_format = getOutputFormat();
    268 
    269   if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) {
    270     return m_pGOT->emit(pRegion);
    271   }
    272 
    273   if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) {
    274     return m_pPLT->emit(pRegion);
    275   }
    276 
    277   if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) {
    278     return m_pGOTPLT->emit(pRegion);
    279   }
    280 
    281   fatal(diag::unrecognized_output_sectoin)
    282           << pSection.name()
    283           << "mclinker (at) googlegroups.com";
    284   return 0;
    285 }
    286 
    287 bool MipsGNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const
    288 {
    289   return ResolveInfo::Section != pSym.type() ||
    290          m_pGpDispSymbol == &pSym;
    291 }
    292 
    293 namespace {
    294   struct DynsymGOTCompare
    295   {
    296     const MipsGOT& m_pGOT;
    297 
    298     DynsymGOTCompare(const MipsGOT& pGOT)
    299       : m_pGOT(pGOT)
    300     {
    301     }
    302 
    303     bool operator()(const LDSymbol* X, const LDSymbol* Y) const
    304     {
    305       return m_pGOT.dynSymOrderCompare(X, Y);
    306     }
    307   };
    308 }
    309 
    310 void MipsGNULDBackend::orderSymbolTable(Module& pModule)
    311 {
    312   if (GeneralOptions::GNU  == config().options().getHashStyle() ||
    313       GeneralOptions::Both == config().options().getHashStyle()) {
    314     // The MIPS ABI and .gnu.hash require .dynsym to be sorted
    315     // in different ways. The MIPS ABI requires a mapping between
    316     // the GOT and the symbol table. At the same time .gnu.hash
    317     // needs symbols to be grouped by hash code.
    318     llvm::errs() << ".gnu.hash is incompatible with the MIPS ABI\n";
    319   }
    320 
    321   Module::SymbolTable& symbols = pModule.getSymbolTable();
    322 
    323   std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(),
    324                    DynsymGOTCompare(*m_pGOT));
    325 }
    326 
    327 namespace llvm {
    328 namespace ELF {
    329 // SHT_MIPS_OPTIONS section's block descriptor.
    330 struct Elf_Options {
    331   unsigned char kind;     // Determines interpretation of variable
    332                           // part of descriptor. See ODK_xxx enumeration.
    333   unsigned char size;     // Byte size of descriptor, including this header.
    334   Elf64_Half    section;  // Section header index of section affected,
    335                           // or 0 for global options.
    336   Elf64_Word    info;     // Kind-specic information.
    337 };
    338 
    339 // Type of SHT_MIPS_OPTIONS section's block.
    340 enum {
    341   ODK_NULL       = 0, // Undefined.
    342   ODK_REGINFO    = 1, // Register usage and GP value.
    343   ODK_EXCEPTIONS = 2, // Exception processing information.
    344   ODK_PAD        = 3, // Section padding information.
    345   ODK_HWPATCH    = 4, // Hardware workarounds performed.
    346   ODK_FILL       = 5, // Fill value used by the linker.
    347   ODK_TAGS       = 6, // Reserved space for desktop tools.
    348   ODK_HWAND      = 7, // Hardware workarounds, AND bits when merging.
    349   ODK_HWOR       = 8, // Hardware workarounds, OR bits when merging.
    350   ODK_GP_GROUP   = 9, // GP group to use for text/data sections.
    351   ODK_IDENT      = 10 // ID information.
    352 };
    353 
    354 // Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 32 bit ABI.
    355 struct Elf32_RegInfo {
    356   Elf32_Word ri_gprmask;    // Mask of general purpose registers used.
    357   Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used.
    358   Elf32_Addr ri_gp_value;   // GP register value for this object file.
    359 };
    360 
    361 // Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 64 bit ABI.
    362 struct Elf64_RegInfo {
    363   Elf32_Word ri_gprmask;    // Mask of general purpose registers used.
    364   Elf32_Word ri_pad;        // Padding.
    365   Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used.
    366   Elf64_Addr ri_gp_value;   // GP register value for this object file.
    367 };
    368 
    369 }
    370 }
    371 
    372 bool MipsGNULDBackend::readSection(Input& pInput, SectionData& pSD)
    373 {
    374   llvm::StringRef name(pSD.getSection().name());
    375 
    376   if (name.startswith(".sdata")) {
    377     uint64_t offset = pInput.fileOffset() + pSD.getSection().offset();
    378     uint64_t size = pSD.getSection().size();
    379 
    380     Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size);
    381     ObjectBuilder::AppendFragment(*frag, pSD);
    382     return true;
    383   }
    384 
    385   if (pSD.getSection().type() == llvm::ELF::SHT_MIPS_OPTIONS) {
    386     uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
    387     uint32_t size = pSD.getSection().size();
    388 
    389     llvm::StringRef region = pInput.memArea()->request(offset, size);
    390     if (region.size() > 0) {
    391       const llvm::ELF::Elf_Options* optb =
    392         reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin());
    393       const llvm::ELF::Elf_Options* opte =
    394         reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin() + size);
    395 
    396       for (const llvm::ELF::Elf_Options* opt = optb; opt < opte; opt += opt->size) {
    397         switch (opt->kind) {
    398           default:
    399             // Nothing to do.
    400             break;
    401           case llvm::ELF::ODK_REGINFO:
    402             if (config().targets().triple().isArch32Bit()) {
    403               const llvm::ELF::Elf32_RegInfo* reg =
    404                 reinterpret_cast<const llvm::ELF::Elf32_RegInfo*>(opt + 1);
    405               m_GP0Map[&pInput] = reg->ri_gp_value;
    406             }
    407             else {
    408               const llvm::ELF::Elf64_RegInfo* reg =
    409                 reinterpret_cast<const llvm::ELF::Elf64_RegInfo*>(opt + 1);
    410               m_GP0Map[&pInput] = reg->ri_gp_value;
    411             }
    412             break;
    413         }
    414       }
    415     }
    416 
    417     return true;
    418   }
    419 
    420   return GNULDBackend::readSection(pInput, pSD);
    421 }
    422 
    423 MipsGOT& MipsGNULDBackend::getGOT()
    424 {
    425   assert(NULL != m_pGOT);
    426   return *m_pGOT;
    427 }
    428 
    429 const MipsGOT& MipsGNULDBackend::getGOT() const
    430 {
    431   assert(NULL != m_pGOT);
    432   return *m_pGOT;
    433 }
    434 
    435 MipsPLT& MipsGNULDBackend::getPLT()
    436 {
    437   assert(NULL != m_pPLT);
    438   return *m_pPLT;
    439 }
    440 
    441 const MipsPLT& MipsGNULDBackend::getPLT() const
    442 {
    443   assert(NULL != m_pPLT);
    444   return *m_pPLT;
    445 }
    446 
    447 MipsGOTPLT& MipsGNULDBackend::getGOTPLT()
    448 {
    449   assert(NULL != m_pGOTPLT);
    450   return *m_pGOTPLT;
    451 }
    452 
    453 const MipsGOTPLT& MipsGNULDBackend::getGOTPLT() const
    454 {
    455   assert(NULL != m_pGOTPLT);
    456   return *m_pGOTPLT;
    457 }
    458 
    459 OutputRelocSection& MipsGNULDBackend::getRelPLT()
    460 {
    461   assert(NULL != m_pRelPlt);
    462   return *m_pRelPlt;
    463 }
    464 
    465 const OutputRelocSection& MipsGNULDBackend::getRelPLT() const
    466 {
    467   assert(NULL != m_pRelPlt);
    468   return *m_pRelPlt;
    469 }
    470 
    471 OutputRelocSection& MipsGNULDBackend::getRelDyn()
    472 {
    473   assert(NULL != m_pRelDyn);
    474   return *m_pRelDyn;
    475 }
    476 
    477 const OutputRelocSection& MipsGNULDBackend::getRelDyn() const
    478 {
    479   assert(NULL != m_pRelDyn);
    480   return *m_pRelDyn;
    481 }
    482 
    483 unsigned int
    484 MipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
    485 {
    486   const ELFFileFormat* file_format = getOutputFormat();
    487 
    488   if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT()))
    489     return SHO_DATA;
    490 
    491   if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT()))
    492     return SHO_DATA;
    493 
    494   if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
    495     return SHO_PLT;
    496 
    497   return SHO_UNDEFINED;
    498 }
    499 
    500 /// finalizeSymbol - finalize the symbol value
    501 bool MipsGNULDBackend::finalizeTargetSymbols()
    502 {
    503   if (NULL != m_pGpDispSymbol)
    504     m_pGpDispSymbol->setValue(m_pGOT->getGPDispAddress());
    505 
    506   return true;
    507 }
    508 
    509 /// allocateCommonSymbols - allocate common symbols in the corresponding
    510 /// sections. This is called at pre-layout stage.
    511 /// @refer Google gold linker: common.cc: 214
    512 /// FIXME: Mips needs to allocate small common symbol
    513 bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule)
    514 {
    515   SymbolCategory& symbol_list = pModule.getSymbolTable();
    516 
    517   if (symbol_list.emptyCommons() && symbol_list.emptyFiles() &&
    518       symbol_list.emptyLocals() && symbol_list.emptyLocalDyns())
    519     return true;
    520 
    521   SymbolCategory::iterator com_sym, com_end;
    522 
    523   // FIXME: If the order of common symbols is defined, then sort common symbols
    524   // std::sort(com_sym, com_end, some kind of order);
    525 
    526   // get corresponding BSS LDSection
    527   ELFFileFormat* file_format = getOutputFormat();
    528   LDSection& bss_sect = file_format->getBSS();
    529   LDSection& tbss_sect = file_format->getTBSS();
    530 
    531   // get or create corresponding BSS SectionData
    532   SectionData* bss_sect_data = NULL;
    533   if (bss_sect.hasSectionData())
    534     bss_sect_data = bss_sect.getSectionData();
    535   else
    536     bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
    537 
    538   SectionData* tbss_sect_data = NULL;
    539   if (tbss_sect.hasSectionData())
    540     tbss_sect_data = tbss_sect.getSectionData();
    541   else
    542     tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
    543 
    544   // remember original BSS size
    545   uint64_t bss_offset  = bss_sect.size();
    546   uint64_t tbss_offset = tbss_sect.size();
    547 
    548   // allocate all local common symbols
    549   com_end = symbol_list.localEnd();
    550 
    551   for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
    552     if (ResolveInfo::Common == (*com_sym)->desc()) {
    553       // We have to reset the description of the symbol here. When doing
    554       // incremental linking, the output relocatable object may have common
    555       // symbols. Therefore, we can not treat common symbols as normal symbols
    556       // when emitting the regular name pools. We must change the symbols'
    557       // description here.
    558       (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    559       Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
    560 
    561       if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
    562         // allocate TLS common symbol in tbss section
    563         tbss_offset += ObjectBuilder::AppendFragment(*frag,
    564                                                      *tbss_sect_data,
    565                                                      (*com_sym)->value());
    566         ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
    567         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    568       }
    569       // FIXME: how to identify small and large common symbols?
    570       else {
    571         bss_offset += ObjectBuilder::AppendFragment(*frag,
    572                                                     *bss_sect_data,
    573                                                     (*com_sym)->value());
    574         ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
    575         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    576       }
    577     }
    578   }
    579 
    580   // allocate all global common symbols
    581   com_end = symbol_list.commonEnd();
    582   for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
    583     // We have to reset the description of the symbol here. When doing
    584     // incremental linking, the output relocatable object may have common
    585     // symbols. Therefore, we can not treat common symbols as normal symbols
    586     // when emitting the regular name pools. We must change the symbols'
    587     // description here.
    588     (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    589     Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
    590 
    591     if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
    592       // allocate TLS common symbol in tbss section
    593       tbss_offset += ObjectBuilder::AppendFragment(*frag,
    594                                                    *tbss_sect_data,
    595                                                    (*com_sym)->value());
    596       ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
    597       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    598     }
    599     // FIXME: how to identify small and large common symbols?
    600     else {
    601       bss_offset += ObjectBuilder::AppendFragment(*frag,
    602                                                   *bss_sect_data,
    603                                                   (*com_sym)->value());
    604       ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
    605       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    606     }
    607   }
    608 
    609   bss_sect.setSize(bss_offset);
    610   tbss_sect.setSize(tbss_offset);
    611   symbol_list.changeCommonsToGlobal();
    612   return true;
    613 }
    614 
    615 uint64_t MipsGNULDBackend::getGP0(const Input& pInput) const
    616 {
    617   return m_GP0Map.lookup(&pInput);
    618 }
    619 
    620 void MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder)
    621 {
    622   // If we do not reserve any GOT entries, we do not need to re-define GOT
    623   // symbol.
    624   if (!m_pGOT->hasGOT1())
    625     return;
    626 
    627   // define symbol _GLOBAL_OFFSET_TABLE_
    628   if ( m_pGOTSymbol != NULL ) {
    629     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
    630                      "_GLOBAL_OFFSET_TABLE_",
    631                      ResolveInfo::Object,
    632                      ResolveInfo::Define,
    633                      ResolveInfo::Local,
    634                      0x0, // size
    635                      0x0, // value
    636                      FragmentRef::Create(*(m_pGOT->begin()), 0x0),
    637                      ResolveInfo::Hidden);
    638   }
    639   else {
    640     m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    641                      "_GLOBAL_OFFSET_TABLE_",
    642                      ResolveInfo::Object,
    643                      ResolveInfo::Define,
    644                      ResolveInfo::Local,
    645                      0x0, // size
    646                      0x0, // value
    647                      FragmentRef::Create(*(m_pGOT->begin()), 0x0),
    648                      ResolveInfo::Hidden);
    649   }
    650 }
    651 
    652 void MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder)
    653 {
    654   // define symbol _PROCEDURE_LINKAGE_TABLE_
    655   if ( m_pPLTSymbol != NULL ) {
    656     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
    657                      "_PROCEDURE_LINKAGE_TABLE_",
    658                      ResolveInfo::Object,
    659                      ResolveInfo::Define,
    660                      ResolveInfo::Local,
    661                      0x0, // size
    662                      0x0, // value
    663                      FragmentRef::Create(*(m_pPLT->begin()), 0x0),
    664                      ResolveInfo::Hidden);
    665   }
    666   else {
    667     m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    668                      "_PROCEDURE_LINKAGE_TABLE_",
    669                      ResolveInfo::Object,
    670                      ResolveInfo::Define,
    671                      ResolveInfo::Local,
    672                      0x0, // size
    673                      0x0, // value
    674                      FragmentRef::Create(*(m_pPLT->begin()), 0x0),
    675                      ResolveInfo::Hidden);
    676   }
    677 }
    678 
    679 /// doCreateProgramHdrs - backend can implement this function to create the
    680 /// target-dependent segments
    681 void MipsGNULDBackend::doCreateProgramHdrs(Module& pModule)
    682 {
    683   // TODO
    684 }
    685 
    686 bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel)
    687 {
    688   uint64_t sym_value = 0x0;
    689 
    690   LDSymbol* symbol = pRel.symInfo()->outSymbol();
    691   if (symbol->hasFragRef()) {
    692     uint64_t value = symbol->fragRef()->getOutputOffset();
    693     uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr();
    694     sym_value = addr + value;
    695   }
    696 
    697   Stub* stub =
    698     getStubFactory()->create(pRel, sym_value, pBuilder, *getBRIslandFactory());
    699 
    700   if (NULL == stub)
    701     return false;
    702 
    703   assert(NULL != stub->symInfo());
    704   // increase the size of .symtab and .strtab
    705   LDSection& symtab = getOutputFormat()->getSymTab();
    706   LDSection& strtab = getOutputFormat()->getStrTab();
    707   symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
    708   strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
    709 
    710   return true;
    711 }
    712 
    713 bool MipsGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder,
    714                                bool& pFinished)
    715 {
    716   assert(NULL != getStubFactory() && NULL != getBRIslandFactory());
    717 
    718   bool isRelaxed = false;
    719 
    720   for (Module::obj_iterator input = pModule.obj_begin();
    721        input != pModule.obj_end(); ++input) {
    722     LDContext* context = (*input)->context();
    723 
    724     for (LDContext::sect_iterator rs = context->relocSectBegin();
    725          rs != context->relocSectEnd(); ++rs) {
    726       LDSection* sec = *rs;
    727 
    728       if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData())
    729         continue;
    730 
    731       for (RelocData::iterator reloc = sec->getRelocData()->begin();
    732            reloc != sec->getRelocData()->end(); ++reloc) {
    733         if (llvm::ELF::R_MIPS_26 != reloc->type())
    734           continue;
    735 
    736         if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc)))
    737           isRelaxed = true;
    738       }
    739     }
    740   }
    741 
    742   SectionData* textData = getOutputFormat()->getText().getSectionData();
    743 
    744   // find the first fragment w/ invalid offset due to stub insertion
    745   Fragment* invalid = NULL;
    746   pFinished = true;
    747   for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(),
    748                                      ie = getBRIslandFactory()->end();
    749        ii != ie; ++ii)
    750   {
    751     BranchIsland& island = *ii;
    752     if (island.end() == textData->end())
    753       break;
    754 
    755     Fragment* exit = island.end();
    756     if ((island.offset() + island.size()) > exit->getOffset()) {
    757       invalid = exit;
    758       pFinished = false;
    759       break;
    760     }
    761   }
    762 
    763   // reset the offset of invalid fragments
    764   while (NULL != invalid) {
    765     invalid->setOffset(invalid->getPrevNode()->getOffset() +
    766                        invalid->getPrevNode()->size());
    767     invalid = invalid->getNextNode();
    768   }
    769 
    770   // reset the size of .text
    771   if (isRelaxed)
    772     getOutputFormat()->getText().setSize(textData->back().getOffset() +
    773                                          textData->back().size());
    774 
    775   return isRelaxed;
    776 }
    777 
    778 bool MipsGNULDBackend::initTargetStubs()
    779 {
    780   if (NULL == getStubFactory())
    781     return false;
    782 
    783   getStubFactory()->addPrototype(new MipsLA25Stub(*this));
    784   return true;
    785 }
    786 
    787 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel,
    788                                       Relocation::Type& pType,
    789                                       uint32_t& pSymIdx,
    790                                       uint32_t& pOffset) const
    791 {
    792   return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset);
    793 }
    794 
    795 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel,
    796                                       Relocation::Type& pType,
    797                                       uint32_t& pSymIdx,
    798                                       uint32_t& pOffset,
    799                                       int32_t& pAddend) const
    800 {
    801   return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
    802 }
    803 
    804 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel,
    805                                       Relocation::Type& pType,
    806                                       uint32_t& pSymIdx,
    807                                       uint64_t& pOffset) const
    808 {
    809   uint64_t r_info = 0x0;
    810   if (llvm::sys::IsLittleEndianHost) {
    811     pOffset = pRel.r_offset;
    812     r_info  = pRel.r_info;
    813   }
    814   else {
    815     pOffset = mcld::bswap64(pRel.r_offset);
    816     r_info  = mcld::bswap64(pRel.r_info);
    817   }
    818 
    819   // MIPS 64 little endian (we do not support big endian now)
    820   // has a "special" encoding of r_info relocation
    821   // field. Instead of one 64 bit little endian number, it is a little
    822   // endian 32 bit number followed by a 32 bit big endian number.
    823   pType = mcld::bswap32(r_info >> 32);
    824   pSymIdx = r_info & 0xffffffff;
    825   return true;
    826 }
    827 
    828 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel,
    829                                       Relocation::Type& pType,
    830                                       uint32_t& pSymIdx,
    831                                       uint64_t& pOffset,
    832                                       int64_t& pAddend) const
    833 {
    834   uint64_t r_info = 0x0;
    835   if (llvm::sys::IsLittleEndianHost) {
    836     pOffset = pRel.r_offset;
    837     r_info  = pRel.r_info;
    838     pAddend = pRel.r_addend;
    839   }
    840   else {
    841     pOffset = mcld::bswap64(pRel.r_offset);
    842     r_info  = mcld::bswap64(pRel.r_info);
    843     pAddend = mcld::bswap64(pRel.r_addend);
    844   }
    845 
    846   pType = mcld::bswap32(r_info >> 32);
    847   pSymIdx = r_info & 0xffffffff;
    848   return true;
    849 }
    850 
    851 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel,
    852                                       Relocation::Type pType,
    853                                       uint32_t pSymIdx,
    854                                       uint32_t pOffset) const
    855 {
    856   GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset);
    857 }
    858 
    859 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel,
    860                                       Relocation::Type pType,
    861                                       uint32_t pSymIdx,
    862                                       uint32_t pOffset,
    863                                       int32_t pAddend) const
    864 {
    865   GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
    866 }
    867 
    868 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel,
    869                                       Relocation::Type pType,
    870                                       uint32_t pSymIdx,
    871                                       uint64_t pOffset) const
    872 {
    873   uint64_t r_info = mcld::bswap32(pType);
    874   r_info <<= 32;
    875   r_info |= pSymIdx;
    876 
    877   pRel.r_info = r_info;
    878   pRel.r_offset = pOffset;
    879 }
    880 
    881 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel,
    882                                       Relocation::Type pType,
    883                                       uint32_t pSymIdx,
    884                                       uint64_t pOffset,
    885                                       int64_t pAddend) const
    886 {
    887   uint64_t r_info = mcld::bswap32(pType);
    888   r_info <<= 32;
    889   r_info |= pSymIdx;
    890 
    891   pRel.r_info = r_info;
    892   pRel.r_offset = pOffset;
    893   pRel.r_addend = pAddend;
    894 }
    895 
    896 //===----------------------------------------------------------------------===//
    897 // Mips32GNULDBackend
    898 //===----------------------------------------------------------------------===//
    899 Mips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig,
    900                                        MipsGNUInfo* pInfo)
    901   : MipsGNULDBackend(pConfig, pInfo)
    902 {}
    903 
    904 bool Mips32GNULDBackend::initRelocator()
    905 {
    906   if (NULL == m_pRelocator)
    907     m_pRelocator = new Mips32Relocator(*this, config());
    908 
    909   return true;
    910 }
    911 
    912 void Mips32GNULDBackend::initTargetSections(Module& pModule,
    913                                             ObjectBuilder& pBuilder)
    914 {
    915   MipsGNULDBackend::initTargetSections(pModule, pBuilder);
    916 
    917   if (LinkerConfig::Object == config().codeGenType())
    918     return;
    919 
    920   ELFFileFormat* fileFormat = getOutputFormat();
    921 
    922   // initialize .got
    923   LDSection& got = fileFormat->getGOT();
    924   m_pGOT = new Mips32GOT(got);
    925 
    926   // initialize .got.plt
    927   LDSection& gotplt = fileFormat->getGOTPLT();
    928   m_pGOTPLT = new MipsGOTPLT(gotplt);
    929 
    930   // initialize .plt
    931   LDSection& plt = fileFormat->getPLT();
    932   m_pPLT = new MipsPLT(plt);
    933 }
    934 
    935 size_t Mips32GNULDBackend::getRelEntrySize()
    936 {
    937   return 8;
    938 }
    939 
    940 size_t Mips32GNULDBackend::getRelaEntrySize()
    941 {
    942   return 12;
    943 }
    944 
    945 //===----------------------------------------------------------------------===//
    946 // Mips64GNULDBackend
    947 //===----------------------------------------------------------------------===//
    948 Mips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig,
    949                                        MipsGNUInfo* pInfo)
    950   : MipsGNULDBackend(pConfig, pInfo)
    951 {}
    952 
    953 bool Mips64GNULDBackend::initRelocator()
    954 {
    955   if (NULL == m_pRelocator)
    956     m_pRelocator = new Mips64Relocator(*this, config());
    957 
    958   return true;
    959 }
    960 
    961 void Mips64GNULDBackend::initTargetSections(Module& pModule,
    962                                             ObjectBuilder& pBuilder)
    963 {
    964   MipsGNULDBackend::initTargetSections(pModule, pBuilder);
    965 
    966   if (LinkerConfig::Object == config().codeGenType())
    967     return;
    968 
    969   ELFFileFormat* fileFormat = getOutputFormat();
    970 
    971   // initialize .got
    972   LDSection& got = fileFormat->getGOT();
    973   m_pGOT = new Mips64GOT(got);
    974 
    975   // initialize .got.plt
    976   LDSection& gotplt = fileFormat->getGOTPLT();
    977   m_pGOTPLT = new MipsGOTPLT(gotplt);
    978 
    979   // initialize .plt
    980   LDSection& plt = fileFormat->getPLT();
    981   m_pPLT = new MipsPLT(plt);
    982 }
    983 
    984 size_t Mips64GNULDBackend::getRelEntrySize()
    985 {
    986   return 16;
    987 }
    988 
    989 size_t Mips64GNULDBackend::getRelaEntrySize()
    990 {
    991   return 24;
    992 }
    993 
    994 //===----------------------------------------------------------------------===//
    995 /// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
    996 ///
    997 static TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig)
    998 {
    999   const llvm::Triple& triple = pConfig.targets().triple();
   1000 
   1001   if (triple.isOSDarwin()) {
   1002     assert(0 && "MachO linker is not supported yet");
   1003   }
   1004   if (triple.isOSWindows()) {
   1005     assert(0 && "COFF linker is not supported yet");
   1006   }
   1007 
   1008   llvm::Triple::ArchType arch = triple.getArch();
   1009 
   1010   if (llvm::Triple::mips64el == arch)
   1011     return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple));
   1012 
   1013   assert (arch == llvm::Triple::mipsel);
   1014   return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple));
   1015 }
   1016 
   1017 //===----------------------------------------------------------------------===//
   1018 // Force static initialization.
   1019 //===----------------------------------------------------------------------===//
   1020 extern "C" void MCLDInitializeMipsLDBackend() {
   1021   mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
   1022                                                 createMipsLDBackend);
   1023   mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget,
   1024                                                 createMipsLDBackend);
   1025 }
   1026