GNULDBackend.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- GNULDBackend.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 <mcld/Target/GNULDBackend.h>
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <string>
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring>
13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cassert>
14d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <vector>
15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <algorithm>
16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h>
21d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Config/Config.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h>
23cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/LDSymbol.h>
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h>
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h>
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrameHdr.h>
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h>
29d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocationFactory.h>
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h>
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryArea.h>
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
34affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
35cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/MemoryAreaFactory.h>
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIslandFactory.h>
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/StubFactory.h>
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===--------------------------------------------------------------------===//
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatic bool isCIdentifier(const std::string& pName)
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  std::string ident = "0123456789"
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      "ABCDEFGHIJKLMNOPWRSTUVWXYZ"
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      "abcdefghijklmnopqrstuvwxyz"
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      "_";
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return (pName.find_first_not_of(ident) > pName.length());
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend
58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : TargetLDBackend(pConfig),
61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pObjectReader(NULL),
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pDynObjFileFormat(NULL),
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pExecFileFormat(NULL),
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pObjectFileFormat(NULL),
65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pInfo(pInfo),
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_ELFSegmentTable(9), // magic number
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pBRIslandFactory(NULL),
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pStubFactory(NULL),
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pEhFrame(NULL),
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr(NULL),
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasTextRel(false),
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasStaticTLS(false),
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayStart(NULL),
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayEnd(NULL),
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayStart(NULL),
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayEnd(NULL),
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayStart(NULL),
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayEnd(NULL),
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pStack(NULL),
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic(NULL),
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pTDATA(NULL),
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pTBSS(NULL),
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pExecutableStart(NULL),
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEText(NULL),
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EText(NULL),
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p__EText(NULL),
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEData(NULL),
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EData(NULL),
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pBSSStart(NULL),
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEnd(NULL),
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_End(NULL) {
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pSymIndexMap = new HashTableType(1024);
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::~GNULDBackend()
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
97d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pInfo;
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynObjFileFormat;
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pExecFileFormat;
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pSymIndexMap;
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pEhFrame;
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pEhFrameHdr;
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != m_pBRIslandFactory)
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    delete m_pBRIslandFactory;
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != m_pStubFactory)
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    delete m_pStubFactory;
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::sectionStartOffset() const
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
112d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Binary == config().codeGenType())
113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return 0x0;
114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (config().targets().bitclass()) {
116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 32u:
117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf32_Ehdr) +
118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao             numOfSegments() * sizeof(llvm::ELF::Elf32_Phdr);
119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 64u:
120d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf64_Ehdr) +
121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao             numOfSegments() * sizeof(llvm::ELF::Elf64_Phdr);
122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default:
123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      fatal(diag::unsupported_bitclass) << config().targets().triple().str()
124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        << config().targets().bitclass();
125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return 0;
126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::segmentStartAddr(const FragmentLinker& pLinker) const
130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ScriptOptions::AddressMap::const_iterator mapping =
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    config().scripts().addressMap().find(".text");
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (mapping != config().scripts().addressMap().end())
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return mapping.getEntry()->value();
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else if (pLinker.isOutputPIC())
136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return 0x0;
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return defaultTextSegmentAddr();
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader*
14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::createArchiveReader(Module& pModule)
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pObjectReader);
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new GNUArchiveReader(pModule, *m_pObjectReader);
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder)
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_pObjectReader = new ELFObjectReader(*this, pBuilder, config());
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_pObjectReader;
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
154d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder)
155d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFDynObjReader(*this, pBuilder, config());
157d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
158d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder)
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
161d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFBinaryReader(*this, pBuilder, config());
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
164d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectWriter* GNULDBackend::createObjectWriter()
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
166d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFObjectWriter(*this, config());
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
169d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjWriter* GNULDBackend::createDynObjWriter()
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
171d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFDynObjWriter(*this, config());
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
174d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFExecWriter* GNULDBackend::createExecWriter()
175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
176d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFExecWriter(*this, config());
177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryWriter* GNULDBackend::createBinaryWriter()
180d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
181d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFBinaryWriter(*this, config());
182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStdSections(ObjectBuilder& pBuilder)
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pDynObjFileFormat)
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pDynObjFileFormat = new ELFDynObjFileFormat();
190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pDynObjFileFormat->initStdSections(pBuilder,
191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pExecFileFormat)
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pExecFileFormat = new ELFExecFileFormat();
198d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pExecFileFormat->initStdSections(pBuilder,
199d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         config().targets().bitclass());
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pObjectFileFormat)
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pObjectFileFormat = new ELFObjectFileFormat();
205d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pObjectFileFormat->initStdSections(pBuilder,
206d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return false;
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols.
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations.
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStandardSymbols(FragmentLinker& pLinker,
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       Module& pModule)
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // GNU extension: define __start and __stop symbols for the sections whose
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name can be presented as C symbol
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ref: GNU gold, Layout::define_section_symbols
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator iter, iterEnd = pModule.end();
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (iter = pModule.begin(); iter != iterEnd; ++iter) {
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection* section = *iter;
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch (section->kind()) {
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame:
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasEhFrame())
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasSectionData())
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // end of switch
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isCIdentifier(section->name())) {
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      llvm::StringRef start_name = llvm::StringRef("__start_" + section->name());
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      FragmentRef* start_fragref = FragmentRef::Create(
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       section->getSectionData()->front(), 0x0);
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      pLinker.defineSymbol<FragmentLinker::AsRefered,
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           FragmentLinker::Resolve>(start_name,
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    false, // isDyn
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::NoType,
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Define,
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Global,
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // size
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // value
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    start_fragref, // FragRef
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Default);
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      llvm::StringRef stop_name = llvm::StringRef("__stop_" + section->name());
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      FragmentRef* stop_fragref = FragmentRef::Create(
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           section->getSectionData()->front(), section->size());
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      pLinker.defineSymbol<FragmentLinker::AsRefered,
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           FragmentLinker::Resolve>(stop_name,
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    false, // isDyn
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::NoType,
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Define,
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Global,
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // size
26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // value
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    stop_fragref, // FragRef
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Default);
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .preinit_array
278cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* preinit_array = NULL;
279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasPreInitArray()) {
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Create(
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   file_format->getPreInitArray().getSectionData()->front(),
282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                   0x0);
283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Null();
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayStart =
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__preinit_array_start",
290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             preinit_array, // FragRef
297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayEnd =
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__preinit_array_end",
301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .init_array
311cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* init_array = NULL;
312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInitArray()) {
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Create(
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      file_format->getInitArray().getSectionData()->front(),
315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0);
316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Null();
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayStart =
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__init_array_start",
324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayEnd =
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__init_array_end",
335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
337affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .fini_array
345cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* fini_array = NULL;
346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasFiniArray()) {
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Create(
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     file_format->getFiniArray().getSectionData()->front(),
349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     0x0);
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Null();
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayStart =
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__fini_array_start",
358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
365affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayEnd =
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__fini_array_end",
369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .stack
379cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* stack = NULL;
380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasStack()) {
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Create(
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          file_format->getStack().getSectionData()->front(),
383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          0x0);
384affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Null();
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pStack =
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__stack",
392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             stack, // FragRef
399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
400affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // _DYNAMIC
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO: add SectionData for .dynamic section, and then we can get the correct
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol section index for _DYNAMIC. Now it will be ABS.
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  f_pDynamic =
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("_DYNAMIC",
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   false, // isDyn
40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Object,
40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Define,
41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Local,
41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   0x0, // size
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   0x0, // value
41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   FragmentRef::Null(), // FragRef
41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Hidden);
41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pExecutableStart =
41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__executable_start",
420affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
425affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEText =
42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("etext",
431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_EText =
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("_etext",
442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p__EText =
45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__etext",
453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEData =
46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("edata",
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEnd =
47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::AsRefered,
47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("end",
476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _edata is defined forcefully.
486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 186
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_EData =
48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::Force,
48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("_edata",
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // __bss_start is defined forcefully.
500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 214
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pBSSStart =
50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::Force,
50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("__bss_start",
504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _end is defined forcefully.
514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 228
515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_End =
51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pLinker.defineSymbol<FragmentLinker::Force,
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          FragmentLinker::Resolve>("_end",
518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
530affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::finalizeStandardSymbols(FragmentLinker& pLinker)
532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayStart) {
540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pPreInitArrayStart->hasFragRef()) {
541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->setValue(0x0);
543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayEnd) {
547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pPreInitArrayEnd->hasFragRef()) {
548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() +
549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   file_format->getPreInitArray().size());
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(0x0);
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayStart) {
558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pInitArrayStart->hasFragRef()) {
559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->setValue(0x0);
561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayEnd) {
565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pInitArrayEnd->hasFragRef()) {
566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() +
567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getInitArray().size());
568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(0x0);
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayStart) {
576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pFiniArrayStart->hasFragRef()) {
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->setValue(0x0);
579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayEnd) {
583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pFiniArrayEnd->hasFragRef()) {
584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() +
585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getFiniArray().size());
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(0x0);
590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pStack) {
594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pStack->hasFragRef()) {
595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute);
596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->setValue(0x0);
597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
60022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pDynamic) {
60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local);
60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setValue(file_format->getDynamic().addr());
60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setSize(file_format->getDynamic().size());
60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
60522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pExecutableStart) {
608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* exec_start = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 0x0, 0x0);
609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != exec_start) {
610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) {
611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pExecutableStart->setValue(f_pExecutableStart->value() +
612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     exec_start->vaddr());
613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pExecutableStart->setValue(0x0);
617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEText || NULL != f_p_EText || NULL !=f_p__EText) {
620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* etext = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD,
621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_X,
622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_W);
623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != etext) {
624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText && ResolveInfo::ThreadLocal != f_pEText->type()) {
625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(f_pEText->value() +
626affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           etext->vaddr() +
627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           etext->memsz());
628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText && ResolveInfo::ThreadLocal != f_p_EText->type()) {
630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(f_p_EText->value() +
631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->vaddr() +
632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->memsz());
633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText && ResolveInfo::ThreadLocal != f_p__EText->type()) {
635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(f_p__EText->value() +
636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->vaddr() +
637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->memsz());
638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText)
642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(0x0);
643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText)
644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(0x0);
645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText)
646affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(0x0);
647affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEData || NULL != f_p_EData || NULL != f_pBSSStart ||
651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      NULL != f_pEnd || NULL != f_p_End) {
652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* edata = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD,
653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_W,
654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               0x0);
655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != edata) {
656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) {
657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(f_pEData->value() +
658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->vaddr() +
659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->filesz());
660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) {
662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(f_p_EData->value() +
663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->vaddr() +
664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->filesz());
665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart && ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(f_pBSSStart->value() +
668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              edata->vaddr() +
669affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              edata->filesz());
670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) {
673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(f_pEnd->value() +
674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                         edata->vaddr() +
675affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                         edata->memsz());
676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) {
678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(f_p_End->value() +
679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          edata->vaddr() +
680affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          edata->memsz());
681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData)
685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(0x0);
686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData)
687affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(0x0);
688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart)
689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(0x0);
690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd)
692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(0x0);
693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End)
694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(0x0);
695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
70122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol)
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
70322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ignore if symbol has no fragRef
70422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSymbol.hasFragRef())
70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
706affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
70722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the value of a TLS symbol is the offset to the TLS segment
70822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFSegment* tls_seg = m_ELFSegmentTable.find(llvm::ELF::PT_TLS,
70922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                               llvm::ELF::PF_R, 0x0);
71022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t value = pSymbol.fragRef()->getOutputOffset();
71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t addr  = pSymbol.fragRef()->frag()->getParent()->getSection().addr();
71222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSymbol.setValue(value + addr - tls_seg->vaddr());
71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
714affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
715affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFFileFormat* GNULDBackend::getOutputFormat()
717affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
71822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
71922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
72022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pDynObjFileFormat);
72122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
72222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
723d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pExecFileFormat);
72522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pObjectFileFormat);
72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
729affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
731affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
734affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst ELFFileFormat* GNULDBackend::getOutputFormat() const
736affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
73922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pDynObjFileFormat);
74022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
74122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
742d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
74322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pExecFileFormat);
74422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
74522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
74622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pObjectFileFormat);
74722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
748affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
74922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
751affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
752affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
753affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
75422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::partialScanRelocation(Relocation& pReloc,
75522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                         FragmentLinker& pLinker,
75622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                         Module& pModule,
75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                         const LDSection& pSection)
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
75922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if we meet a section symbol
76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pReloc.symInfo()->type() == ResolveInfo::Section) {
76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSymbol* input_sym = pReloc.symInfo()->outSymbol();
76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
76322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // 1. update the relocation target offset
76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    assert(input_sym->hasFragRef());
76522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint64_t offset = input_sym->fragRef()->getOutputOffset();
76622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pReloc.target() += offset;
76722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // 2. get output section symbol
76922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // get the output LDSection which the symbol defined in
77022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const LDSection& out_sect =
77122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      input_sym->fragRef()->frag()->getParent()->getSection();
77222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ResolveInfo* sym_info = pModule.getSectionSymbolSet().get(out_sect)->resolveInfo();
77322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set relocation target symbol to the output section symbol's resolveInfo
77422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pReloc.setSymInfo(sym_info);
77522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools
7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab,
78022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab.
7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid
78222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::sizeNamePools(const Module& pModule, bool pIsStaticLink)
7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // number of entries in symbol tables starts from 1 to hold the special entry
7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
78622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t symtab = 1;
78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t dynsym = pIsStaticLink ? 0 : 1;
78822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // size of string tables starts from 1 to hold the null character in their
79022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // first byte
7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtab = 1;
79222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t dynstr = pIsStaticLink ? 0 : 1;
79322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t shstrtab = 1;
7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hash   = 0;
7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
796d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // number of local symbol in the .dynsym
797d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  size_t dynsym_local_cnt = 0;
798d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// compute the size of .symtab, .dynsym and .strtab
80022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
80122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symbol;
80222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const Module::SymbolTable& symbols = pModule.getSymbolTable();
80322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t str_size = 0;
80422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of symbols in Local and File category
80522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symEnd = symbols.localEnd();
80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
80722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
80922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
81022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (ResolveInfo::Section != (*symbol)->type())
81122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
81222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
81322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
81422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
81522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
81622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
81722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of symbols in TLS category
81822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = symbols.tlsEnd();
81922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
82022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
82122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink) {
8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      ++dynsym;
82322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (ResolveInfo::Section != (*symbol)->type())
82422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtab;
82722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
82822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
82922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
830d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  dynsym_local_cnt = dynsym;
83122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // compute the size of the reset of symbols
83222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = pModule.sym_end();
83322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
83422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    str_size = (*symbol)->nameSize() + 1;
83522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
83622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++dynsym;
83722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (ResolveInfo::Section != (*symbol)->type())
83822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += str_size;
83922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
84022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
84122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
84222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtab += str_size;
8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
84522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
84722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(config().codeGenType()) {
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute size of .dynstr and .hash
84922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
85022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // soname
85122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!pIsStaticLink)
85222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        dynstr += pModule.name().size() + 1;
85322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
85422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /** fall through **/
855d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
856d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // add DT_NEED strings into .dynstr and .dynamic
8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Rules:
8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      //   1. ignore --no-add-needed
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      //   2. force count in --no-as-needed
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      //   3. judge --as-needed
86222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!pIsStaticLink) {
86322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        Module::const_lib_iterator lib, libEnd = pModule.lib_end();
86422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // --add-needed
86622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if ((*lib)->attribute()->isAddNeeded()) {
8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            // --no-as-needed
86822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            if (!(*lib)->attribute()->isAsNeeded()) {
86922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynstr += (*lib)->name().size() + 1;
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              dynamic().reserveNeedEntry();
8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            }
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            // --as-needed
87322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            else if ((*lib)->isNeeded()) {
87422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              dynstr += (*lib)->name().size() + 1;
8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              dynamic().reserveNeedEntry();
8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            }
8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
88022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // compute .hash
88122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Both Elf32_Word and Elf64_Word are 4 bytes
88222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
88322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao               sizeof(llvm::ELF::Elf32_Word);
88422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set size
887d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits())
8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getDynStrTab().setSize(dynstr);
8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getHashTab().setSize(hash);
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
894d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // set .dynsym sh_info to one greater than the symbol table
895d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // index of the last local symbol
896d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      file_format->getDynSymTab().setInfo(dynsym_local_cnt);
8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /* fall through */
89922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
900d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits())
9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getStrTab().setSize(strtab);
905d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
906d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // set .symtab sh_info to one greater than the symbol table
907d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // index of the last local symbol
908d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      file_format->getSymTab().setInfo(symbols.numOfLocals() + 1);
9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
91122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
91222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::fatal_illegal_codegen_type) << pModule.name();
91322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of switch
91522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
9165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
91722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// reserve fixed entries in the .dynamic section.
91822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
91922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
920d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Exec   == config().codeGenType() ||
921d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
9225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // Because some entries in .dynamic section need information of .dynsym,
9235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
9245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // entries until we get the size of the sections mentioned above
92522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!pIsStaticLink)
926d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      dynamic().reserveEntries(*file_format);
9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    file_format->getDynamic().setSize(dynamic().numOfBytes());
9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
93022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
93122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// compute the size of .shstrtab section.
93222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
93322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_iterator sect, sectEnd = pModule.end();
93422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
93522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // StackNote sections will always be in output!
93622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (0 != (*sect)->size() || LDFileFormat::StackNote == (*sect)->kind()) {
93722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      shstrtab += ((*sect)->name().size() + 1);
93822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
93922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
94022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  shstrtab += (strlen(".shstrtab") + 1);
94122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  file_format->getShStrTab().setSize(shstrtab);
94222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @}
94322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
94422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
94522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol
94622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym,
94722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
94822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
94922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
95022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pSymtabIdx)
95122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
95222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
95322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
95422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   if (ResolveInfo::Section != pSymbol.type()) {
95522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = pStrtabsize;
95622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     strcpy((pStrtab + pStrtabsize), pSymbol.name());
95722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
95822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   else {
95922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = 0;
96022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
96122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
96222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
96322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
96422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
96522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
96622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
96722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
96822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol
96922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym,
97022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
97122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
97222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
97322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pSymtabIdx)
97422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
97522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
97622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
97722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_name  = pStrtabsize;
97822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
97922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
98022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
98122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
98222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
98322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out string
98422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   strcpy((pStrtab + pStrtabsize), pSymbol.name());
9855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab
9885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
9895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
9905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
99122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule,
99222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    MemoryArea& pOutput)
9935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
99422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
9955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getSymTab();
9975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getStrTab();
9985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
99922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(),
100022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                symtab_sect.size());
100122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(),
100222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                strtab_sect.size());
10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
1007d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
10085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
1009d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
1011d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
1012d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
1013d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
1014d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
1015d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
10165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
10175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
10195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize the first ELF symbol
1021d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits()) {
10225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_name  = 0;
10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_value = 0;
10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_size  = 0;
10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_info  = 0;
10265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_other = 0;
10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_shndx = 0;
10285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else { // must 64
10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_name  = 0;
10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_value = 0;
10325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_size  = 0;
10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_info  = 0;
10345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_other = 0;
10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_shndx = 0;
10365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
103822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool sym_exist = false;
103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  HashTableType::entry_type* entry = NULL;
104022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
104122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(NULL, sym_exist);
104222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(0);
104322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
104422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
10465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
10475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute size of .symtab, .dynsym and .strtab
104822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symbol;
104922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symEnd = pModule.sym_end();
105022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = pModule.sym_begin(); symbol != symEnd; ++symbol) {
105122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map if building .o file
105222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::Object == config().codeGenType()) {
105322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      entry = m_pSymIndexMap->insert(*symbol, sym_exist);
10545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      entry->setValue(symtabIdx);
10555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
10565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1057d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
105822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
105922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
106022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
106122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize,
106222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
10635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
10655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
106622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
106722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
10685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
107122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
10725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
10735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
10745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
107522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitDynNamePools(const Module& pModule,
107622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    MemoryArea& pOutput)
10775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
107822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
107922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file_format->hasDynSymTab() ||
108022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynStrTab() ||
108122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasHashTab()   ||
108222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynamic())
108322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
10845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
10865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
10875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
10895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
10905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& hash_sect   = file_format->getHashTab();
10915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
10925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
109322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(),
109422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                symtab_sect.size());
109522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(),
109622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                strtab_sect.size());
109722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* hash_region   = pOutput.request(hash_sect.offset(),
109822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                hash_sect.size());
109922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* dyn_region    = pOutput.request(dyn_sect.offset(),
110022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                dyn_sect.size());
11015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
11025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
11035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
1104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
11055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
1106d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
11075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
1108d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
1109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
1110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
1111d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
11125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize the first ELF symbol
1114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits()) {
11155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_name  = 0;
11165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_value = 0;
11175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_size  = 0;
11185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_info  = 0;
11195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_other = 0;
11205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_shndx = 0;
11215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
11225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else { // must 64
11235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_name  = 0;
11245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_value = 0;
11255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_size  = 0;
11265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_info  = 0;
11275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_other = 0;
11285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_shndx = 0;
11295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
11305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
11315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
11325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
11335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add the first symbol into m_pSymIndexMap
11355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(NULL, sym_exist);
11365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(0);
11375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
11395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
11405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit of .dynsym, and .dynstr
114222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symbol;
114322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const Module::SymbolTable& symbols = pModule.getSymbolTable();
114422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit symbol in File and Local category if it's dynamic symbol
114522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_sym_iterator symEnd = symbols.localEnd();
114622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
114722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
11485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
11495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
115122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
115222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
115322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
115422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize,
115522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
115622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // maintain output's symbol and index map
11585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
11595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry->setValue(symtabIdx);
116022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
116122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtabIdx;
116222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
116322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
116422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
11655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
116622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit symbols in TLS category, all symbols in TLS category shold be emitited
116722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = symbols.tlsEnd();
116822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
1169d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
117022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
117122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
117222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
117322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize,
117422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
117522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
117622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
117722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
117822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
117922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
118022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtabIdx;
118122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
118222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
118322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
118422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
118522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit the reset of the symbols if the symbol is dynamic symbol
118622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  symEnd = pModule.sym_end();
118722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
118822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (!isDynamicSymbol(**symbol))
118922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
119022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
119222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
119322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
119422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
119522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize,
119622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   symtabIdx);
11975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
119822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // maintain output's symbol and index map
119922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
120022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(symtabIdx);
12015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
12025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
120322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (ResolveInfo::Section != (*symbol)->type())
120422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
12055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
12085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
12095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Rules:
12105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   1. ignore --no-add-needed
12115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   2. force count in --no-as-needed
12125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   3. judge --as-needed
12135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
121422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_lib_iterator lib, libEnd = pModule.lib_end();
121522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
121622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // --add-needed
121722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*lib)->attribute()->isAddNeeded()) {
121822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // --no-as-needed
121922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (!(*lib)->attribute()->isAsNeeded()) {
122022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strcpy((strtab + strtabsize), (*lib)->name().c_str());
122122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
122222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strtabsize += (*lib)->name().size() + 1;
122322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++dt_need;
122422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
122522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // --as-needed
122622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else if ((*lib)->isNeeded()) {
122722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strcpy((strtab + strtabsize), (*lib)->name().c_str());
122822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
122922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        strtabsize += (*lib)->name().size() + 1;
123022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++dt_need;
12315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
12325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
123322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
12345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
123622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
123722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set pointer to SONAME entry in dynamic string table.
1238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
123922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1240d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  dynamic().applyEntries(*file_format);
12415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().emit(dyn_sect, *dyn_region);
12425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
124322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit soname
124422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
124522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    strcpy((strtab + strtabsize), pModule.name().c_str());
124622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    strtabsize += pModule.name().size() + 1;
124722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
12485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit hash table
12495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: this verion only emit SVR4 hash section.
12505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //        Please add GNU new hash section
12515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
12535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
12545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* word_array = (uint32_t*)hash_region->start();
12555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
12565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
12575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nbucket = getHashBucketCount(symtabIdx, false);
12595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nchain  = symtabIdx;
12605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
12625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
12635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
12655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bzero((void*)bucket, nbucket);
12665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  StringHash<ELF> hash_func;
12685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1269d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits()) {
12705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
12715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
12725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      size_t bucket_pos = hash_func(name) % nbucket;
12735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      chain[sym_idx] = bucket[bucket_pos];
12745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      bucket[bucket_pos] = sym_idx;
12755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1277d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits()) {
12785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
12795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::StringRef name(strtab + symtab64[sym_idx].st_name);
12805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      size_t bucket_pos = hash_func(name) % nbucket;
12815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      chain[sym_idx] = bucket[bucket_pos];
12825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      bucket[bucket_pos] = sym_idx;
12835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section
128822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::sizeInterp()
1289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const char* dyld_name;
129122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasDyld())
129222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dyld_name = config().options().dyld().c_str();
1293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyld_name = dyld();
1295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
129622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& interp = getOutputFormat()->getInterp();
1297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  interp.setSize(std::strlen(dyld_name) + 1);
1298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp
130122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitInterp(MemoryArea& pOutput)
1302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
130322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasInterp()) {
130422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const LDSection& interp = getOutputFormat()->getInterp();
130522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    MemoryRegion *region = pOutput.request(interp.offset(), interp.size());
130622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const char* dyld_name;
130722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasDyld())
130822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      dyld_name = config().options().dyld().c_str();
130922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
131022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      dyld_name = dyld();
1311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
131222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    std::memcpy(region->start(), dyld_name, interp.size());
131322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
13165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder
131722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaounsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const
13185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
131922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
132022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // NULL section should be the "1st" section
13225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (LDFileFormat::Null == pSectHdr.kind())
13235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0;
13245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
132522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (&pSectHdr == &file_format->getStrTab())
132622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return SHO_STRTAB;
132722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the section is not ALLOC, lay it out until the last possible moment
13295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC))
13305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_UNDEFINED;
13315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0;
13335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0;
13345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: need to take care other possible output sections
13355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pSectHdr.kind()) {
13365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Regular:
13375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (is_exec) {
13385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getInit())
13395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_INIT;
13405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getFini())
13415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_FINI;
13425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_TEXT;
13435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else if (!is_write) {
13445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RO;
13455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else {
134622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (config().options().hasRelro()) {
134722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (&pSectHdr == &file_format->getPreInitArray() ||
134822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getInitArray() ||
134922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getFiniArray() ||
1350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getCtors() ||
1351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getDtors() ||
1352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getJCR() ||
1353d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao              &pSectHdr == &file_format->getDataRelRo())
1354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO;
1355d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          if (&pSectHdr == &file_format->getDataRelRoLocal())
1356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO_LOCAL;
1357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
135822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) {
135922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return SHO_TLS_DATA;
136022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
13615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_DATA;
13625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
13635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::BSS:
136522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0)
136622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return SHO_TLS_BSS;
13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_BSS;
13685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
136922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LDFileFormat::NamePool: {
13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getDynamic())
13715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RELRO;
13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_NAMEPOOL;
137322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
13745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Relocation:
13755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getRelPlt() ||
13765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          &pSectHdr == &file_format->getRelaPlt())
13775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_REL_PLT;
13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_RELOCATION;
13795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // get the order from target for target specific sections
13815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Target:
138222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return getTargetSectionOrder(pSectHdr);
13835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // handle .interp
13855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Note:
13865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_INTERP;
13875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrame:
1389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrameHdr:
1390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::GCCExceptTable:
1391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_EXCEPTION;
13925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::MetaData:
13945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Debug:
13955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
13965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_UNDEFINED;
13975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
13985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
13995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize
14015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const
14025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold linker: symtab.cc: 2780
14045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // undefined and dynamic symbols should have zero size.
14055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined)
14065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
14075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.resolveInfo()->size();
14085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo
14115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const
14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set binding
14145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t bind = 0x0;
14155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isLocal())
14165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isGlobal())
14185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isWeak())
14205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_WEAK;
14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isAbsolute()) {
14225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // (Luba) Is a absolute but not global (weak or local) symbol meaningful?
14235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1426d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().codeGenType() != LinkerConfig::Object &&
1427d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
1428d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pSymbol.visibility() == llvm::ELF::STV_HIDDEN))
14295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t type = pSymbol.resolveInfo()->type();
1432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change
1433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // its type to Function
1434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn())
1435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    type = ResolveInfo::Function;
1436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (type | (bind << 4));
14375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout()
14405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const
14415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn())
14435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
14445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.value();
14465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout()
14495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t
145022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const
14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isAbsolute())
14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_ABS;
14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isCommon())
14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_COMMON;
14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn())
14575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_UNDEF;
14585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isLocal()) {
14605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch (pSymbol.type()) {
14615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case ResolveInfo::NoType:
14625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case ResolveInfo::File:
14635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return llvm::ELF::SHN_ABS;
14645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
14655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
146722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef())
146822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return llvm::ELF::SHN_ABS;
146922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSymbol.hasFragRef() && "symbols must have fragment reference to get its index");
147122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pSymbol.fragRef()->frag()->getParent()->getSection().index();
14725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index
14755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::getSymbolIdx(LDSymbol* pSymbol) const
14765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao   HashTableType::iterator entry = m_pSymIndexMap->find(pSymbol);
14785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao   return entry.getEntry()->value();
14795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding
148222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage.
1483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @refer Google gold linker: common.cc: 214
1484affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool
148522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::allocateCommonSymbols(Module& pModule)
14865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
148722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SymbolCategory& symbol_list = pModule.getSymbolTable();
1488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
1490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
1493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: If the order of common symbols is defined, then sort common symbols
1495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // std::sort(com_sym, com_end, some kind of order);
1496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
149722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // get corresponding BSS LDSection
149822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
149922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& bss_sect = file_format->getBSS();
150022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& tbss_sect = file_format->getTBSS();
1501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1502cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
150322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_sect_data = NULL;
150422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect.hasSectionData())
150522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = bss_sect.getSectionData();
150622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
150722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
150822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
150922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* tbss_sect_data = NULL;
151022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (tbss_sect.hasSectionData())
151122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = tbss_sect.getSectionData();
151222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
151322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
1514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
151622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t bss_offset  = bss_sect.size();
151722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t tbss_offset = tbss_sect.size();
1518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all local common symbols
1520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.localEnd();
1521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
1523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::Common == (*com_sym)->desc()) {
1524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // We have to reset the description of the symbol here. When doing
1525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // incremental linking, the output relocatable object may have common
1526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // symbols. Therefore, we can not treat common symbols as normal symbols
1527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // when emitting the regular name pools. We must change the symbols'
1528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // description here.
1529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1530cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
153122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
153522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        tbss_offset += ObjectBuilder::AppendFragment(*frag,
153622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     *tbss_sect_data,
153722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     (*com_sym)->value());
1538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      else {
154022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        bss_offset += ObjectBuilder::AppendFragment(*frag,
154122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    *bss_sect_data,
154222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    (*com_sym)->value());
1543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
15465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all global common symbols
1548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.commonEnd();
1549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
1550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // We have to reset the description of the symbol here. When doing
1551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // incremental linking, the output relocatable object may have common
1552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // symbols. Therefore, we can not treat common symbols as normal symbols
1553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // when emitting the regular name pools. We must change the symbols'
1554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // description here.
1555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1556cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
155722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
156122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tbss_offset += ObjectBuilder::AppendFragment(*frag,
156222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   *tbss_sect_data,
156322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   (*com_sym)->value());
1564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
156622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      bss_offset += ObjectBuilder::AppendFragment(*frag,
156722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  *bss_sect_data,
156822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  (*com_sym)->value());
1569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
157222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bss_sect.setSize(bss_offset);
157322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  tbss_sect.setSize(tbss_offset);
1574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  symbol_list.changeCommonsToGlobal();
1575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
15765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers
158022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::createProgramHdrs(Module& pModule,
158122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     const FragmentLinker& pLinker)
15825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
158322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat *file_format = getOutputFormat();
1584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_PHDR
15865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_ELFSegmentTable.produce(llvm::ELF::PT_PHDR);
15875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_INTERP
1589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInterp()) {
15905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ELFSegment* interp_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_INTERP);
1591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    interp_seg->addSection(&file_format->getInterp());
1592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
159422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t cur_flag, prev_flag = getSegmentFlag(0);
15955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegment* load_seg = NULL;
15965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make possible PT_LOAD segments
159722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator sect, sect_end = pModule.end();
159822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (sect = pModule.begin(); sect != sect_end; ++sect) {
1599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
16005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0 == ((*sect)->flag() & llvm::ELF::SHF_ALLOC) &&
16015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        LDFileFormat::Null != (*sect)->kind())
16025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
16035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
160422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    cur_flag = getSegmentFlag((*sect)->flag());
160522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bool createPT_LOAD = false;
160622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LDFileFormat::Null == (*sect)->kind()) {
160722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. create text segment
160822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
160922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
161022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if (!config().options().omagic() &&
161122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) {
161222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. create data segment if w/o omagic set
161322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
161422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
161522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if ((*sect)->kind() == LDFileFormat::BSS &&
161622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             load_seg->isDataSegment() &&
161722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             config().scripts().addressMap().find(".bss") !=
161822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             (config().scripts().addressMap().end())) {
161922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 3. create bss segment if w/ -Tbss and there is a data segment
162022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
162122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
162222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
162322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((*sect != &(file_format->getText())) &&
162422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*sect != &(file_format->getData())) &&
162522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*sect != &(file_format->getBSS())) &&
162622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (config().scripts().addressMap().find((*sect)->name()) !=
162722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao           config().scripts().addressMap().end()))
162822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 4. create PT_LOAD for sections in address map except for text, data,
162922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // and bss
163022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        createPT_LOAD = true;
163122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
16325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
163322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (createPT_LOAD) {
163422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // create new PT_LOAD segment
163522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      load_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_LOAD, cur_flag);
163622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      load_seg->setAlign(abiPageSize());
16375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
16385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != load_seg);
1640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    load_seg->addSection((*sect));
164122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (cur_flag != prev_flag)
164222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      load_seg->updateFlag(cur_flag);
16435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
164422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    prev_flag = cur_flag;
16455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
16465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_DYNAMIC
1648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasDynamic()) {
1649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* dyn_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_DYNAMIC,
1650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_R |
1651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_W);
1652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyn_seg->addSection(&file_format->getDynamic());
1653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
165522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasRelro()) {
1656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // make PT_GNU_RELRO
1657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* relro_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_RELRO);
165822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
165922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) {
166022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (llvm::ELF::PT_LOAD != (*seg).type())
166122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
166222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
166322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (ELFSegment::sect_iterator sect = (*seg).begin(),
166422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             sectEnd = (*seg).end(); sect != sectEnd; ++sect) {
166522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        unsigned int order = getSectionOrder(**sect);
166622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (SHO_RELRO_LOCAL == order ||
166722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            SHO_RELRO == order ||
166822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            SHO_RELRO_LAST == order) {
166922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          relro_seg->addSection(*sect);
167022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
1671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
16735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
16745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1675affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // make PT_GNU_EH_FRAME
1676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasEhFrameHdr()) {
1677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* eh_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_EH_FRAME);
1678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    eh_seg->addSection(&file_format->getEhFrameHdr());
1679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
168022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
168122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_TLS
168222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasTData() || file_format->hasTBSS()) {
168322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFSegment* tls_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_TLS);
168422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTData())
168522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tls_seg->addSection(&file_format->getTData());
168622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTBSS())
168722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tls_seg->addSection(&file_format->getTBSS());
168822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
168922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
169022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_GNU_STACK
169122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasStackNote()) {
169222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_STACK,
169322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              llvm::ELF::PF_R |
169422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              llvm::ELF::PF_W |
169522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              getSegmentFlag(file_format->getStackNote().flag()));
169622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
169722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
169822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // create target dependent segments
169922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  doCreateProgramHdrs(pModule, pLinker);
1700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments
170322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupProgramHdrs(const FragmentLinker& pLinker)
1704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
17055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update segment info
17065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegmentFactory::iterator seg, seg_end = m_ELFSegmentTable.end();
17075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (seg = m_ELFSegmentTable.begin(); seg != seg_end; ++seg) {
17085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ELFSegment& segment = *seg;
17095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // update PT_PHDR
17115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (llvm::ELF::PT_PHDR == segment.type()) {
17125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      uint64_t offset, phdr_size;
1713d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits()) {
17145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf32_Ehdr);
17155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
17165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
17175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else {
17185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf64_Ehdr);
17195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf64_Phdr);
17205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
17215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setOffset(offset);
172222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      segment.setVaddr(segmentStartAddr(pLinker) + offset);
17235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setPaddr(segment.vaddr());
17245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setFilesz(numOfSegments() * phdr_size);
17255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setMemsz(numOfSegments() * phdr_size);
1726d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      segment.setAlign(config().targets().bitclass() / 8);
17275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
17285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
17295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1730affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // bypass if there is no section in this segment (e.g., PT_GNU_STACK)
1731affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (segment.numOfSections() == 0)
1732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      continue;
1733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
173422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    segment.setOffset(segment.front()->offset());
1735affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::PT_LOAD == segment.type() &&
173622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDFileFormat::Null == segment.front()->kind())
173722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      segment.setVaddr(segmentStartAddr(pLinker));
1738affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
173922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      segment.setVaddr(segment.front()->addr());
17405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setPaddr(segment.vaddr());
17415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
174222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const LDSection* last_sect = segment.back();
17435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != last_sect);
1744affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    uint64_t file_size = last_sect->offset() - segment.offset();
17455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (LDFileFormat::BSS != last_sect->kind())
17465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_size += last_sect->size();
17475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setFilesz(file_size);
17485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setMemsz(last_sect->addr() - segment.vaddr() + last_sect->size());
17505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
17515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
17525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
175322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
1754affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: layout.cc:2608
175522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupGNUStackInfo(Module& pModule, FragmentLinker& pLinker)
17565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1757affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t flag = 0x0;
175822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasStackSet()) {
1759affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 1. check the command line option (-z execstack or -z noexecstack)
176022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasExecStack())
1761affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      flag = llvm::ELF::SHF_EXECINSTR;
176222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
176322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
1764affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2. check the stack info from the input objects
176522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // FIXME: since we alway emit .note.GNU-stack in output now, we may be able
176622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // to check this from the output .note.GNU-stack directly after section
176722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // merging is done
1768affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    size_t object_count = 0, stack_note_count = 0;
176922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::const_obj_iterator obj, objEnd = pModule.obj_end();
177022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (obj = pModule.obj_begin(); obj != objEnd; ++obj) {
177122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++object_count;
177222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack");
177322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL != sect) {
177422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++stack_note_count;
177522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 2.1 found a stack note that is set as executable
177622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) {
177722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          flag = llvm::ELF::SHF_EXECINSTR;
177822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
1779affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
1780affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1781affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
17825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1783affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.2 there are no stack note sections in all input objects
1784affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (0 == stack_note_count)
1785affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
17865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1787affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.3 a special case. Use the target default to decide if the stack should
1788affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //     be executable
1789affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count)
1790affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (isDefaultExecStack())
1791affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        flag = llvm::ELF::SHF_EXECINSTR;
17925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
17935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
179422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasStackNote()) {
179522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    getOutputFormat()->getStackNote().setFlag(flag);
179622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
179722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
179822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
179922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupRelro - setup the offset constraint of PT_RELRO
180022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupRelro(Module& pModule)
180122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
180222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(config().options().hasRelro());
180322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if -z relro is given, we need to adjust sections' offset again, and let
180422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // PT_GNU_RELRO end on a common page boundary
180522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
180622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator sect = pModule.begin();
180722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (Module::iterator sect_end = pModule.end(); sect != sect_end; ++sect) {
180822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // find the first non-relro section
180922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (getSectionOrder(**sect) > SHO_RELRO_LAST)
181022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
181122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
181222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
181322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // align the first non-relro section to page boundary
181422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t offset = (*sect)->offset();
181522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  alignAddress(offset, commonPageSize());
181622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  (*sect)->setOffset(offset);
181722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
181822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // It seems that compiler think .got and .got.plt are continuous (w/o any
181922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // padding between). If .got is the last section in PT_RELRO and it's not
182022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // continuous to its next section (i.e. .got.plt), we need to add padding
182122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // in front of .got instead.
182222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // FIXME: Maybe we can handle this in a more general way.
182322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& got = getOutputFormat()->getGOT();
182422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if ((getSectionOrder(got) == SHO_RELRO_LAST) &&
182522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (got.offset() + got.size() != offset)) {
182622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    got.setOffset(offset - got.size());
182722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
182822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
182922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up remaining section's offset
183022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  setOutputSectionOffset(pModule, ++sect, pModule.end());
183122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
183222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
183322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set a group of output sections'
183422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// offset, and set pSectBegin to pStartOffset if pStartOffset is not -1U.
183522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setOutputSectionOffset(Module& pModule,
183622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          Module::iterator pSectBegin,
183722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          Module::iterator pSectEnd,
183822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          uint64_t pStartOffset)
183922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
184022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSectBegin == pModule.end())
184122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
184222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
184322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(pSectEnd == pModule.end() ||
184422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         (pSectEnd != pModule.end() &&
184522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*pSectBegin)->index() <= (*pSectEnd)->index()));
184622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
184722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pStartOffset != -1U) {
184822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*pSectBegin)->setOffset(pStartOffset);
184922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++pSectBegin;
185022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
185122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
185222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up the "cur" and "prev" iterator
185322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator cur = pSectBegin;
185422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator prev = pSectBegin;
185522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (cur != pModule.begin())
185622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    --prev;
1857affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
185822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++cur;
185922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
186022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (; cur != pSectEnd; ++cur, ++prev) {
186122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint64_t offset = 0x0;
186222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch ((*prev)->kind()) {
186322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Null:
186422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        offset = sectionStartOffset();
186522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
186622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::BSS:
186722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        offset = (*prev)->offset();
186822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
186922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
187022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        offset = (*prev)->offset() + (*prev)->size();
187122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
187222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
187322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
187422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    alignAddress(offset, (*cur)->align());
187522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*cur)->setOffset(offset);
187622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
187722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
187822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
187922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set output sections' address
188022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setOutputSectionAddress(FragmentLinker& pLinker,
188122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           Module& pModule,
188222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           Module::iterator pSectBegin,
188322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           Module::iterator pSectEnd)
188422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
188522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSectBegin == pModule.end())
188622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
188722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
188822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(pSectEnd == pModule.end() ||
188922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         (pSectEnd != pModule.end() &&
189022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*pSectBegin)->index() <= (*pSectEnd)->index()));
189122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
189222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
189322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         segEnd = elfSegmentTable().end(), prev = elfSegmentTable().end();
189422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao       seg != segEnd; prev = seg, ++seg) {
189522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (llvm::ELF::PT_LOAD != (*seg).type())
189622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
189722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
189822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint64_t start_addr = 0x0;
189922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ScriptOptions::AddressMap::const_iterator mapping;
190022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*seg).front()->kind() == LDFileFormat::Null)
190122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mapping = config().scripts().addressMap().find(".text");
190222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if ((*seg).isDataSegment())
190322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mapping = config().scripts().addressMap().find(".data");
190422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if ((*seg).isBssSegment())
190522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mapping = config().scripts().addressMap().find(".bss");
190622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
190722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mapping = config().scripts().addressMap().find((*seg).front()->name());
190822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
190922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (mapping != config().scripts().addressMap().end()) {
191022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // check address mapping
191122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      start_addr = mapping.getEntry()->value();
1912d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if ((*seg).front()->kind() != LDFileFormat::Null) {
1913d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        const uint64_t remainder = start_addr % abiPageSize();
1914d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        if (remainder != (*seg).front()->offset() % abiPageSize()) {
1915d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          uint64_t padding = abiPageSize() + remainder -
1916d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                             (*seg).front()->offset() % abiPageSize();
1917d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          setOutputSectionOffset(pModule,
1918d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 pModule.begin() + (*seg).front()->index(),
1919d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 pModule.end(),
1920d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 (*seg).front()->offset() + padding);
1921d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          if (config().options().hasRelro())
1922d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao            setupRelro(pModule);
1923d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        }
192422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
192522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
192622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
192722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((*seg).front()->kind() == LDFileFormat::Null) {
192822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 1st PT_LOAD
192922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        start_addr = segmentStartAddr(pLinker);
193022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
193122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else if ((*prev).front()->kind() == LDFileFormat::Null) {
193222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // prev segment is 1st PT_LOAD
193322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        start_addr = segmentStartAddr(pLinker) + (*seg).front()->offset();
193422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
193522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else {
193622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Others
193722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        start_addr = (*prev).front()->addr() + (*seg).front()->offset();
193822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
193922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
194022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // padding
194122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (((*seg).front()->offset() & (abiPageSize() - 1)) != 0)
194222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        start_addr += abiPageSize();
194322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
194422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
194522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (ELFSegment::sect_iterator sect = (*seg).begin(),
194622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao           sectEnd = (*seg).end(); sect != sectEnd; ++sect) {
194722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((*sect)->index() < (*pSectBegin)->index())
194822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
194922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
195022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LDFileFormat::Null == (*sect)->kind())
195122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
195222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
195322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (sect == pSectEnd)
195422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
195522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
195622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (sect != (*seg).begin())
195722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*sect)->setAddr(start_addr + (*sect)->offset() -
195822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                         (*seg).front()->offset());
195922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
196022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*sect)->setAddr(start_addr);
196122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
196222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
19635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
19645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1965d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// layout - layout method
1966d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid GNULDBackend::layout(Module& pModule, FragmentLinker& pLinker)
1967d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
1968d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::vector<SHOEntry> output_list;
1969d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 1. determine what sections will go into final output, and push the needed
1970d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // sections into output_list for later processing
1971d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie;
1972d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       ++it) {
1973d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    switch ((*it)->kind()) {
1974d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // take NULL and StackNote directly
1975d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Null:
1976d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::StackNote:
1977d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
1978d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        break;
1979d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // ignore if section size is 0
1980d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Regular:
1981d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Target:
1982d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::MetaData:
1983d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::BSS:
1984d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Debug:
1985d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::EhFrame:
1986d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::GCCExceptTable:
1987d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::NamePool:
1988d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Relocation:
1989d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Note:
1990d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::EhFrameHdr:
1991d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        if (0 != (*it)->size()) {
1992d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
1993d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        }
1994d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        break;
1995d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Group:
1996d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        if (LinkerConfig::Object == config().codeGenType()) {
1997d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          //TODO: support incremental linking
1998d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ;
1999d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        }
2000d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        break;
2001d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Version:
2002d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        if (0 != (*it)->size()) {
2003d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
2004d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name();
2005d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        }
2006d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        break;
2007d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      default:
2008d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        if (0 != (*it)->size()) {
2009d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          error(diag::err_unsupported_section) << (*it)->name() << (*it)->kind();
2010d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        }
2011d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        break;
2012d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
2013d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  } // end of for
2014d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2015d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 2. sort output section orders
2016d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::stable_sort(output_list.begin(), output_list.end(), SHOCompare());
2017d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2018d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 3. update output sections in Module
2019d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pModule.getSectionTable().clear();
2020d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  for(size_t index = 0; index < output_list.size(); ++index) {
2021d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    (output_list[index].first)->setIndex(index);
2022d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    pModule.getSectionTable().push_back(output_list[index].first);
2023d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
2024d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2025d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 4. create program headers
2026d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
2027d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    createProgramHdrs(pModule, pLinker);
2028d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
2029d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2030d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 5. set output section offset
2031d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  setOutputSectionOffset(pModule, pModule.begin(), pModule.end(), 0x0);
2032d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
2033d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
20345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// preLayout - Backend can do any needed modification before layout
203522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::preLayout(Module& pModule, FragmentLinker& pLinker)
20365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
20375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // prelayout target first
203822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  doPreLayout(pLinker);
2039affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
204022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2041affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // init EhFrameHdr and size the output section
204222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* format = getOutputFormat();
204322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pEhFrameHdr = new EhFrameHdr(format->getEhFrameHdr(),
204422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   format->getEhFrame());
2045affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr->sizeOutput();
2046affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
204722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
204822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // change .tbss and .tdata section symbol from Local to TLS category
204922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pTDATA)
205022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pModule.getSymbolTable().changeLocalToTLS(*f_pTDATA);
205122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
205222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pTBSS)
205322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pModule.getSymbolTable().changeLocalToTLS(*f_pTBSS);
205422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
205522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // To merge input's relocation sections into output's relocation sections.
205622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //
205722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are generating relocatables (-r), move input relocation sections
205822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // to corresponding output relocation sections.
205922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
206022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::obj_iterator input, inEnd = pModule.obj_end();
206122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (input = pModule.obj_begin(); input != inEnd; ++input) {
206222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
206322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
206422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
206522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the output relocation LDSection with identical name.
206622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_sect = pModule.getSection((*rs)->name());
206722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == output_sect) {
206822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect = LDSection::Create((*rs)->name(),
206922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->kind(),
207022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->type(),
207122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->flag());
207222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
207322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setAlign((*rs)->align());
207422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          pModule.getSectionTable().push_back(output_sect);
207522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
207622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
207722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // set output relocation section link
207822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        const LDSection* input_link = (*rs)->getLink();
207922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != input_link && "Illegal input relocation section.");
208022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
208122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the linked output section
208222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_link = pModule.getSection(input_link->name());
208322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != output_link);
208422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
208522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        output_sect->setLink(output_link);
208622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
208722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get output relcoationData, create one if not exist
208822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!output_sect->hasRelocData())
208922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          IRBuilder::CreateRelocData(*output_sect);
209022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
209122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        RelocData* out_reloc_data = output_sect->getRelocData();
209222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
209322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // move relocations from input's to output's RelcoationData
2094d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& out_list =
2095d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                             out_reloc_data->getRelocationList();
2096d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& in_list =
2097d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      (*rs)->getRelocData()->getRelocationList();
209822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        out_list.splice(out_list.end(), in_list);
209922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
210022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // size output
210122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (llvm::ELF::SHT_REL == output_sect->type())
210222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelEntrySize());
210322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else if (llvm::ELF::SHT_RELA == output_sect->type())
210422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelaEntrySize());
210522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else {
210622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          fatal(diag::unknown_reloc_section_type) << output_sect->type()
210722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << output_sect->name();
210822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
210922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // end of for each relocation section
211022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // end of for each input
211122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of if
211222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
211322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up the section flag of .note.GNU-stack section
211422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  setupGNUStackInfo(pModule, pLinker);
21155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
21165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2117cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout
211822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::postLayout(Module& pModule,
211922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              FragmentLinker& pLinker)
21205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 1. set up section address and segment attributes
212222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
212322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasRelro()) {
2124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // 1.1 set up the offset constraint of PT_RELRO
212522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setupRelro(pModule);
212622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
212722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2128d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // 1.2 set up the output sections' address
212922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    setOutputSectionAddress(pLinker, pModule, pModule.begin(), pModule.end());
213022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // 1.3 do relaxation
213222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    relax(pModule, pLinker);
2133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // 1.4 set up the attributes of program headers
213522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    setupProgramHdrs(pLinker);
2136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 2. target specific post layout
213922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  doPostLayout(pModule, pLinker);
21405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
21415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
214222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::postProcessing(FragmentLinker& pLinker, MemoryArea& pOutput)
2143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
214422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // emit eh_frame_hdr
2146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
214722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      m_pEhFrameHdr->emitOutput<32>(pOutput);
2148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
21515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count.
21525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker, dynobj.cc:791
21535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols,
21545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          bool pIsGNUStyle)
21555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
21565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold, dynobj.cc:loc 791
21575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static const unsigned int buckets[] =
21585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
21595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
21605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    16411, 32771, 65537, 131101, 262147
21615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
21625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const unsigned buckets_count = sizeof buckets / sizeof buckets[0];
21635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int result = 1;
21655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (unsigned i = 0; i < buckets_count; ++i) {
21665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pNumOfSymbols < buckets[i])
21675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
21685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = buckets[i];
21695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
21705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pIsGNUStyle && result < 2)
21725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = 2;
21735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
21755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
21765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol
21785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker: symtab.cc:311
217922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol)
21805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
21815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
21825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // symbol. We should not add it
21835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.binding() == ResolveInfo::Local)
21845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
21855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If we are building shared object, and the visibility is external, we
21875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // need to add it.
218822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
2189d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Exec   == config().codeGenType() ||
2190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
21915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default ||
2192d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected ||
2193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        pSymbol.resolveInfo()->type() == ResolveInfo::ThreadLocal) {
21945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return true;
219522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
219622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
219722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
219822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
219922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
220022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol
220122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker: symtab.cc:311
220222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo)
220322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
220422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
220522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol. We should not add it
220622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pResolveInfo.binding() == ResolveInfo::Local)
220722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
220822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
220922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are building shared object, and the visibility is external, we
221022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // need to add it.
221122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
2212d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Exec   == config().codeGenType() ||
2213d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
221422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (pResolveInfo.visibility() == ResolveInfo::Default ||
2215d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        pResolveInfo.visibility() == ResolveInfo::Protected ||
2216d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        pResolveInfo.type() == ResolveInfo::ThreadLocal) {
221722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
221822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
221922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
2221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine.
2224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:135
222522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::commonPageSize() const
2226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
222722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().commPageSize() > 0)
222822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return std::min(config().options().commPageSize(), abiPageSize());
2229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
223022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return std::min(static_cast<uint64_t>(0x1000), abiPageSize());
2231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine.
2234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:125
223522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::abiPageSize() const
2236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
223722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().maxPageSize() > 0)
223822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return config().options().maxPageSize();
2239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
2240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return static_cast<uint64_t>(0x1000);
2241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other
2244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit
2245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:551
224622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const
2247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
2248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.other() != ResolveInfo::Default)
2249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
225122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This is because the codeGenType of pie is DynObj. And gold linker check
225222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the "shared" option instead.
225322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
225422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
225522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
225622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj != config().codeGenType())
225722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
225822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
225922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().Bsymbolic())
2260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
226222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // A local defined symbol should be non-preemptible.
226322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32
226422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relocation refers to a local defined symbol, and we should generate a
226522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relative dynamic relocation when applying the relocation.
226622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local)
2267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
2270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
227222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
227322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, symtab.h:645
227422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolNeedsDynRel(const FragmentLinker& pLinker,
227522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     const ResolveInfo& pSym,
227622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     bool pSymHasPLT,
227722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     bool isAbsReloc) const
227822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
227922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // an undefined reference in the executables should be statically
228022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // resolved to 0 and no need a dynamic relocation
228122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isUndef() &&
228222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !pSym.isDyn() &&
2283d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::Exec   == config().codeGenType() ||
2284d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary == config().codeGenType()))
228522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
228622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
228722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isAbsolute())
228822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
228922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pLinker.isOutputPIC() && isAbsReloc)
229022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
229122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymHasPLT && ResolveInfo::Function == pSym.type())
229222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
229322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pLinker.isOutputPIC() && pSymHasPLT)
229422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
229522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDyn() || pSym.isUndef() ||
229622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      isSymbolPreemptible(pSym))
229722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
229822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
229922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
230022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
230122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry
2303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:596
230422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolNeedsPLT(const FragmentLinker& pLinker,
230522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                  const ResolveInfo& pSym) const
2306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
230722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isUndef() &&
230822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !pSym.isDyn() &&
230922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LinkerConfig::DynObj != config().codeGenType())
2310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry
2313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() == ResolveInfo::IndirectFunc)
2314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() != ResolveInfo::Function)
2317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
231922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pLinker.isStaticLink() && !pLinker.isOutputPIC())
232022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
232122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
232222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
2323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (pSym.isDyn() ||
2326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          pSym.isUndef() ||
232722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          isSymbolPreemptible(pSym));
2328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
233022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at
233122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time
233222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, Symbol::final_value_is_known
233322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolFinalValueIsKnown(const FragmentLinker& pLinker,
233422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           const ResolveInfo& pSym) const
2335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
233622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the output is pic code or if not executables, symbols' value may change
233722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // at runtime
2338d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pLinker.isOutputPIC() ||
2339d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::Exec != config().codeGenType() &&
2340d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary != config().codeGenType()))
2341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
234222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
234322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is from dynamic object, then its value is unknown
234422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDyn())
2345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
234622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
234722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is not in dynamic object and is not undefined, then its value
234822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // is known
234922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSym.isUndef())
2350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
235222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is undefined and not in dynamic objects, for example, a weak
235322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // undefined symbol, then whether the symbol's final value can be known
235422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // depends on whrther we're doing static link
235522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pLinker.isStaticLink();
2356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
235922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolNeedsCopyReloc(const FragmentLinker& pLinker,
2360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const Relocation& pReloc,
236122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                        const ResolveInfo& pSym) const
2362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
2363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // only the reference from dynamic executable to non-function symbol in
2364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // the dynamic objects may need copy relocation
236522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pLinker.isOutputPIC() ||
2366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !pSym.isDyn() ||
2367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.type() == ResolveInfo::Function ||
2368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.size() == 0)
2369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // check if the option -z nocopyreloc is given
237222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasNoCopyReloc())
2373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // TODO: Is this check necessary?
2376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if relocation target place is readonly, a copy relocation is needed
237722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag();
237822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE))
2379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
23805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
23825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
238422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTDATASymbol()
238522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
238622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTDATA);
238722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
238822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
238922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
239022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTDATASymbol() const
239122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
239222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTDATA);
239322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
239422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
239522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
239622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTBSSSymbol()
239722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
239822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTBSS);
239922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
240022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
240122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
240222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTBSSSymbol() const
240322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
240422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTBSS);
240522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
240622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
240722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
240822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection)
240922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
241022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_bHasTextRel)
241122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
241222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
241322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the target section of the dynamic relocation is ALLOCATE but is not
241422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // writable, than we should set DF_TEXTREL
241522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const uint32_t flag = pSection.flag();
241622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC))
241722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasTextRel = true;
241822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
241922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return;
242022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
242122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
242222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation
242322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initBRIslandFactory()
242422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
242522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pBRIslandFactory) {
242622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pBRIslandFactory = new BranchIslandFactory(maxBranchOffset());
242722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
242822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
242922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
243022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
243122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation
243222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStubFactory()
243322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
243422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pStubFactory) {
243522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pStubFactory = new StubFactory();
243622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
243722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
243822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
243922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
244022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::relax(Module& pModule, FragmentLinker& pLinker)
244122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
244222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!mayRelax())
244322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
244422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
244522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool finished = true;
244622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  do {
244722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (doRelax(pModule, pLinker, finished)) {
244822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // If the sections (e.g., .text) are relaxed, the layout is also changed
244922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // We need to do the following:
245022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
245122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. set up the offset
245222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setOutputSectionOffset(pModule, pModule.begin(), pModule.end());
245322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
245422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. set up the offset constraint of PT_RELRO
245522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (config().options().hasRelro())
245622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        setupRelro(pModule);
245722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
245822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 3. set up the output sections' address
245922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setOutputSectionAddress(pLinker, pModule, pModule.begin(), pModule.end());
246022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
246122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } while (!finished);
246222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
246322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
246422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
246522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2466