MipsLDBackend.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsLDBackend.cpp --------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "Mips.h"
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsELFDynamic.h"
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsLDBackend.h"
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsRelocationFactory.h"
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum {
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // The original o32 abi.
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O32    = 0x00001000,
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // O32 extended to work on 64 bit architectures.
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O64    = 0x00002000,
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 32 bit mode.
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI32 = 0x00003000,
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 64 bit mode.
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI64 = 0x00004000
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend()
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_pRelocFactory(NULL),
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic(NULL),
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol(NULL),
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol(NULL)
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend()
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelocFactory)
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelocFactory;
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGOT)
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pGOT;
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelDyn)
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelDyn;
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pDynamic)
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynamic;
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Nothing to do because we do not support
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // any MIPS specific sections now.
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(MCLinker& pLinker)
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Nothing to do because we do not support
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // any MIPS specific sections now.
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker)
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // same name in input
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_GLOBAL_OFFSET_TABLE_",
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Object,
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Local,
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   NULL, // FragRef
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Hidden);
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_gp_disp",
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Section,
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Absolute,
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   NULL, // FragRef
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Default);
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGpDispSymbol) {
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker)
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pRelocFactory) {
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory = new MipsRelocationFactory(1024, *this);
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory->setLayout(pLinker.getLayout());
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* MipsGNULDBackend::getRelocFactory()
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelocFactory);
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pRelocFactory;
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanRelocation(Relocation& pReloc,
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const LDSymbol& pInputSym,
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      MCLinker& pLinker,
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const MCLDInfo& pLDInfo,
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // that a .got section is needed.
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pGOT && NULL != m_pGOTSymbol) {
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (rsym == m_pGOTSymbol->resolveInfo()) {
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      createGOT(pLinker, pOutput);
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (rsym->isLocal())
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t MipsGNULDBackend::machine() const
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EM_MIPS;
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::OSABI() const
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::ELFOSABI_NONE;
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::ABIVersion() const
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::flags() const
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: (simon) The correct flag's set depend on command line
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // arguments and flags from input .o files.
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EF_MIPS_ARCH_32R2 |
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_NOREORDER |
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_PIC |
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_CPIC |
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         E_MIPS_ABI_O32;
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isLittleEndian() const
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Now we support little endian (mipsel) target only.
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int MipsGNULDBackend::bitclass() const
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 32;
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(const Output& pOutput,
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const MCLDInfo& pInfo,
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MCLinker& pLinker)
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // when building shared object, the .got section is must.
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pOutput.type() == Output::DynObj && NULL == m_pGOT) {
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      createGOT(pLinker, pOutput);
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(const Output& pOutput,
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const MCLDInfo& pInfo,
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    MCLinker& pLinker)
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit program headers
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec)
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    emitProgramHdrs(pLinker.getLDInfo().output());
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic()
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic = new MipsELFDynamic(*this);
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput,
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           const LDSection& pSection,
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           const MCLDInfo& pInfo,
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           MemoryRegion& pRegion) const
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(file_format->getGOT())) {
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint64_t result = m_pGOT->emit(pRegion);
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::report_fatal_error(llvm::Twine("Unable to emit section `") +
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           pSection.name() +
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           llvm::Twine("'.\n"));
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isGOTSymbol - return true if the symbol is the GOT entry.
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isGOTSymbol(const LDSymbol& pSymbol) const
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return std::find(m_LocalGOTSyms.begin(),
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   m_LocalGOTSyms.end(), &pSymbol) != m_LocalGOTSyms.end() ||
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         std::find(m_GlobalGOTSyms.begin(),
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitDynamicSymbol - emit dynamic symbol.
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         Output& pOutput,
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         LDSymbol& pSymbol,
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         const Layout& pLayout,
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         char* strtab,
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         size_t strtabsize,
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         size_t symtabIdx)
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // maintain output's symbol and index map
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(&pSymbol, sym_exist);
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(symtabIdx);
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: check the endian between host and target
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out symbol
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_name  = strtabsize;
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_value = pSymbol.value();
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_size  = getSymbolSize(pSymbol);
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_info  = getSymbolInfo(pSymbol);
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_other = pSymbol.visibility();
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_shndx = getSymbolShndx(pSymbol, pLayout);
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out string
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strcpy((strtab + strtabsize), pSymbol.name());
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(Output& pOutput,
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        SymbolCategory& pSymbols,
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        const Layout& pLayout,
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        const MCLDInfo& pLDInfo)
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pOutput.hasMemArea());
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& hash_sect   = file_format->getHashTab();
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           symtab_sect.size());
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           strtab_sect.size());
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(),
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         hash_sect.size());
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(),
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                        dyn_sect.size());
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_name  = 0;
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_value = 0;
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_size  = 0;
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_info  = 0;
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_other = 0;
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_shndx = 0;
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add index 0 symbol into SymIndexMap
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(NULL, sym_exist);
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(0);
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit of .dynsym, and .dynstr except GOT entries
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (SymbolCategory::iterator symbol = pSymbols.begin(),
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       sym_end = pSymbols.end(); symbol != sym_end; ++symbol) {
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!isDynamicSymbol(**symbol, pOutput))
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isGOTSymbol(**symbol))
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      strtabsize, symtabIdx);
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strtabsize += (*symbol)->nameSize() + 1;
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit global GOT
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol_end = m_GlobalGOTSyms.end();
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol != symbol_end; ++symbol) {
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      strtabsize, symtabIdx);
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strtabsize += (*symbol)->nameSize() + 1;
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Rules:
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   1. ignore --no-add-needed
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   2. force count in --no-as-needed
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   3. judge --as-needed
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (Input::DynObj == (*input)->type()) {
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // --add-needed
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if ((*input)->attribute()->isAddNeeded()) {
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // --no-as-needed
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (!(*input)->attribute()->isAsNeeded()) {
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strcpy((strtab + strtabsize), (*input)->name().c_str());
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strtabsize += (*input)->name().size() + 1;
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ++dt_need;
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // --as-needed
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        else if ((*input)->isNeeded()) {
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strcpy((strtab + strtabsize), (*input)->name().c_str());
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strtabsize += (*input)->name().size() + 1;
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ++dt_need;
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // for
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit soname
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().applySoname(strtabsize);
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().applyEntries(pLDInfo, *file_format);
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().emit(dyn_sect, *dyn_region);
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strcpy((strtab + strtabsize), pOutput.name().c_str());
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtabsize += pOutput.name().size() + 1;
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit hash table
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: this verion only emit SVR4 hash section.
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //        Please add GNU new hash section
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* word_array = (uint32_t*)hash_region->start();
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nbucket = getHashBucketCount(symtabIdx, false);
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nchain  = symtabIdx;
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bzero((void*)bucket, nbucket);
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  StringHash<ELF> hash_func;
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t bucket_pos = hash_func(name) % nbucket;
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    chain[sym_idx] = bucket[bucket_pos];
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bucket[bucket_pos] = sym_idx;
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT()
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn()
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const Output& pOutput,
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        const LDSection& pSectHdr) const
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getGOT())
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_DATA;
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// If the symbol's reserved field is not zero, MCLinker will call back this
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// function to ask the final value of the symbol
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSymbol == m_pGpDispSymbol) {
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0);
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sections.
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // SymbolCategory contains all symbols that must emit to the output files.
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // We are not like Google gold linker, we don't remember symbols before symbol
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolution. All symbols in SymbolCategory are already resolved. Therefore, we
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // don't need to care about some symbols may be changed its category due to symbol
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolution.
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // addralign := max value of all common symbols
4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t addralign = 0x0;
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Due to the visibility, some common symbols may be forcefully local.
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd();
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (ResolveInfo::Common == (*com_sym)->desc()) {
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if ((*com_sym)->value() > addralign)
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        addralign = (*com_sym)->value();
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // global common symbols.
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.commonEnd();
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((*com_sym)->value() > addralign)
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      addralign = (*com_sym)->value();
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: If the order of common symbols is defined, then sort common symbols
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // com_sym = symbol_list.commonBegin();
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // std::sort(com_sym, com_end, some kind of order);
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create corresponding BSS LDSection
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* bss_sect_hdr = NULL;
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   ".tbss",
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::BSS,
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHT_NOBITS,
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::BSS,
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHT_NOBITS,
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create corresponding BSS MCSectionData
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != bss_sect_hdr);
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr);
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all common symbols
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t offset = bss_sect_hdr->size();
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all local common symbols
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.localEnd();
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (ResolveInfo::Common == (*com_sym)->desc()) {
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      alignAddress(offset, (*com_sym)->value());
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We have to reset the description of the symbol here. When doing
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // incremental linking, the output relocatable object may have common
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // symbols. Therefore, we can not treat common symbols as normal symbols
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when emitting the regular name pools. We must change the symbols'
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // description here.
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section);
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      offset += (*com_sym)->size();
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all global common symbols
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.commonEnd();
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    alignAddress(offset, (*com_sym)->value());
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // We have to reset the description of the symbol here. When doing
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // incremental linking, the output relocatable object may have common
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // symbols. Therefore, we can not treat common symbols as normal symbols
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // when emitting the regular name pools. We must change the symbols'
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // description here.
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section);
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset += (*com_sym)->size();
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bss_sect_hdr->setSize(offset);
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symbol_list.changeCommonsToGlobal();
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::updateAddend(Relocation& pReloc,
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const LDSymbol& pInputSym,
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const Layout& pLayout) const
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Update value keep in addend if we meet a section symbol
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pReloc.symInfo()->type() == ResolveInfo::Section) {
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pReloc.setAddend(pLayout.getOutputOffset(
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     *pInputSym.fragRef()) + pReloc.addend());
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const LDSymbol& pInputSym,
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      MCLinker& pLinker,
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const MCLDInfo& pLDInfo,
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  updateAddend(pReloc, pInputSym, pLinker.getLayout());
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (Output::DynObj == pOutput.type()) {
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // TODO: (simon) The gold linker does not create an entry in .rel.dyn
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // section if the symbol section flags contains SHF_EXECINSTR.
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 1. Find the reason of this condition.
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 2. Check this condition here.
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (NULL == m_pRelDyn)
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createRelDyn(pLinker, pOutput);
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL == m_pGOT)
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createGOT(pLinker, pOutput);
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveLocalEntry();
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_LocalGOTSyms.push_back(rsym->outSymbol());
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD32:
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("Unknown relocation ") +
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(pReloc.type()) +
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("for the local symbol `") +
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               pReloc.symInfo()->name() +
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("'."));
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const LDSymbol& pInputSym,
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       MCLinker& pLinker,
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const MCLDInfo& pLDInfo,
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const Output& pOutput)
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (isSymbolNeedsDynRel(*rsym, pOutput)) {
7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (NULL == m_pRelDyn)
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createRelDyn(pLinker, pOutput);
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL == m_pGOT)
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createGOT(pLinker, pOutput);
7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveGlobalEntry();
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_GlobalGOTSyms.push_back(rsym->outSymbol());
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("Relocation ") +
7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(pReloc.type()) +
7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(" is not defined for the "
7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           "global symbol `") +
7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               pReloc.symInfo()->name() +
7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("'."));
7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("Relocation ") +
7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(pReloc.type()) +
7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("for the global symbol `") +
7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               pReloc.symInfo()->name() +
7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("' should only be seen "
7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           "by the dynamic linker"));
7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("Unknown relocation ") +
7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(pReloc.type()) +
7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("for the global symbol `") +
7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               pReloc.symInfo()->name() +
7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine("'."));
7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isSymbolNeedsPLT(ResolveInfo& pSym,
7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        const Output& pOutput) const
7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (Output::DynObj == pOutput.type() &&
7895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         ResolveInfo::Function == pSym.type() &&
7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         (pSym.isDyn() || pSym.isUndef()));
7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isSymbolNeedsDynRel(ResolveInfo& pSym,
7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           const Output& pOutput) const
7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pSym.isUndef() && Output::Exec == pOutput.type())
7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
7985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pSym.isAbsolute())
7995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(Output::DynObj == pOutput.type())
8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(pSym.isDyn() || pSym.isUndef())
8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
8045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput)
8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& got = file_format->getGOT();
8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got));
8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if( m_pGOTSymbol != NULL ) {
8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput)
8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get .rel.dyn LDSection and create MCSectionData
8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& reldyn = file_format->getRelDyn();
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and ARMRelDynSection
8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelDyn = new OutputRelocSection(reldyn,
8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(reldyn),
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFFileFormat* MipsGNULDBackend::getOutputFormat(const Output& pOutput) const
8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pOutput.type()) {
8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::DynObj:
8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return getDynObjFileFormat();
8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Exec:
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return getExecFileFormat();
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Object:
8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") +
8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                               llvm::Twine(pOutput.type()));
8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                            const std::string& pTriple)
8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::Triple theTriple(pTriple);
8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSDarwin()) {
8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSWindows()) {
8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return new MipsGNULDBackend();
8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=============================
8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeMipsLDBackend() {
8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                mcld::createMipsLDBackend);
8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
895