MipsLDBackend.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
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"
10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "MipsGNUInfo.h"
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsELFDynamic.h"
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsLDBackend.h"
13d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "MipsRelocator.h"
14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h>
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h>
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum {
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // The original o32 abi.
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O32    = 0x00001000,
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // O32 extended to work on 64 bit architectures.
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_O64    = 0x00002000,
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 32 bit mode.
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI32 = 0x00003000,
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // EABI in 64 bit mode.
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  E_MIPS_ABI_EABI64 = 0x00004000
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// MipsGNULDBackend
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
47d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig,
48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                   MipsGNUInfo* pInfo)
49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  : GNULDBackend(pConfig, pInfo),
50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelocator(NULL),
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOT(NULL),
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pRelDyn(NULL),
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynamic(NULL),
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGOTSymbol(NULL),
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pGpDispSymbol(NULL)
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend()
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pRelocator;
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pGOT;
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pRelDyn;
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynamic;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .got
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& got = file_format->getGOT();
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOT = new MipsGOT(got);
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // initialize .rel.dyn
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection& reldyn = file_format->getRelDyn();
78d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
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
113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaobool MipsGNULDBackend::initRelocator(const FragmentLinker& pLinker)
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (NULL == m_pRelocator) {
116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelocator = new MipsRelocator(*this);
117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pRelocator->setFragmentLinker(pLinker);
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* MipsGNULDBackend::getRelocator()
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != m_pRelocator);
125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return m_pRelocator;
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
159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
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 Liaouint64_t MipsGNULDBackend::flags() const
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: (simon) The correct flag's set depend on command line
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // arguments and flags from input .o files.
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::ELF::EF_MIPS_ARCH_32R2 |
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_NOREORDER |
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_PIC |
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         llvm::ELF::EF_MIPS_CPIC |
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         E_MIPS_ABI_O32;
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
179affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t MipsGNULDBackend::defaultTextSegmentAddr() const
180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return 0x80000;
182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::abiPageSize() const
185cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().maxPageSize() > 0)
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return config().options().maxPageSize();
188cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  else
189cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return static_cast<uint64_t>(0x10000);
190cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
191cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(FragmentLinker& pLinker)
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set .got size
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // when building shared object, the .got section is must.
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::DynObj == config().codeGenType() ||
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pGOT->hasGOT1() ||
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        NULL != m_pGOTSymbol) {
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pGOT->finalizeSectionSize();
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      defineGOTSymbol(pLinker);
20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
204d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    ELFFileFormat* file_format = getOutputFormat();
20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set .rel.dyn size
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!m_pRelDyn->empty())
207d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      file_format->getRelDyn().setSize(
208d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                  m_pRelDyn->numOfRelocs() * getRelEntrySize());
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(Module& pModule,
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    FragmentLinker& pLinker)
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic()
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == m_pDynamic)
221d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pDynamic = new MipsELFDynamic(*this, config());
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine.
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section.
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert( NULL != m_pDynamic);
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pDynamic;
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection,
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           MemoryRegion& pRegion) const
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pRegion.size() && "Size of MemoryRegion is zero!");
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSection == &(file_format->getGOT())) {
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint64_t result = m_pGOT->emit(pRegion);
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  fatal(diag::unrecognized_output_sectoin)
248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << pSection.name()
249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          << "mclinker@googlegroups.com";
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
253affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return std::find(m_GlobalGOTSyms.begin(),
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sizeNamePools - compute the size of regular name pools
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab,
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab.
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::sizeNamePools(const Module& pModule, bool pIsStaticLink)
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // number of entries in symbol tables starts from 1 to hold the special entry
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t symtab = 1;
26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t dynsym = pIsStaticLink ? 0 : 1;
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // size of string tables starts from 1 to hold the null character in their
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // first byte
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t strtab = 1;
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t dynstr = pIsStaticLink ? 0 : 1;
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t shstrtab = 1;
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t hash   = 0;
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
277d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // number of local symbol in the .dynsym
278d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  size_t dynsym_local_cnt = 0;
279d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// compute the size of .symtab, .dynsym and .strtab
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symbol;
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const Module::SymbolTable& symbols = pModule.getSymbolTable();
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t str_size = 0;
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of symbols in Local and File category
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symEnd = symbols.localEnd();
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of symbols in TLS category
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = symbols.tlsEnd();
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink) {
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
311d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  dynsym_local_cnt = dynsym;
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of the reset of symbols
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = pModule.sym_end();
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(config().codeGenType()) {
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // compute size of .dynstr and .hash
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // soname
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!pIsStaticLink)
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += pModule.name().size() + 1;
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /** fall through **/
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec: {
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // add DT_NEED strings into .dynstr and .dynamic
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // Rules:
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      //   1. ignore --no-add-needed
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      //   2. force count in --no-as-needed
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      //   3. judge --as-needed
34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!pIsStaticLink) {
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        Module::const_lib_iterator lib, libEnd = pModule.lib_end();
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          // --add-needed
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if ((*lib)->attribute()->isAddNeeded()) {
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // --no-as-needed
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            if (!(*lib)->attribute()->isAsNeeded()) {
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynstr += (*lib)->name().size() + 1;
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynamic().reserveNeedEntry();
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // --as-needed
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            else if ((*lib)->isNeeded()) {
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynstr += (*lib)->name().size() + 1;
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynamic().reserveNeedEntry();
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // compute .hash
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Both Elf32_Word and Elf64_Word are 4 bytes
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao               sizeof(llvm::ELF::Elf32_Word);
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // set size
367d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits())
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getDynStrTab().setSize(dynstr);
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getHashTab().setSize(hash);
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
374d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // set .dynsym sh_info to one greater than the symbol table
375d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // index of the last local symbol
376d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      file_format->getDynSymTab().setInfo(dynsym_local_cnt);
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /* fall through */
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
380d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits())
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      file_format->getStrTab().setSize(strtab);
385d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
386d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // set .symtab sh_info to one greater than the symbol table
387d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // index of the last local symbol
388d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      file_format->getSymTab().setInfo(symbols.numOfLocals() + 1);
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default: {
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::fatal_illegal_codegen_type) << pModule.name();
39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of switch
39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// reserve fixed entries in the .dynamic section.
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LinkerConfig::Exec == config().codeGenType()) {
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Because some entries in .dynamic section need information of .dynsym,
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // entries until we get the size of the sections mentioned above
405d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    dynamic().reserveEntries(*file_format);
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    file_format->getDynamic().setSize(dynamic().numOfBytes());
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// compute the size of .shstrtab section.
41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_iterator sect, sectEnd = pModule.end();
41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // StackNote sections will always be in output!
41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (0 != (*sect)->size() || LDFileFormat::StackNote == (*sect)->kind()) {
41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      shstrtab += ((*sect)->name().size() + 1);
41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  shstrtab += (strlen(".shstrtab") + 1);
42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file_format->getShStrTab().setSize(shstrtab);
42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol
42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym,
42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    LDSymbol& pSymbol,
42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    char* pStrtab,
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    size_t pStrtabsize,
42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    size_t pSymtabIdx)
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != pSymbol.type() ||
43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          &pSymbol == m_pGpDispSymbol) {
43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = pStrtabsize;
43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     strcpy((pStrtab + pStrtabsize), pSymbol.name());
43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   else {
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = 0;
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(const Module& pModule,
45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                        MemoryArea& pOutput)
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file_format->hasDynSymTab() ||
45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynStrTab() ||
45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasHashTab()   ||
45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynamic())
46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& hash_sect   = file_format->getHashTab();
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(),
46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                symtab_sect.size());
46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(),
47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                strtab_sect.size());
47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* hash_region   = pOutput.request(hash_sect.offset(),
47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                hash_sect.size());
47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* dyn_region    = pOutput.request(dyn_sect.offset(),
47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                dyn_sect.size());
47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_name  = 0;
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_value = 0;
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_size  = 0;
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_info  = 0;
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_other = 0;
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symtab32[0].st_shndx = 0;
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add index 0 symbol into SymIndexMap
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(NULL, sym_exist);
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(0);
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit of .dynsym, and .dynstr except GOT entries
50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symbol;
50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const Module::SymbolTable& symbols = pModule.getSymbolTable();
50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit symbol in File and Local category if it's dynamic symbol
50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symEnd = symbols.localEnd();
50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isGlobalGOTSymbol(**symbol))
51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtabIdx;
52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit symbols in TLS category, all symbols in TLS category shold be emitited
52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // directly, except GOT entries
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = symbols.tlsEnd();
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isGlobalGOTSymbol(**symbol))
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtabIdx;
54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit the reset of the symbols if the symbol is dynamic symbol
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = pModule.sym_end();
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (isGlobalGOTSymbol(**symbol))
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
56122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit global GOT
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol_end = m_GlobalGOTSyms.end();
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       symbol != symbol_end; ++symbol) {
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // Make sure this golbal GOT entry is a dynamic symbol.
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // If not, something is wrong earlier when putting this symbol into
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //  global GOT.
57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::mips_got_symbol) << (*symbol)->name();
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
57622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
58422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
58522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Rules:
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   1. ignore --no-add-needed
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   2. force count in --no-as-needed
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   3. judge --as-needed
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
59522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_lib_iterator lib, libEnd = pModule.lib_end();
59622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
59722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // --add-needed
59822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*lib)->attribute()->isAddNeeded()) {
59922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // --no-as-needed
60022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!(*lib)->attribute()->isAsNeeded()) {
60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strcpy((strtab + strtabsize), (*lib)->name().c_str());
60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strtabsize += (*lib)->name().size() + 1;
60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++dt_need;
60522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
60622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // --as-needed
60722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else if ((*lib)->isNeeded()) {
60822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strcpy((strtab + strtabsize), (*lib)->name().c_str());
60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
61022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strtabsize += (*lib)->name().size() + 1;
61122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++dt_need;
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // for
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit soname
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
61822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType())
619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
620d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  dynamic().applyEntries(*file_format);
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().emit(dyn_sect, *dyn_region);
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
62322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  strcpy((strtab + strtabsize), pModule.name().c_str());
62422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  strtabsize += pModule.name().size() + 1;
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit hash table
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: this verion only emit SVR4 hash section.
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //        Please add GNU new hash section
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* word_array = (uint32_t*)hash_region->start();
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nbucket = getHashBucketCount(symtabIdx, false);
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nchain  = symtabIdx;
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bzero((void*)bucket, nbucket);
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  StringHash<ELF> hash_func;
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t bucket_pos = hash_func(name) % nbucket;
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    chain[sym_idx] = bucket[bucket_pos];
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bucket[bucket_pos] = sym_idx;
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT()
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pGOT);
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pGOT;
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn()
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != m_pRelDyn);
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *m_pRelDyn;
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int
68122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
68322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (&pSectHdr == &file_format->getGOT())
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_DATA;
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return SHO_UNDEFINED;
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value
69222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::finalizeTargetSymbols(FragmentLinker& pLinker)
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
694cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (NULL != m_pGpDispSymbol)
69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGpDispSymbol->setValue(m_pGOT->addr() + 0x7FF0);
696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding
70022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is called at pre-layout stage.
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol
70322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::allocateCommonSymbols(Module& pModule)
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SymbolCategory& symbol_list = pModule.getSymbolTable();
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
710affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: If the order of common symbols is defined, then sort common symbols
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // std::sort(com_sym, com_end, some kind of order);
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
71522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // get corresponding BSS LDSection
71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
71722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& bss_sect = file_format->getBSS();
71822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& tbss_sect = file_format->getTBSS();
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
720cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
72122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_sect_data = NULL;
72222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect.hasSectionData())
72322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = bss_sect.getSectionData();
72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
72522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* tbss_sect_data = NULL;
72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (tbss_sect.hasSectionData())
72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = tbss_sect.getSectionData();
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
73122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t bss_offset  = bss_sect.size();
73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t tbss_offset = tbss_sect.size();
7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all local common symbols
7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.localEnd();
739affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (ResolveInfo::Common == (*com_sym)->desc()) {
7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We have to reset the description of the symbol here. When doing
7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // incremental linking, the output relocatable object may have common
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // symbols. Therefore, we can not treat common symbols as normal symbols
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // when emitting the regular name pools. We must change the symbols'
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // description here.
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
748cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
74922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
751affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
752affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
75322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        tbss_offset += ObjectBuilder::AppendFragment(*frag,
75422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     *tbss_sect_data,
75522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     (*com_sym)->value());
756affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
757affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // FIXME: how to identify small and large common symbols?
758affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      else {
75922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        bss_offset += ObjectBuilder::AppendFragment(*frag,
76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    *bss_sect_data,
76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    (*com_sym)->value());
762affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // allocate all global common symbols
7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  com_end = symbol_list.commonEnd();
7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // We have to reset the description of the symbol here. When doing
7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // incremental linking, the output relocatable object may have common
7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // symbols. Therefore, we can not treat common symbols as normal symbols
7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // when emitting the regular name pools. We must change the symbols'
7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // description here.
7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
775cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
77622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
777affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
778affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
779affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
78022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tbss_offset += ObjectBuilder::AppendFragment(*frag,
78122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   *tbss_sect_data,
78222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   (*com_sym)->value());
783affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
784affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // FIXME: how to identify small and large common symbols?
785affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
78622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      bss_offset += ObjectBuilder::AppendFragment(*frag,
78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  *bss_sect_data,
78822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  (*com_sym)->value());
789affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
79222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bss_sect.setSize(bss_offset);
79322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  tbss_sect.setSize(tbss_offset);
7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  symbol_list.changeCommonsToGlobal();
7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      FragmentLinker& pLinker)
8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
8045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LinkerConfig::DynObj == config().codeGenType()) {
8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // TODO: (simon) The gold linker does not create an entry in .rel.dyn
8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // section if the symbol section flags contains SHF_EXECINSTR.
8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 1. Find the reason of this condition.
8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // 2. Check this condition here.
813d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
816affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry (as if it needs an entry).
817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Actually we don't allocate an GOT entry.
818affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
849affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // For got16 section based relocations, we need to reserve got entries.
850affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (rsym->type() == ResolveInfo::Section) {
851affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->reserveLocalEntry();
852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry
853affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
854affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        return;
855affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
856affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveLocalEntry();
8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
860affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a local GOT entry
861affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setLocal(rsym);
8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD32:
8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
889affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unknown_relocation) << (int)pReloc.type()
890affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      << pReloc.symInfo()->name();
8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
89522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       FragmentLinker& pLinker)
8965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* rsym = pReloc.symInfo();
8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pReloc.type()){
9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_NONE:
9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_A:
9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_INSERT_B:
9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_DELETE:
9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
9055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL64:
9065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL16:
9075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PJUMP:
9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_RELGOT:
9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL64:
9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_32:
9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_64:
9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HI16:
9155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LO16:
91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (symbolNeedsDynRel(pLinker, *rsym, false, true)) {
917d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_pRelDyn->reserveEntry();
9185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveRel);
919affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
920affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a global GOT entry (as if it needs an entry).
921affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Actually we don't allocate an GOT entry.
922affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setGlobal(rsym);
9235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
9245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT16:
9265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL16:
9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_DISP:
9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_HI16:
9295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_HI16:
9305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_LO16:
9315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_CALL_LO16:
9325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_PAGE:
9335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GOT_OFST:
9345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
9355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_pGOT->reserveGlobalEntry();
9365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        rsym->setReserved(rsym->reserved() | ReserveGot);
9375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_GlobalGOTSyms.push_back(rsym->outSymbol());
938affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // Remeber this rsym is a global GOT entry
939affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_pGOT->setGlobal(rsym);
9405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
9415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_LITERAL:
9435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL32:
944affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::invalid_global_relocation) << (int)pReloc.type()
945affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             << pReloc.symInfo()->name();
9465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GPREL16:
9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_26:
9505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_PC16:
9515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_16:
9535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT5:
9545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SHIFT6:
9555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SUB:
9565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHER:
9575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_HIGHEST:
9585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_SCN_DISP:
9595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL32:
9615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GD:
9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_LDM:
9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
9665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL32:
9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
9685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_REL32:
9715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JALR:
9735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_COPY:
9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_GLOB_DAT:
9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case llvm::ELF::R_MIPS_JUMP_SLOT:
977affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::dynamic_relocation) << (int)pReloc.type();
9785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
980affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unknown_relocation) << (int)pReloc.type()
981affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      << pReloc.symInfo()->name();
9825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
98522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::defineGOTSymbol(FragmentLinker& pLinker)
9865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
98722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // define symbol _GLOBAL_OFFSET_TABLE_
988affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if ( m_pGOTSymbol != NULL ) {
98922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Unresolve>(
9905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
9915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
9935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
9945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
9955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
99722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
9985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
9995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
100122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>(
10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     "_GLOBAL_OFFSET_TABLE_",
10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     false,
10045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Object,
10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Define,
10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Local,
10075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // size
10085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     0x0, // value
100922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     ResolveInfo::Hidden);
10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
101422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the
101522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments
101622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doCreateProgramHdrs(Module& pModule,
101722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           const FragmentLinker& pLinker)
10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
101922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO
10205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
102622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                            const LinkerConfig& pConfig)
10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1028d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSDarwin()) {
10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "MachO linker is not supported yet");
10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1031d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().triple().isOSWindows()) {
10325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "COFF linker is not supported yet");
10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1034d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new MipsGNULDBackend(pConfig, new MipsGNUInfo(pConfig.targets().triple()));
10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
103722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
10385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization.
103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
104022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeMipsLDBackend() {
10415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Register the linker backend
10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
104322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                createMipsLDBackend);
10445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
104522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1046