MipsLDBackend.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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//===----------------------------------------------------------------------===//
9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "Mips.h"
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsELFDynamic.h"
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsLDBackend.h"
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsRelocationFactory.h"
13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h>
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum {
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // The original o32 abi.
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O32    = 0x00001000,
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // O32 extended to work on 64 bit architectures.
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O64    = 0x00002000,
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 32 bit mode.
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI32 = 0x00003000,
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 64 bit mode.
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI64 = 0x00004000
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// MipsGNULDBackend
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig)
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : GNULDBackend(pConfig),
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRelocFactory(NULL),
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic(NULL),
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol(NULL),
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol(NULL)
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend()
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelocFactory;
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pGOT;
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelDyn;
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynamic;
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& got = file_format->getGOT();
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOT = new MipsGOT(got);
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .rel.dyn
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& reldyn = file_format->getRelDyn();
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRelDyn = new OutputRelocSection(pModule,
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       reldyn,
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       getRelEntrySize());
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::initTargetSymbols(FragmentLinker& pLinker)
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // same name in input
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::AsRefered, FragmentLinker::Resolve>(
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_GLOBAL_OFFSET_TABLE_",
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Object,
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Local,
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   FragmentRef::Null(), // FragRef
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Hidden);
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pGpDispSymbol = pLinker.defineSymbol<FragmentLinker::AsRefered, FragmentLinker::Resolve>(
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   "_gp_disp",
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   false,
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Section,
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Define,
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Absolute,
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // size
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   0x0,  // value
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   FragmentRef::Null(), // FragRef
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   ResolveInfo::Default);
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != m_pGpDispSymbol) {
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp);
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::initRelocFactory(const FragmentLinker& pLinker)
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pRelocFactory) {
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelocFactory = new MipsRelocationFactory(1024, *this);
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRelocFactory->setFragmentLinker(pLinker);
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* MipsGNULDBackend::getRelocFactory()
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelocFactory);
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pRelocFactory;
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanRelocation(Relocation& pReloc,
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      FragmentLinker& pLinker,
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      Module& pModule,
131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      const LDSection& pSection)
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // rsym - The relocation target symbol
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Skip relocation against _gp_disp
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != m_pGpDispSymbol) {
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (pReloc.symInfo() == m_pGpDispSymbol->resolveInfo())
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pReloc.updateAddend();
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (pSection.flag() & llvm::ELF::SHF_ALLOC))
146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // We test isLocal or if pInputSym is not a dynamic symbol
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn()
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Don't put undef symbols into local entries.
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if ((rsym->isLocal() || !isDynamicSymbol(*rsym) ||
152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !rsym->isDyn()) && !rsym->isUndef())
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    scanLocalReloc(pReloc, pLinker);
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    scanGlobalReloc(pReloc, pLinker);
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // check if we shoule issue undefined reference for the relocation target
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak())
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::undefined_reference) << rsym->name();
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if ((rsym->reserved() & ReserveRel) != 0x0) {
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set hasTextRelSection if needed
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    checkAndSetHasTextRel(pSection);
16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t MipsGNULDBackend::machine() const
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EM_MIPS;
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::OSABI() const
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::ELFOSABI_NONE;
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::ABIVersion() const
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::flags() const
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: (simon) The correct flag's set depend on command line
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // arguments and flags from input .o files.
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EF_MIPS_ARCH_32R2 |
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_NOREORDER |
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_PIC |
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_CPIC |
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         E_MIPS_ABI_O32;
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isLittleEndian() const
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Now we support little endian (mipsel) target only.
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int MipsGNULDBackend::bitclass() const
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 32;
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t MipsGNULDBackend::defaultTextSegmentAddr() const
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return 0x80000;
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::abiPageSize() const
211cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().maxPageSize() > 0)
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return config().options().maxPageSize();
214cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  else
215cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return static_cast<uint64_t>(0x10000);
216cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
217cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(FragmentLinker& pLinker)
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set .got size
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // when building shared object, the .got section is must.
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::DynObj == config().codeGenType() ||
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pGOT->hasGOT1() ||
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        NULL != m_pGOTSymbol) {
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->finalizeSectionSize();
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      defineGOTSymbol(pLinker);
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .rel.dyn size
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!m_pRelDyn->empty())
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pRelDyn->finalizeSectionSize();
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(Module& pModule,
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    FragmentLinker& pLinker)
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic()
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic = new MipsELFDynamic(*this);
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection,
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           MemoryRegion& pRegion) const
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(file_format->getGOT())) {
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint64_t result = m_pGOT->emit(pRegion);
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  fatal(diag::unrecognized_output_sectoin)
272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << pSection.name()
273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << "mclinker@googlegroups.com";
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
277affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return std::find(m_GlobalGOTSyms.begin(),
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sizeNamePools - compute the size of regular name pools
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab,
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab.
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::sizeNamePools(const Module& pModule, bool pIsStaticLink)
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // number of entries in symbol tables starts from 1 to hold the special entry
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t symtab = 1;
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t dynsym = pIsStaticLink ? 0 : 1;
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // size of string tables starts from 1 to hold the null character in their
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // first byte
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t strtab = 1;
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t dynstr = pIsStaticLink ? 0 : 1;
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t shstrtab = 1;
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t hash   = 0;
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// compute the size of .symtab, .dynsym and .strtab
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symbol;
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const Module::SymbolTable& symbols = pModule.getSymbolTable();
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t str_size = 0;
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of symbols in Local and File category
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symEnd = symbols.localEnd();
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of symbols in TLS category
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = symbols.tlsEnd();
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink) {
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of the reset of symbols
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = pModule.sym_end();
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(config().codeGenType()) {
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // compute size of .dynstr and .hash
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // soname
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!pIsStaticLink)
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += pModule.name().size() + 1;
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /** fall through **/
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec: {
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // add DT_NEED strings into .dynstr and .dynamic
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // Rules:
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      //   1. ignore --no-add-needed
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      //   2. force count in --no-as-needed
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      //   3. judge --as-needed
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!pIsStaticLink) {
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        Module::const_lib_iterator lib, libEnd = pModule.lib_end();
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          // --add-needed
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if ((*lib)->attribute()->isAddNeeded()) {
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // --no-as-needed
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            if (!(*lib)->attribute()->isAsNeeded()) {
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynstr += (*lib)->name().size() + 1;
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynamic().reserveNeedEntry();
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // --as-needed
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            else if ((*lib)->isNeeded()) {
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynstr += (*lib)->name().size() + 1;
37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynamic().reserveNeedEntry();
37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // compute .hash
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Both Elf32_Word and Elf64_Word are 4 bytes
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao               sizeof(llvm::ELF::Elf32_Word);
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set size
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (32 == bitclass())
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getDynStrTab().setSize(dynstr);
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getHashTab().setSize(hash);
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /* fall through */
39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (32 == bitclass())
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getStrTab().setSize(strtab);
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default: {
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::fatal_illegal_codegen_type) << pModule.name();
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of switch
40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// reserve fixed entries in the .dynamic section.
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LinkerConfig::Exec == config().codeGenType()) {
41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Because some entries in .dynamic section need information of .dynsym,
41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // entries until we get the size of the sections mentioned above
41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dynamic().reserveEntries(config(), *file_format);
41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    file_format->getDynamic().setSize(dynamic().numOfBytes());
42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// compute the size of .shstrtab section.
42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_iterator sect, sectEnd = pModule.end();
42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // StackNote sections will always be in output!
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (0 != (*sect)->size() || LDFileFormat::StackNote == (*sect)->kind()) {
42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      shstrtab += ((*sect)->name().size() + 1);
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  shstrtab += (strlen(".shstrtab") + 1);
43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file_format->getShStrTab().setSize(shstrtab);
43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol
43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym,
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    LDSymbol& pSymbol,
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    char* pStrtab,
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    size_t pStrtabsize,
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    size_t pSymtabIdx)
44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != pSymbol.type() ||
44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          &pSymbol == m_pGpDispSymbol) {
44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = pStrtabsize;
44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     strcpy((pStrtab + pStrtabsize), pSymbol.name());
45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   else {
45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = 0;
45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
45422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(const Module& pModule,
46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                        MemoryArea& pOutput)
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file_format->hasDynSymTab() ||
47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynStrTab() ||
47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasHashTab()   ||
47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynamic())
47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& hash_sect   = file_format->getHashTab();
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(),
48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                symtab_sect.size());
48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(),
48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                strtab_sect.size());
48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* hash_region   = pOutput.request(hash_sect.offset(),
48522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                hash_sect.size());
48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* dyn_region    = pOutput.request(dyn_sect.offset(),
48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                dyn_sect.size());
48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_name  = 0;
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_value = 0;
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_size  = 0;
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_info  = 0;
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_other = 0;
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_shndx = 0;
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add index 0 symbol into SymIndexMap
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(NULL, sym_exist);
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(0);
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit of .dynsym, and .dynstr except GOT entries
51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symbol;
51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const Module::SymbolTable& symbols = pModule.getSymbolTable();
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit symbol in File and Local category if it's dynamic symbol
51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symEnd = symbols.localEnd();
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isGlobalGOTSymbol(**symbol))
52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtabIdx;
53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit symbols in TLS category, all symbols in TLS category shold be emitited
53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // directly, except GOT entries
54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = symbols.tlsEnd();
54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isGlobalGOTSymbol(**symbol))
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
54922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtabIdx;
55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
55522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit the reset of the symbols if the symbol is dynamic symbol
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = pModule.sym_end();
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (isGlobalGOTSymbol(**symbol))
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
57122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
57422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
57522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit global GOT
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol_end = m_GlobalGOTSyms.end();
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol != symbol_end; ++symbol) {
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // Make sure this golbal GOT entry is a dynamic symbol.
584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // If not, something is wrong earlier when putting this symbol into
585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //  global GOT.
58622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::mips_got_symbol) << (*symbol)->name();
588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
58922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
59022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
59222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
59322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
59722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
59822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Rules:
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   1. ignore --no-add-needed
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   2. force count in --no-as-needed
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   3. judge --as-needed
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
60822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_lib_iterator lib, libEnd = pModule.lib_end();
60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
61022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // --add-needed
61122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*lib)->attribute()->isAddNeeded()) {
61222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // --no-as-needed
61322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!(*lib)->attribute()->isAsNeeded()) {
61422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strcpy((strtab + strtabsize), (*lib)->name().c_str());
61522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
61622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strtabsize += (*lib)->name().size() + 1;
61722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++dt_need;
61822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
61922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // --as-needed
62022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else if ((*lib)->isNeeded()) {
62122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strcpy((strtab + strtabsize), (*lib)->name().c_str());
62222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
62322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strtabsize += (*lib)->name().size() + 1;
62422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++dt_need;
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // for
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit soname
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
63122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType())
632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
63322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  dynamic().applyEntries(config(), *file_format);
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().emit(dyn_sect, *dyn_region);
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
63622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  strcpy((strtab + strtabsize), pModule.name().c_str());
63722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  strtabsize += pModule.name().size() + 1;
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit hash table
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: this verion only emit SVR4 hash section.
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //        Please add GNU new hash section
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* word_array = (uint32_t*)hash_region->start();
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nbucket = getHashBucketCount(symtabIdx, false);
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nchain  = symtabIdx;
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bzero((void*)bucket, nbucket);
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  StringHash<ELF> hash_func;
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t bucket_pos = hash_func(name) % nbucket;
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    chain[sym_idx] = bucket[bucket_pos];
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bucket[bucket_pos] = sym_idx;
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT()
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn()
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
69422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
69622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getGOT())
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_DATA;
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::finalizeTargetSymbols(FragmentLinker& pLinker)
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
707cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (NULL != m_pGpDispSymbol)
70822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGpDispSymbol->setValue(m_pGOT->addr() + 0x7FF0);
709affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding
71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is called at pre-layout stage.
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol
71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::allocateCommonSymbols(Module& pModule)
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
71822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SymbolCategory& symbol_list = pModule.getSymbolTable();
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
723affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: If the order of common symbols is defined, then sort common symbols
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // std::sort(com_sym, com_end, some kind of order);
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // get corresponding BSS LDSection
72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& bss_sect = file_format->getBSS();
73122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& tbss_sect = file_format->getTBSS();
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
733cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_sect_data = NULL;
73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect.hasSectionData())
73622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = bss_sect.getSectionData();
73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
73922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
74022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* tbss_sect_data = NULL;
74122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (tbss_sect.hasSectionData())
74222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = tbss_sect.getSectionData();
74322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
74422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
746affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
74722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t bss_offset  = bss_sect.size();
74822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t tbss_offset = tbss_sect.size();
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all local common symbols
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.localEnd();
752affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (ResolveInfo::Common == (*com_sym)->desc()) {
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We have to reset the description of the symbol here. When doing
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // incremental linking, the output relocatable object may have common
7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // symbols. Therefore, we can not treat common symbols as normal symbols
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when emitting the regular name pools. We must change the symbols'
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // description here.
7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
761cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
763affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
764affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
76622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        tbss_offset += ObjectBuilder::AppendFragment(*frag,
76722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     *tbss_sect_data,
76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     (*com_sym)->value());
769affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
770affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // FIXME: how to identify small and large common symbols?
771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      else {
77222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        bss_offset += ObjectBuilder::AppendFragment(*frag,
77322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    *bss_sect_data,
77422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    (*com_sym)->value());
775affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all global common symbols
7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.commonEnd();
7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // We have to reset the description of the symbol here. When doing
7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // incremental linking, the output relocatable object may have common
7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // symbols. Therefore, we can not treat common symbols as normal symbols
7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // when emitting the regular name pools. We must change the symbols'
7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // description here.
7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
788cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
790affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
791affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
792affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
79322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tbss_offset += ObjectBuilder::AppendFragment(*frag,
79422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   *tbss_sect_data,
79522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   (*com_sym)->value());
796affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
797affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // FIXME: how to identify small and large common symbols?
798affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      bss_offset += ObjectBuilder::AppendFragment(*frag,
80022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  *bss_sect_data,
80122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  (*com_sym)->value());
802affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
80522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bss_sect.setSize(bss_offset);
80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  tbss_sect.setSize(tbss_offset);
8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symbol_list.changeCommonsToGlobal();
8085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
81222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      FragmentLinker& pLinker)
8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
82122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // TODO: (simon) The gold linker does not create an entry in .rel.dyn
8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // section if the symbol section flags contains SHF_EXECINSTR.
8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 1. Find the reason of this condition.
8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 2. Check this condition here.
8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
828affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
829affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry (as if it needs an entry).
830affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Actually we don't allocate an GOT entry.
831affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
862affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // For got16 section based relocations, we need to reserve got entries.
863affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->type() == ResolveInfo::Section) {
864affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->reserveLocalEntry();
865affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry
866affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
867affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        return;
868affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
869affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveLocalEntry();
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
873affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry
874affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD32:
8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
8955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
8965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
902affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unknown_relocation) << (int)pReloc.type()
903affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      << pReloc.symInfo()->name();
9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
90822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       FragmentLinker& pLinker)
9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
9155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
9165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
9175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
9185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
9195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
9205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
9215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
9225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
9235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
9245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
9265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (symbolNeedsDynRel(pLinker, *rsym, false, true)) {
9305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pRelDyn->reserveEntry(*m_pRelocFactory);
9315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
932affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
933affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a global GOT entry (as if it needs an entry).
934affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Actually we don't allocate an GOT entry.
935affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setGlobal(rsym);
9365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
9375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
9395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
9405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
9415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
9425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
9435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
9445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
9455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
9465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
9475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveGlobalEntry();
9495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
9505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_GlobalGOTSyms.push_back(rsym->outSymbol());
951affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a global GOT entry
952affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setGlobal(rsym);
9535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
9545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
9565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
957affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::invalid_global_relocation) << (int)pReloc.type()
958affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             << pReloc.symInfo()->name();
9595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
9615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
9665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
9685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
9705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
9715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
9725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
9745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
9775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
9785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
9795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
9805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
9815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
9825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
9845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
9865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
9885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
9895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
990affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::dynamic_relocation) << (int)pReloc.type();
9915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
993affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unknown_relocation) << (int)pReloc.type()
994affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      << pReloc.symInfo()->name();
9955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
99822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::defineGOTSymbol(FragmentLinker& pLinker)
9995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
100022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_
1001affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if ( m_pGOTSymbol != NULL ) {
100222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Unresolve>(
10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
10045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
10075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
10085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
10095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
101022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
101422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>(
10155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
10165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
10175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
10195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
10205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
102222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
102722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the
102822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments
102922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doCreateProgramHdrs(Module& pModule,
103022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           const FragmentLinker& pLinker)
10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
103222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO
10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
10365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
10375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
10385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                            const LinkerConfig& pConfig)
10405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
104122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pConfig.triple().isOSDarwin()) {
10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
10435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
104422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pConfig.triple().isOSWindows()) {
10455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
10465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
104722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new MipsGNULDBackend(pConfig);
10485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
105022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
10515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
105222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
105322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeMipsLDBackend() {
10545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
10555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
105622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                createMipsLDBackend);
10575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
105822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1059