MipsLDBackend.cpp revision affc150dc44fab1911775a49636d0ce85333b634
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>
17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "Mips.h"
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsELFDynamic.h"
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsLDBackend.h"
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsRelocationFactory.h"
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum {
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // The original o32 abi.
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O32    = 0x00001000,
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // O32 extended to work on 64 bit architectures.
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O64    = 0x00002000,
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 32 bit mode.
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI32 = 0x00003000,
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 64 bit mode.
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI64 = 0x00004000
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend()
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_pRelocFactory(NULL),
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic(NULL),
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol(NULL),
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol(NULL)
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend()
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelocFactory)
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelocFactory;
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGOT)
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pGOT;
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pRelDyn)
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pRelDyn;
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pDynamic)
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynamic;
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Nothing to do because we do not support
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // any MIPS specific sections now.
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(MCLinker& pLinker)
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Set up .dynamic
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = NULL;
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  switch(pLinker.getLDInfo().output().type()) {
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::DynObj:
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      file_format = getDynObjFileFormat();
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::Exec:
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      file_format = getExecFileFormat();
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::Object:
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // TODO: not support yet
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  file_format->getDynamic().setFlag(llvm::ELF::SHF_ALLOC);
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
87affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput)
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // same name in input
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_GLOBAL_OFFSET_TABLE_",
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Object,
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Local,
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   NULL, // FragRef
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Hidden);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_gp_disp",
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Section,
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Absolute,
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   NULL, // FragRef
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Default);
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGpDispSymbol) {
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp);
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker)
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pRelocFactory) {
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory = new MipsRelocationFactory(1024, *this);
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory->setLayout(pLinker.getLayout());
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* MipsGNULDBackend::getRelocFactory()
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelocFactory);
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pRelocFactory;
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanRelocation(Relocation& pReloc,
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const LDSymbol& pInputSym,
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      MCLinker& pLinker,
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const MCLDInfo& pLDInfo,
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      const Output& pOutput,
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      const LDSection& pSection)
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != pSection.getLink());
145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) {
146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (rsym->isLocal()) {
147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      updateAddend(pReloc, pInputSym, pLinker.getLayout());
148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // that a .got section is needed.
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pGOT && NULL != m_pGOTSymbol) {
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (rsym == m_pGOTSymbol->resolveInfo()) {
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      createGOT(pLinker, pOutput);
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Skip relocation against _gp_disp
161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (strcmp("_gp_disp", pInputSym.name()) == 0)
162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // We test isLocal or if pInputSym is not a dynamic symbol
165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn()
166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Don't put undef symbols into local entries.
167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if ((rsym->isLocal() || !isDynamicSymbol(pInputSym, pOutput) ||
168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !rsym->isDyn()) && !rsym->isUndef())
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t MipsGNULDBackend::machine() const
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EM_MIPS;
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::OSABI() const
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::ELFOSABI_NONE;
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::ABIVersion() const
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::flags() const
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: (simon) The correct flag's set depend on command line
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // arguments and flags from input .o files.
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EF_MIPS_ARCH_32R2 |
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_NOREORDER |
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_PIC |
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_CPIC |
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         E_MIPS_ABI_O32;
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isLittleEndian() const
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Now we support little endian (mipsel) target only.
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int MipsGNULDBackend::bitclass() const
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 32;
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
211affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t MipsGNULDBackend::defaultTextSegmentAddr() const
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return 0x80000;
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(const Output& pOutput,
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const MCLDInfo& pInfo,
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MCLinker& pLinker)
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // when building shared object, the .got section is must.
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pOutput.type() == Output::DynObj && NULL == m_pGOT) {
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      createGOT(pLinker, pOutput);
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(const Output& pOutput,
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const MCLDInfo& pInfo,
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    MCLinker& pLinker)
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic()
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic = new MipsELFDynamic(*this);
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput,
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           const LDSection& pSection,
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           const MCLDInfo& pInfo,
253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                           const Layout& pLayout,
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           MemoryRegion& pRegion) const
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFFileFormat* file_format = getOutputFormat(pOutput);
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(file_format->getGOT())) {
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint64_t result = m_pGOT->emit(pRegion);
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  fatal(diag::unrecognized_output_sectoin)
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << pSection.name()
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << "mclinker@googlegroups.com";
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
272affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return std::find(m_GlobalGOTSyms.begin(),
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitDynamicSymbol - emit dynamic symbol.
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         Output& pOutput,
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         LDSymbol& pSymbol,
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         const Layout& pLayout,
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         char* strtab,
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         size_t strtabsize,
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                         size_t symtabIdx)
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // maintain output's symbol and index map
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(&pSymbol, sym_exist);
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(symtabIdx);
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: check the endian between host and target
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out symbol
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_name  = strtabsize;
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_value = pSymbol.value();
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_size  = getSymbolSize(pSymbol);
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_info  = getSymbolInfo(pSymbol);
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_other = pSymbol.visibility();
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sym32.st_shndx = getSymbolShndx(pSymbol, pLayout);
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out string
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strcpy((strtab + strtabsize), pSymbol.name());
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(Output& pOutput,
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        SymbolCategory& pSymbols,
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        const Layout& pLayout,
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        const MCLDInfo& pLDInfo)
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pOutput.hasMemArea());
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& hash_sect   = file_format->getHashTab();
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           symtab_sect.size());
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           strtab_sect.size());
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(),
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         hash_sect.size());
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(),
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                        dyn_sect.size());
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_name  = 0;
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_value = 0;
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_size  = 0;
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_info  = 0;
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_other = 0;
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_shndx = 0;
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add index 0 symbol into SymIndexMap
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(NULL, sym_exist);
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(0);
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit of .dynsym, and .dynstr except GOT entries
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (SymbolCategory::iterator symbol = pSymbols.begin(),
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       sym_end = pSymbols.end(); symbol != sym_end; ++symbol) {
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!isDynamicSymbol(**symbol, pOutput))
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (isGlobalGOTSymbol(**symbol))
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      strtabsize, symtabIdx);
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strtabsize += (*symbol)->nameSize() + 1;
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit global GOT
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol_end = m_GlobalGOTSyms.end();
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol != symbol_end; ++symbol) {
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // Make sure this golbal GOT entry is a dynamic symbol.
378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // If not, something is wrong earlier when putting this symbol into
379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //  global GOT.
380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!isDynamicSymbol(**symbol, pOutput))
381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::mips_got_symbol) << (*symbol)->name();
382affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      strtabsize, symtabIdx);
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strtabsize += (*symbol)->nameSize() + 1;
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Rules:
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   1. ignore --no-add-needed
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   2. force count in --no-as-needed
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   3. judge --as-needed
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (Input::DynObj == (*input)->type()) {
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // --add-needed
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if ((*input)->attribute()->isAddNeeded()) {
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // --no-as-needed
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (!(*input)->attribute()->isAsNeeded()) {
4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strcpy((strtab + strtabsize), (*input)->name().c_str());
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strtabsize += (*input)->name().size() + 1;
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ++dt_need;
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // --as-needed
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        else if ((*input)->isNeeded()) {
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strcpy((strtab + strtabsize), (*input)->name().c_str());
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strtabsize += (*input)->name().size() + 1;
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ++dt_need;
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // for
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit soname
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Output::DynObj == pOutput.type())
424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().applyEntries(pLDInfo, *file_format);
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().emit(dyn_sect, *dyn_region);
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strcpy((strtab + strtabsize), pOutput.name().c_str());
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtabsize += pOutput.name().size() + 1;
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit hash table
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: this verion only emit SVR4 hash section.
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //        Please add GNU new hash section
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* word_array = (uint32_t*)hash_region->start();
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nbucket = getHashBucketCount(symtabIdx, false);
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nchain  = symtabIdx;
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bzero((void*)bucket, nbucket);
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  StringHash<ELF> hash_func;
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t bucket_pos = hash_func(name) % nbucket;
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    chain[sym_idx] = bucket[bucket_pos];
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bucket[bucket_pos] = sym_idx;
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT()
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn()
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const Output& pOutput,
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const LDSection& pSectHdr,
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const MCLDInfo& pInfo) const
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFFileFormat* file_format = getOutputFormat(pOutput);
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getGOT())
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_DATA;
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
499affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput)
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0);
502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sections.
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: If the order of common symbols is defined, then sort common symbols
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // std::sort(com_sym, com_end, some kind of order);
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create corresponding BSS LDSection
523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* bss_sect = &pLinker.getOrCreateOutputSectHdr(".bss",
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::BSS,
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHT_NOBITS,
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* tbss_sect = &pLinker.getOrCreateOutputSectHdr(
529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   ".tbss",
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::BSS,
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHT_NOBITS,
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: .sbss amd .lbss currently unused.
535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /*
536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* sbss_sect = &pLinker.getOrCreateOutputSectHdr(
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   ".sbss",
538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC |
541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_MIPS_GPREL);
542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* lbss_sect = &pLinker.getOrCreateOutputSectHdr(
544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   ".lbss",
545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC |
548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_MIPS_LOCAL);
549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  */
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != bss_sect && NULL != tbss_sect);
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create corresponding BSS MCSectionData
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::MCSectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect);
555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::MCSectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect);
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t bss_offset  = bss_sect->size();
559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t tbss_offset = tbss_sect->size();
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all local common symbols
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.localEnd();
563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (ResolveInfo::Common == (*com_sym)->desc()) {
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We have to reset the description of the symbol here. When doing
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // incremental linking, the output relocatable object may have common
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // symbols. Therefore, we can not treat common symbols as normal symbols
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when emitting the regular name pools. We must change the symbols'
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // description here.
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        tbss_offset += pLinker.getLayout().appendFragment(*frag,
578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                          tbss_sect_data,
579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                          (*com_sym)->value());
580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // FIXME: how to identify small and large common symbols?
582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      else {
583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        bss_offset += pLinker.getLayout().appendFragment(*frag,
584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                         bss_sect_data,
585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                         (*com_sym)->value());
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all global common symbols
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.commonEnd();
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // We have to reset the description of the symbol here. When doing
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // incremental linking, the output relocatable object may have common
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // symbols. Therefore, we can not treat common symbols as normal symbols
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // when emitting the regular name pools. We must change the symbols'
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // description here.
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      tbss_offset += pLinker.getLayout().appendFragment(*frag,
605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                        tbss_sect_data,
606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                        (*com_sym)->value());
607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // FIXME: how to identify small and large common symbols?
609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      bss_offset += pLinker.getLayout().appendFragment(*frag,
611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                       bss_sect_data,
612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                       (*com_sym)->value());
613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bss_sect->setSize(bss_offset);
617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  tbss_sect->setSize(tbss_offset);
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symbol_list.changeCommonsToGlobal();
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::updateAddend(Relocation& pReloc,
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const LDSymbol& pInputSym,
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const Layout& pLayout) const
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Update value keep in addend if we meet a section symbol
627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pReloc.symInfo()->type() == ResolveInfo::Section) {
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pReloc.setAddend(pLayout.getOutputOffset(
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     *pInputSym.fragRef()) + pReloc.addend());
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const LDSymbol& pInputSym,
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      MCLinker& pLinker,
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const MCLDInfo& pLDInfo,
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                      const Output& pOutput)
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  updateAddend(pReloc, pInputSym, pLinker.getLayout());
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (Output::DynObj == pOutput.type()) {
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // TODO: (simon) The gold linker does not create an entry in .rel.dyn
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // section if the symbol section flags contains SHF_EXECINSTR.
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 1. Find the reason of this condition.
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 2. Check this condition here.
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (NULL == m_pRelDyn)
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createRelDyn(pLinker, pOutput);
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry (as if it needs an entry).
660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Actually we don't allocate an GOT entry.
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pGOT)
662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          createGOT(pLinker, pOutput);
663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL == m_pGOT)
6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createGOT(pLinker, pOutput);
6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // For got16 section based relocations, we need to reserve got entries.
698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->type() == ResolveInfo::Section) {
699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->reserveLocalEntry();
700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry
701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        return;
703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveLocalEntry();
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
708affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry
709affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD32:
7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
737affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unknown_relocation) << (int)pReloc.type()
738affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      << pReloc.symInfo()->name();
7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const LDSymbol& pInputSym,
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       MCLinker& pLinker,
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const MCLDInfo& pLDInfo,
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const Output& pOutput)
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
767affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (symbolNeedsDynRel(*rsym, false, pLDInfo, pOutput, true)) {
7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (NULL == m_pRelDyn)
7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          createRelDyn(pLinker, pOutput);
7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
773affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
774affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a global GOT entry (as if it needs an entry).
775affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Actually we don't allocate an GOT entry.
776affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == m_pGOT)
777affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          createGOT(pLinker, pOutput);
778affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setGlobal(rsym);
7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
7895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL == m_pGOT)
7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        createGOT(pLinker, pOutput);
7925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveGlobalEntry();
7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_GlobalGOTSyms.push_back(rsym->outSymbol());
797affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a global GOT entry
798affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setGlobal(rsym);
7995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
803affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::invalid_global_relocation) << (int)pReloc.type()
804affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             << pReloc.symInfo()->name();
8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
836affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::dynamic_relocation) << (int)pReloc.type();
8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
839affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unknown_relocation) << (int)pReloc.type()
840affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      << pReloc.symInfo()->name();
8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput)
8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& got = file_format->getGOT();
8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got));
8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if ( m_pGOTSymbol != NULL ) {
8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput)
8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat(pOutput);
8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get .rel.dyn LDSection and create MCSectionData
8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& reldyn = file_format->getRelDyn();
8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create MCSectionData and ARMRelDynSection
8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRelDyn = new OutputRelocSection(reldyn,
8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     pLinker.getOrCreateSectData(reldyn),
8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     8);
8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                            const std::string& pTriple)
8955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::Triple theTriple(pTriple);
8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSDarwin()) {
8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (theTriple.isOSWindows()) {
9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return new MipsGNULDBackend();
9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
9075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//=============================
9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeMipsLDBackend() {
9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                mcld::createMipsLDBackend);
9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
915