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 
     10 #include <llvm/ADT/Triple.h>
     11 #include <llvm/Support/ELF.h>
     12 
     13 #include <mcld/LD/SectionMap.h>
     14 #include <mcld/MC/MCLDInfo.h>
     15 #include <mcld/MC/MCLinker.h>
     16 #include <mcld/Support/MemoryRegion.h>
     17 #include <mcld/Support/TargetRegistry.h>
     18 #include <mcld/Target/OutputRelocSection.h>
     19 
     20 #include "Mips.h"
     21 #include "MipsELFDynamic.h"
     22 #include "MipsLDBackend.h"
     23 #include "MipsRelocationFactory.h"
     24 
     25 enum {
     26   // The original o32 abi.
     27   E_MIPS_ABI_O32    = 0x00001000,
     28   // O32 extended to work on 64 bit architectures.
     29   E_MIPS_ABI_O64    = 0x00002000,
     30   // EABI in 32 bit mode.
     31   E_MIPS_ABI_EABI32 = 0x00003000,
     32   // EABI in 64 bit mode.
     33   E_MIPS_ABI_EABI64 = 0x00004000
     34 };
     35 
     36 namespace mcld {
     37 
     38 MipsGNULDBackend::MipsGNULDBackend()
     39   : m_pRelocFactory(NULL),
     40     m_pGOT(NULL),
     41     m_pRelDyn(NULL),
     42     m_pDynamic(NULL),
     43     m_pGOTSymbol(NULL),
     44     m_pGpDispSymbol(NULL)
     45 {
     46 }
     47 
     48 MipsGNULDBackend::~MipsGNULDBackend()
     49 {
     50   if (NULL != m_pRelocFactory)
     51     delete m_pRelocFactory;
     52   if (NULL != m_pGOT)
     53     delete m_pGOT;
     54   if (NULL != m_pRelDyn)
     55     delete m_pRelDyn;
     56   if (NULL != m_pDynamic)
     57     delete m_pDynamic;
     58 }
     59 
     60 bool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
     61 {
     62   // Nothing to do because we do not support
     63   // any MIPS specific sections now.
     64   return true;
     65 }
     66 
     67 void MipsGNULDBackend::initTargetSections(MCLinker& pLinker)
     68 {
     69   // Nothing to do because we do not support
     70   // any MIPS specific sections now.
     71 }
     72 
     73 void MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker)
     74 {
     75   // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
     76   // same name in input
     77   m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
     78                    "_GLOBAL_OFFSET_TABLE_",
     79                    false,
     80                    ResolveInfo::Object,
     81                    ResolveInfo::Define,
     82                    ResolveInfo::Local,
     83                    0x0,  // size
     84                    0x0,  // value
     85                    NULL, // FragRef
     86                    ResolveInfo::Hidden);
     87 
     88   m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
     89                    "_gp_disp",
     90                    false,
     91                    ResolveInfo::Section,
     92                    ResolveInfo::Define,
     93                    ResolveInfo::Absolute,
     94                    0x0,  // size
     95                    0x0,  // value
     96                    NULL, // FragRef
     97                    ResolveInfo::Default);
     98 
     99   if (NULL != m_pGpDispSymbol) {
    100     m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp);
    101   }
    102 }
    103 
    104 bool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker)
    105 {
    106   if (NULL == m_pRelocFactory) {
    107     m_pRelocFactory = new MipsRelocationFactory(1024, *this);
    108     m_pRelocFactory->setLayout(pLinker.getLayout());
    109   }
    110   return true;
    111 }
    112 
    113 RelocationFactory* MipsGNULDBackend::getRelocFactory()
    114 {
    115   assert(NULL != m_pRelocFactory);
    116   return m_pRelocFactory;
    117 }
    118 
    119 void MipsGNULDBackend::scanRelocation(Relocation& pReloc,
    120                                       const LDSymbol& pInputSym,
    121                                       MCLinker& pLinker,
    122                                       const MCLDInfo& pLDInfo,
    123                                       const Output& pOutput)
    124 {
    125   // rsym - The relocation target symbol
    126   ResolveInfo* rsym = pReloc.symInfo();
    127   assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
    128 
    129   // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies
    130   // that a .got section is needed.
    131   if (NULL == m_pGOT && NULL != m_pGOTSymbol) {
    132     if (rsym == m_pGOTSymbol->resolveInfo()) {
    133       createGOT(pLinker, pOutput);
    134     }
    135   }
    136 
    137   if (rsym->isLocal())
    138     scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
    139   else
    140     scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
    141 }
    142 
    143 uint32_t MipsGNULDBackend::machine() const
    144 {
    145   return llvm::ELF::EM_MIPS;
    146 }
    147 
    148 uint8_t MipsGNULDBackend::OSABI() const
    149 {
    150   return llvm::ELF::ELFOSABI_NONE;
    151 }
    152 
    153 uint8_t MipsGNULDBackend::ABIVersion() const
    154 {
    155   return 0;
    156 }
    157 
    158 uint64_t MipsGNULDBackend::flags() const
    159 {
    160   // TODO: (simon) The correct flag's set depend on command line
    161   // arguments and flags from input .o files.
    162   return llvm::ELF::EF_MIPS_ARCH_32R2 |
    163          llvm::ELF::EF_MIPS_NOREORDER |
    164          llvm::ELF::EF_MIPS_PIC |
    165          llvm::ELF::EF_MIPS_CPIC |
    166          E_MIPS_ABI_O32;
    167 }
    168 
    169 bool MipsGNULDBackend::isLittleEndian() const
    170 {
    171   // Now we support little endian (mipsel) target only.
    172   return true;
    173 }
    174 
    175 unsigned int MipsGNULDBackend::bitclass() const
    176 {
    177   return 32;
    178 }
    179 
    180 void MipsGNULDBackend::doPreLayout(const Output& pOutput,
    181                                    const MCLDInfo& pInfo,
    182                                    MCLinker& pLinker)
    183 {
    184   // when building shared object, the .got section is must.
    185   if (pOutput.type() == Output::DynObj && NULL == m_pGOT) {
    186       createGOT(pLinker, pOutput);
    187   }
    188 }
    189 
    190 void MipsGNULDBackend::doPostLayout(const Output& pOutput,
    191                                     const MCLDInfo& pInfo,
    192                                     MCLinker& pLinker)
    193 {
    194   // emit program headers
    195   if (pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec)
    196     emitProgramHdrs(pLinker.getLDInfo().output());
    197 }
    198 
    199 /// dynamic - the dynamic section of the target machine.
    200 /// Use co-variant return type to return its own dynamic section.
    201 MipsELFDynamic& MipsGNULDBackend::dynamic()
    202 {
    203   if (NULL == m_pDynamic)
    204     m_pDynamic = new MipsELFDynamic(*this);
    205 
    206   return *m_pDynamic;
    207 }
    208 
    209 /// dynamic - the dynamic section of the target machine.
    210 /// Use co-variant return type to return its own dynamic section.
    211 const MipsELFDynamic& MipsGNULDBackend::dynamic() const
    212 {
    213   assert( NULL != m_pDynamic);
    214   return *m_pDynamic;
    215 }
    216 
    217 uint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput,
    218                                            const LDSection& pSection,
    219                                            const MCLDInfo& pInfo,
    220                                            MemoryRegion& pRegion) const
    221 {
    222   assert(pRegion.size() && "Size of MemoryRegion is zero!");
    223 
    224   ELFFileFormat* file_format = getOutputFormat(pOutput);
    225 
    226   if (&pSection == &(file_format->getGOT())) {
    227     assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
    228     uint64_t result = m_pGOT->emit(pRegion);
    229     return result;
    230   }
    231 
    232   llvm::report_fatal_error(llvm::Twine("Unable to emit section `") +
    233                            pSection.name() +
    234                            llvm::Twine("'.\n"));
    235   return 0;
    236 }
    237 /// isGOTSymbol - return true if the symbol is the GOT entry.
    238 bool MipsGNULDBackend::isGOTSymbol(const LDSymbol& pSymbol) const
    239 {
    240   return std::find(m_LocalGOTSyms.begin(),
    241                    m_LocalGOTSyms.end(), &pSymbol) != m_LocalGOTSyms.end() ||
    242          std::find(m_GlobalGOTSyms.begin(),
    243                    m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
    244 }
    245 
    246 /// emitDynamicSymbol - emit dynamic symbol.
    247 void MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
    248                                          Output& pOutput,
    249                                          LDSymbol& pSymbol,
    250                                          const Layout& pLayout,
    251                                          char* strtab,
    252                                          size_t strtabsize,
    253                                          size_t symtabIdx)
    254 {
    255   // maintain output's symbol and index map
    256   bool sym_exist = false;
    257   HashTableType::entry_type* entry = 0;
    258   entry = m_pSymIndexMap->insert(&pSymbol, sym_exist);
    259   entry->setValue(symtabIdx);
    260 
    261   // FIXME: check the endian between host and target
    262   // write out symbol
    263   sym32.st_name  = strtabsize;
    264   sym32.st_value = pSymbol.value();
    265   sym32.st_size  = getSymbolSize(pSymbol);
    266   sym32.st_info  = getSymbolInfo(pSymbol);
    267   sym32.st_other = pSymbol.visibility();
    268   sym32.st_shndx = getSymbolShndx(pSymbol, pLayout);
    269   // write out string
    270   strcpy((strtab + strtabsize), pSymbol.name());
    271 }
    272 
    273 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
    274 ///
    275 /// the size of these tables should be computed before layout
    276 /// layout should computes the start offset of these tables
    277 void MipsGNULDBackend::emitDynNamePools(Output& pOutput,
    278                                         SymbolCategory& pSymbols,
    279                                         const Layout& pLayout,
    280                                         const MCLDInfo& pLDInfo)
    281 {
    282   assert(pOutput.hasMemArea());
    283   ELFFileFormat* file_format = getOutputFormat(pOutput);
    284 
    285   LDSection& symtab_sect = file_format->getDynSymTab();
    286   LDSection& strtab_sect = file_format->getDynStrTab();
    287   LDSection& hash_sect   = file_format->getHashTab();
    288   LDSection& dyn_sect    = file_format->getDynamic();
    289 
    290   MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
    291                                                            symtab_sect.size());
    292   MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
    293                                                            strtab_sect.size());
    294   MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(),
    295                                                          hash_sect.size());
    296   MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(),
    297                                                         dyn_sect.size());
    298   // set up symtab_region
    299   llvm::ELF::Elf32_Sym* symtab32 = NULL;
    300   symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
    301 
    302   symtab32[0].st_name  = 0;
    303   symtab32[0].st_value = 0;
    304   symtab32[0].st_size  = 0;
    305   symtab32[0].st_info  = 0;
    306   symtab32[0].st_other = 0;
    307   symtab32[0].st_shndx = 0;
    308 
    309   // set up strtab_region
    310   char* strtab = (char*)strtab_region->start();
    311   strtab[0] = '\0';
    312 
    313   bool sym_exist = false;
    314   HashTableType::entry_type* entry = 0;
    315 
    316   // add index 0 symbol into SymIndexMap
    317   entry = m_pSymIndexMap->insert(NULL, sym_exist);
    318   entry->setValue(0);
    319 
    320   size_t symtabIdx = 1;
    321   size_t strtabsize = 1;
    322 
    323   // emit of .dynsym, and .dynstr except GOT entries
    324   for (SymbolCategory::iterator symbol = pSymbols.begin(),
    325        sym_end = pSymbols.end(); symbol != sym_end; ++symbol) {
    326     if (!isDynamicSymbol(**symbol, pOutput))
    327       continue;
    328 
    329     if (isGOTSymbol(**symbol))
    330       continue;
    331 
    332     emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
    333                       strtabsize, symtabIdx);
    334 
    335     // sum up counters
    336     ++symtabIdx;
    337     strtabsize += (*symbol)->nameSize() + 1;
    338   }
    339 
    340   // emit global GOT
    341   for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
    342        symbol_end = m_GlobalGOTSyms.end();
    343        symbol != symbol_end; ++symbol) {
    344 
    345     emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
    346                       strtabsize, symtabIdx);
    347 
    348     // sum up counters
    349     ++symtabIdx;
    350     strtabsize += (*symbol)->nameSize() + 1;
    351   }
    352 
    353   // emit DT_NEED
    354   // add DT_NEED strings into .dynstr
    355   // Rules:
    356   //   1. ignore --no-add-needed
    357   //   2. force count in --no-as-needed
    358   //   3. judge --as-needed
    359   ELFDynamic::iterator dt_need = dynamic().needBegin();
    360   InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
    361   for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
    362     if (Input::DynObj == (*input)->type()) {
    363       // --add-needed
    364       if ((*input)->attribute()->isAddNeeded()) {
    365         // --no-as-needed
    366         if (!(*input)->attribute()->isAsNeeded()) {
    367           strcpy((strtab + strtabsize), (*input)->name().c_str());
    368           (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
    369           strtabsize += (*input)->name().size() + 1;
    370           ++dt_need;
    371         }
    372         // --as-needed
    373         else if ((*input)->isNeeded()) {
    374           strcpy((strtab + strtabsize), (*input)->name().c_str());
    375           (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
    376           strtabsize += (*input)->name().size() + 1;
    377           ++dt_need;
    378         }
    379       }
    380     }
    381   } // for
    382 
    383   // emit soname
    384   // initialize value of ELF .dynamic section
    385   dynamic().applySoname(strtabsize);
    386   dynamic().applyEntries(pLDInfo, *file_format);
    387   dynamic().emit(dyn_sect, *dyn_region);
    388 
    389   strcpy((strtab + strtabsize), pOutput.name().c_str());
    390   strtabsize += pOutput.name().size() + 1;
    391 
    392   // emit hash table
    393   // FIXME: this verion only emit SVR4 hash section.
    394   //        Please add GNU new hash section
    395 
    396   // both 32 and 64 bits hash table use 32-bit entry
    397   // set up hash_region
    398   uint32_t* word_array = (uint32_t*)hash_region->start();
    399   uint32_t& nbucket = word_array[0];
    400   uint32_t& nchain  = word_array[1];
    401 
    402   nbucket = getHashBucketCount(symtabIdx, false);
    403   nchain  = symtabIdx;
    404 
    405   uint32_t* bucket = (word_array + 2);
    406   uint32_t* chain  = (bucket + nbucket);
    407 
    408   // initialize bucket
    409   bzero((void*)bucket, nbucket);
    410 
    411   StringHash<ELF> hash_func;
    412 
    413   for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
    414     llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
    415     size_t bucket_pos = hash_func(name) % nbucket;
    416     chain[sym_idx] = bucket[bucket_pos];
    417     bucket[bucket_pos] = sym_idx;
    418   }
    419 
    420 }
    421 
    422 MipsGOT& MipsGNULDBackend::getGOT()
    423 {
    424   assert(NULL != m_pGOT);
    425   return *m_pGOT;
    426 }
    427 
    428 const MipsGOT& MipsGNULDBackend::getGOT() const
    429 {
    430   assert(NULL != m_pGOT);
    431   return *m_pGOT;
    432 }
    433 
    434 OutputRelocSection& MipsGNULDBackend::getRelDyn()
    435 {
    436   assert(NULL != m_pRelDyn);
    437   return *m_pRelDyn;
    438 }
    439 
    440 const OutputRelocSection& MipsGNULDBackend::getRelDyn() const
    441 {
    442   assert(NULL != m_pRelDyn);
    443   return *m_pRelDyn;
    444 }
    445 
    446 unsigned int
    447 MipsGNULDBackend::getTargetSectionOrder(const Output& pOutput,
    448                                         const LDSection& pSectHdr) const
    449 {
    450   ELFFileFormat* file_format = getOutputFormat(pOutput);
    451 
    452   if (&pSectHdr == &file_format->getGOT())
    453     return SHO_DATA;
    454 
    455   return SHO_UNDEFINED;
    456 }
    457 
    458 /// finalizeSymbol - finalize the symbol value
    459 /// If the symbol's reserved field is not zero, MCLinker will call back this
    460 /// function to ask the final value of the symbol
    461 bool MipsGNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const
    462 {
    463   if (&pSymbol == m_pGpDispSymbol) {
    464     m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0);
    465     return true;
    466   }
    467   return false;
    468 }
    469 
    470 /// allocateCommonSymbols - allocate common symbols in the corresponding
    471 /// sections.
    472 /// @refer Google gold linker: common.cc: 214
    473 /// FIXME: Mips needs to allocate small common symbol
    474 bool
    475 MipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
    476 {
    477   // SymbolCategory contains all symbols that must emit to the output files.
    478   // We are not like Google gold linker, we don't remember symbols before symbol
    479   // resolution. All symbols in SymbolCategory are already resolved. Therefore, we
    480   // don't need to care about some symbols may be changed its category due to symbol
    481   // resolution.
    482   SymbolCategory& symbol_list = pLinker.getOutputSymbols();
    483 
    484   if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
    485     return true;
    486 
    487   // addralign := max value of all common symbols
    488   uint64_t addralign = 0x0;
    489 
    490   // Due to the visibility, some common symbols may be forcefully local.
    491   SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd();
    492   for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
    493     if (ResolveInfo::Common == (*com_sym)->desc()) {
    494       if ((*com_sym)->value() > addralign)
    495         addralign = (*com_sym)->value();
    496     }
    497   }
    498 
    499   // global common symbols.
    500   com_end = symbol_list.commonEnd();
    501   for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
    502     if ((*com_sym)->value() > addralign)
    503       addralign = (*com_sym)->value();
    504   }
    505 
    506   // FIXME: If the order of common symbols is defined, then sort common symbols
    507   // com_sym = symbol_list.commonBegin();
    508   // std::sort(com_sym, com_end, some kind of order);
    509 
    510   // get or create corresponding BSS LDSection
    511   LDSection* bss_sect_hdr = NULL;
    512   if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
    513     bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
    514                                    ".tbss",
    515                                    LDFileFormat::BSS,
    516                                    llvm::ELF::SHT_NOBITS,
    517                                    llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
    518   }
    519   else {
    520     bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
    521                                    LDFileFormat::BSS,
    522                                    llvm::ELF::SHT_NOBITS,
    523                                    llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
    524   }
    525 
    526   // get or create corresponding BSS MCSectionData
    527   assert(NULL != bss_sect_hdr);
    528   llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr);
    529 
    530   // allocate all common symbols
    531   uint64_t offset = bss_sect_hdr->size();
    532 
    533   // allocate all local common symbols
    534   com_end = symbol_list.localEnd();
    535   for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
    536     if (ResolveInfo::Common == (*com_sym)->desc()) {
    537       alignAddress(offset, (*com_sym)->value());
    538       // We have to reset the description of the symbol here. When doing
    539       // incremental linking, the output relocatable object may have common
    540       // symbols. Therefore, we can not treat common symbols as normal symbols
    541       // when emitting the regular name pools. We must change the symbols'
    542       // description here.
    543       (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    544       llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section);
    545       (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
    546       offset += (*com_sym)->size();
    547     }
    548   }
    549 
    550   // allocate all global common symbols
    551   com_end = symbol_list.commonEnd();
    552   for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
    553     alignAddress(offset, (*com_sym)->value());
    554 
    555     // We have to reset the description of the symbol here. When doing
    556     // incremental linking, the output relocatable object may have common
    557     // symbols. Therefore, we can not treat common symbols as normal symbols
    558     // when emitting the regular name pools. We must change the symbols'
    559     // description here.
    560     (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    561     llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section);
    562     (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
    563     offset += (*com_sym)->size();
    564   }
    565 
    566   bss_sect_hdr->setSize(offset);
    567   symbol_list.changeCommonsToGlobal();
    568   return true;
    569 }
    570 
    571 void MipsGNULDBackend::updateAddend(Relocation& pReloc,
    572                                    const LDSymbol& pInputSym,
    573                                    const Layout& pLayout) const
    574 {
    575   // Update value keep in addend if we meet a section symbol
    576   if(pReloc.symInfo()->type() == ResolveInfo::Section) {
    577     pReloc.setAddend(pLayout.getOutputOffset(
    578                      *pInputSym.fragRef()) + pReloc.addend());
    579   }
    580 }
    581 
    582 void MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
    583                                       const LDSymbol& pInputSym,
    584                                       MCLinker& pLinker,
    585                                       const MCLDInfo& pLDInfo,
    586                                       const Output& pOutput)
    587 {
    588   ResolveInfo* rsym = pReloc.symInfo();
    589 
    590   updateAddend(pReloc, pInputSym, pLinker.getLayout());
    591 
    592   switch (pReloc.type()){
    593     case llvm::ELF::R_MIPS_NONE:
    594     case llvm::ELF::R_MIPS_16:
    595       break;
    596     case llvm::ELF::R_MIPS_32:
    597       if (Output::DynObj == pOutput.type()) {
    598         // TODO: (simon) The gold linker does not create an entry in .rel.dyn
    599         // section if the symbol section flags contains SHF_EXECINSTR.
    600         // 1. Find the reason of this condition.
    601         // 2. Check this condition here.
    602         if (NULL == m_pRelDyn)
    603           createRelDyn(pLinker, pOutput);
    604 
    605         m_pRelDyn->reserveEntry(*m_pRelocFactory);
    606         rsym->setReserved(rsym->reserved() | ReserveRel);
    607       }
    608       break;
    609     case llvm::ELF::R_MIPS_REL32:
    610     case llvm::ELF::R_MIPS_26:
    611     case llvm::ELF::R_MIPS_HI16:
    612     case llvm::ELF::R_MIPS_LO16:
    613     case llvm::ELF::R_MIPS_PC16:
    614     case llvm::ELF::R_MIPS_SHIFT5:
    615     case llvm::ELF::R_MIPS_SHIFT6:
    616     case llvm::ELF::R_MIPS_64:
    617     case llvm::ELF::R_MIPS_GOT_PAGE:
    618     case llvm::ELF::R_MIPS_GOT_OFST:
    619     case llvm::ELF::R_MIPS_SUB:
    620     case llvm::ELF::R_MIPS_INSERT_A:
    621     case llvm::ELF::R_MIPS_INSERT_B:
    622     case llvm::ELF::R_MIPS_DELETE:
    623     case llvm::ELF::R_MIPS_HIGHER:
    624     case llvm::ELF::R_MIPS_HIGHEST:
    625     case llvm::ELF::R_MIPS_SCN_DISP:
    626     case llvm::ELF::R_MIPS_REL16:
    627     case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
    628     case llvm::ELF::R_MIPS_PJUMP:
    629     case llvm::ELF::R_MIPS_RELGOT:
    630     case llvm::ELF::R_MIPS_JALR:
    631     case llvm::ELF::R_MIPS_GLOB_DAT:
    632     case llvm::ELF::R_MIPS_COPY:
    633     case llvm::ELF::R_MIPS_JUMP_SLOT:
    634       break;
    635     case llvm::ELF::R_MIPS_GOT16:
    636     case llvm::ELF::R_MIPS_CALL16:
    637       if (NULL == m_pGOT)
    638         createGOT(pLinker, pOutput);
    639 
    640       if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
    641         m_pGOT->reserveLocalEntry();
    642         rsym->setReserved(rsym->reserved() | ReserveGot);
    643         m_LocalGOTSyms.push_back(rsym->outSymbol());
    644       }
    645       break;
    646     case llvm::ELF::R_MIPS_GPREL32:
    647     case llvm::ELF::R_MIPS_GPREL16:
    648     case llvm::ELF::R_MIPS_LITERAL:
    649       break;
    650     case llvm::ELF::R_MIPS_GOT_DISP:
    651     case llvm::ELF::R_MIPS_GOT_HI16:
    652     case llvm::ELF::R_MIPS_CALL_HI16:
    653     case llvm::ELF::R_MIPS_GOT_LO16:
    654     case llvm::ELF::R_MIPS_CALL_LO16:
    655       break;
    656     case llvm::ELF::R_MIPS_TLS_DTPMOD32:
    657     case llvm::ELF::R_MIPS_TLS_DTPREL32:
    658     case llvm::ELF::R_MIPS_TLS_DTPMOD64:
    659     case llvm::ELF::R_MIPS_TLS_DTPREL64:
    660     case llvm::ELF::R_MIPS_TLS_GD:
    661     case llvm::ELF::R_MIPS_TLS_LDM:
    662     case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
    663     case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
    664     case llvm::ELF::R_MIPS_TLS_GOTTPREL:
    665     case llvm::ELF::R_MIPS_TLS_TPREL32:
    666     case llvm::ELF::R_MIPS_TLS_TPREL64:
    667     case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
    668     case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
    669       break;
    670     default:
    671       llvm::report_fatal_error(llvm::Twine("Unknown relocation ") +
    672                                llvm::Twine(pReloc.type()) +
    673                                llvm::Twine("for the local symbol `") +
    674                                pReloc.symInfo()->name() +
    675                                llvm::Twine("'."));
    676   }
    677 }
    678 
    679 void MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
    680                                        const LDSymbol& pInputSym,
    681                                        MCLinker& pLinker,
    682                                        const MCLDInfo& pLDInfo,
    683                                        const Output& pOutput)
    684 {
    685   ResolveInfo* rsym = pReloc.symInfo();
    686 
    687   switch (pReloc.type()){
    688     case llvm::ELF::R_MIPS_NONE:
    689     case llvm::ELF::R_MIPS_INSERT_A:
    690     case llvm::ELF::R_MIPS_INSERT_B:
    691     case llvm::ELF::R_MIPS_DELETE:
    692     case llvm::ELF::R_MIPS_TLS_DTPMOD64:
    693     case llvm::ELF::R_MIPS_TLS_DTPREL64:
    694     case llvm::ELF::R_MIPS_REL16:
    695     case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
    696     case llvm::ELF::R_MIPS_PJUMP:
    697     case llvm::ELF::R_MIPS_RELGOT:
    698     case llvm::ELF::R_MIPS_TLS_TPREL64:
    699       break;
    700     case llvm::ELF::R_MIPS_32:
    701     case llvm::ELF::R_MIPS_64:
    702     case llvm::ELF::R_MIPS_HI16:
    703     case llvm::ELF::R_MIPS_LO16:
    704       if (isSymbolNeedsDynRel(*rsym, pOutput)) {
    705         if (NULL == m_pRelDyn)
    706           createRelDyn(pLinker, pOutput);
    707 
    708         m_pRelDyn->reserveEntry(*m_pRelocFactory);
    709         rsym->setReserved(rsym->reserved() | ReserveRel);
    710       }
    711       break;
    712     case llvm::ELF::R_MIPS_GOT16:
    713     case llvm::ELF::R_MIPS_CALL16:
    714     case llvm::ELF::R_MIPS_GOT_DISP:
    715     case llvm::ELF::R_MIPS_GOT_HI16:
    716     case llvm::ELF::R_MIPS_CALL_HI16:
    717     case llvm::ELF::R_MIPS_GOT_LO16:
    718     case llvm::ELF::R_MIPS_CALL_LO16:
    719     case llvm::ELF::R_MIPS_GOT_PAGE:
    720     case llvm::ELF::R_MIPS_GOT_OFST:
    721       if (NULL == m_pGOT)
    722         createGOT(pLinker, pOutput);
    723 
    724       if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
    725         m_pGOT->reserveGlobalEntry();
    726         rsym->setReserved(rsym->reserved() | ReserveGot);
    727         m_GlobalGOTSyms.push_back(rsym->outSymbol());
    728       }
    729       break;
    730     case llvm::ELF::R_MIPS_LITERAL:
    731     case llvm::ELF::R_MIPS_GPREL32:
    732       llvm::report_fatal_error(llvm::Twine("Relocation ") +
    733                                llvm::Twine(pReloc.type()) +
    734                                llvm::Twine(" is not defined for the "
    735                                            "global symbol `") +
    736                                pReloc.symInfo()->name() +
    737                                llvm::Twine("'."));
    738       break;
    739     case llvm::ELF::R_MIPS_GPREL16:
    740       break;
    741     case llvm::ELF::R_MIPS_26:
    742     case llvm::ELF::R_MIPS_PC16:
    743       break;
    744     case llvm::ELF::R_MIPS_16:
    745     case llvm::ELF::R_MIPS_SHIFT5:
    746     case llvm::ELF::R_MIPS_SHIFT6:
    747     case llvm::ELF::R_MIPS_SUB:
    748     case llvm::ELF::R_MIPS_HIGHER:
    749     case llvm::ELF::R_MIPS_HIGHEST:
    750     case llvm::ELF::R_MIPS_SCN_DISP:
    751       break;
    752     case llvm::ELF::R_MIPS_TLS_DTPREL32:
    753     case llvm::ELF::R_MIPS_TLS_GD:
    754     case llvm::ELF::R_MIPS_TLS_LDM:
    755     case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
    756     case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
    757     case llvm::ELF::R_MIPS_TLS_GOTTPREL:
    758     case llvm::ELF::R_MIPS_TLS_TPREL32:
    759     case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
    760     case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
    761       break;
    762     case llvm::ELF::R_MIPS_REL32:
    763       break;
    764     case llvm::ELF::R_MIPS_JALR:
    765       break;
    766     case llvm::ELF::R_MIPS_COPY:
    767     case llvm::ELF::R_MIPS_GLOB_DAT:
    768     case llvm::ELF::R_MIPS_JUMP_SLOT:
    769       llvm::report_fatal_error(llvm::Twine("Relocation ") +
    770                                llvm::Twine(pReloc.type()) +
    771                                llvm::Twine("for the global symbol `") +
    772                                pReloc.symInfo()->name() +
    773                                llvm::Twine("' should only be seen "
    774                                            "by the dynamic linker"));
    775       break;
    776     default:
    777       llvm::report_fatal_error(llvm::Twine("Unknown relocation ") +
    778                                llvm::Twine(pReloc.type()) +
    779                                llvm::Twine("for the global symbol `") +
    780                                pReloc.symInfo()->name() +
    781                                llvm::Twine("'."));
    782   }
    783 }
    784 
    785 bool MipsGNULDBackend::isSymbolNeedsPLT(ResolveInfo& pSym,
    786                                         const Output& pOutput) const
    787 {
    788   return (Output::DynObj == pOutput.type() &&
    789          ResolveInfo::Function == pSym.type() &&
    790          (pSym.isDyn() || pSym.isUndef()));
    791 }
    792 
    793 bool MipsGNULDBackend::isSymbolNeedsDynRel(ResolveInfo& pSym,
    794                                            const Output& pOutput) const
    795 {
    796   if(pSym.isUndef() && Output::Exec == pOutput.type())
    797     return false;
    798   if(pSym.isAbsolute())
    799     return false;
    800   if(Output::DynObj == pOutput.type())
    801     return true;
    802   if(pSym.isDyn() || pSym.isUndef())
    803     return true;
    804 
    805   return false;
    806 }
    807 
    808 void MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput)
    809 {
    810   ELFFileFormat* file_format = getOutputFormat(pOutput);
    811 
    812   LDSection& got = file_format->getGOT();
    813   m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got));
    814 
    815   // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
    816   if( m_pGOTSymbol != NULL ) {
    817     pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
    818                      "_GLOBAL_OFFSET_TABLE_",
    819                      false,
    820                      ResolveInfo::Object,
    821                      ResolveInfo::Define,
    822                      ResolveInfo::Local,
    823                      0x0, // size
    824                      0x0, // value
    825                      pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
    826                      ResolveInfo::Hidden);
    827   }
    828   else {
    829     m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
    830                      "_GLOBAL_OFFSET_TABLE_",
    831                      false,
    832                      ResolveInfo::Object,
    833                      ResolveInfo::Define,
    834                      ResolveInfo::Local,
    835                      0x0, // size
    836                      0x0, // value
    837                      pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
    838                      ResolveInfo::Hidden);
    839   }
    840 }
    841 
    842 void MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput)
    843 {
    844   ELFFileFormat* file_format = getOutputFormat(pOutput);
    845 
    846   // get .rel.dyn LDSection and create MCSectionData
    847   LDSection& reldyn = file_format->getRelDyn();
    848   // create MCSectionData and ARMRelDynSection
    849   m_pRelDyn = new OutputRelocSection(reldyn,
    850                                      pLinker.getOrCreateSectData(reldyn),
    851                                      8);
    852 }
    853 
    854 ELFFileFormat* MipsGNULDBackend::getOutputFormat(const Output& pOutput) const
    855 {
    856   switch (pOutput.type()) {
    857     case Output::DynObj:
    858       return getDynObjFileFormat();
    859     case Output::Exec:
    860       return getExecFileFormat();
    861     case Output::Object:
    862       return NULL;
    863     default:
    864       llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") +
    865                                llvm::Twine(pOutput.type()));
    866       return NULL;
    867   }
    868 }
    869 
    870 //===----------------------------------------------------------------------===//
    871 /// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
    872 ///
    873 static TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
    874                                             const std::string& pTriple)
    875 {
    876   llvm::Triple theTriple(pTriple);
    877   if (theTriple.isOSDarwin()) {
    878     assert(0 && "MachO linker is not supported yet");
    879   }
    880   if (theTriple.isOSWindows()) {
    881     assert(0 && "COFF linker is not supported yet");
    882   }
    883   return new MipsGNULDBackend();
    884 }
    885 
    886 } // namespace of mcld
    887 
    888 //=============================
    889 // Force static initialization.
    890 extern "C" void LLVMInitializeMipsLDBackend() {
    891   // Register the linker backend
    892   mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
    893                                                 mcld::createMipsLDBackend);
    894 }
    895