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>
166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <map>
17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h>
22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Config/Config.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h>
24cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/LDSymbol.h>
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h>
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h>
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h>
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrameHdr.h>
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h>
30d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocationFactory.h>
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.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
40f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace {
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===--------------------------------------------------------------------===//
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesstatic const std::string simple_c_identifier_allowed_chars =
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "0123456789"
47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "ABCDEFGHIJKLMNOPWRSTUVWXYZ"
48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "abcdefghijklmnopqrstuvwxyz"
49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "_";
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatic bool isCIdentifier(const std::string& pName)
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return (pName.find_first_not_of(simple_c_identifier_allowed_chars)
55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines              == std::string::npos);
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} // anonymous namespace
59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesusing namespace mcld;
61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend
64cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : TargetLDBackend(pConfig),
67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pObjectReader(NULL),
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pDynObjFileFormat(NULL),
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pExecFileFormat(NULL),
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pObjectFileFormat(NULL),
71d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pInfo(pInfo),
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_ELFSegmentTable(9), // magic number
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pBRIslandFactory(NULL),
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pStubFactory(NULL),
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr(NULL),
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasTextRel(false),
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasStaticTLS(false),
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayStart(NULL),
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayEnd(NULL),
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayStart(NULL),
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayEnd(NULL),
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayStart(NULL),
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayEnd(NULL),
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pStack(NULL),
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic(NULL),
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pTDATA(NULL),
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pTBSS(NULL),
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pExecutableStart(NULL),
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEText(NULL),
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EText(NULL),
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p__EText(NULL),
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEData(NULL),
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EData(NULL),
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pBSSStart(NULL),
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEnd(NULL),
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_End(NULL) {
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pSymIndexMap = new HashTableType(1024);
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::~GNULDBackend()
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pInfo;
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynObjFileFormat;
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pExecFileFormat;
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pObjectFileFormat;
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pSymIndexMap;
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pEhFrameHdr;
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pBRIslandFactory;
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pStubFactory;
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::sectionStartOffset() const
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Binary == config().codeGenType())
115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return 0x0;
116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (config().targets().bitclass()) {
118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 32u:
119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf32_Ehdr) +
120d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao             numOfSegments() * sizeof(llvm::ELF::Elf32_Phdr);
121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 64u:
122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf64_Ehdr) +
123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao             numOfSegments() * sizeof(llvm::ELF::Elf64_Phdr);
124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default:
125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      fatal(diag::unsupported_bitclass) << config().targets().triple().str()
126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        << config().targets().bitclass();
127d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return 0;
128d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesuint64_t GNULDBackend::getSegmentStartAddr(const LinkerScript& pScript) const
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::AddressMap::const_iterator mapping =
134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pScript.addressMap().find(".text");
135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pScript.addressMap().end() != mapping)
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return mapping.getEntry()->value();
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (config().isCodeIndep())
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return 0x0;
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_pInfo->defaultTextSegmentAddr();
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader*
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::createArchiveReader(Module& pModule)
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pObjectReader);
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new GNUArchiveReader(pModule, *m_pObjectReader);
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder)
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
152d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_pObjectReader = new ELFObjectReader(*this, pBuilder, config());
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_pObjectReader;
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder)
157d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
158d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFDynObjReader(*this, pBuilder, config());
159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
160d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
161d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder)
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
163d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFBinaryReader(*this, pBuilder, config());
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter* GNULDBackend::createWriter()
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
168d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFObjectWriter(*this, config());
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStdSections(ObjectBuilder& pBuilder)
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pDynObjFileFormat)
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pDynObjFileFormat = new ELFDynObjFileFormat();
177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pDynObjFileFormat->initStdSections(pBuilder,
178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
181d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
182d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pExecFileFormat)
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pExecFileFormat = new ELFExecFileFormat();
185d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pExecFileFormat->initStdSections(pBuilder,
186d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         config().targets().bitclass());
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pObjectFileFormat)
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pObjectFileFormat = new ELFObjectFileFormat();
192d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pObjectFileFormat->initStdSections(pBuilder,
193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return false;
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols.
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations.
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::initStandardSymbols(IRBuilder& pBuilder,
20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       Module& pModule)
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // GNU extension: define __start and __stop symbols for the sections whose
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name can be presented as C symbol
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ref: GNU gold, Layout::define_section_symbols
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator iter, iterEnd = pModule.end();
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (iter = pModule.begin(); iter != iterEnd; ++iter) {
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection* section = *iter;
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch (section->kind()) {
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame:
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasEhFrame())
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasSectionData())
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // end of switch
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isCIdentifier(section->name())) {
231f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      std::string start_name = "__start_" + section->name();
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      FragmentRef* start_fragref = FragmentRef::Create(
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       section->getSectionData()->front(), 0x0);
2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    start_name,
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::NoType,
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Define,
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Global,
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // size
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // value
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    start_fragref, // FragRef
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Default);
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
244f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      std::string stop_name = "__stop_" + section->name();
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      FragmentRef* stop_fragref = FragmentRef::Create(
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           section->getSectionData()->front(), section->size());
2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    stop_name,
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::NoType,
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Define,
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Global,
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // size
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // value
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    stop_fragref, // FragRef
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Default);
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .preinit_array
263cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* preinit_array = NULL;
264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasPreInitArray()) {
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Create(
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   file_format->getPreInitArray().getSectionData()->front(),
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                   0x0);
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Null();
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayStart =
2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__preinit_array_start",
275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             preinit_array, // FragRef
281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayEnd =
2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__preinit_array_end",
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .init_array
294cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* init_array = NULL;
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInitArray()) {
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Create(
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      file_format->getInitArray().getSectionData()->front(),
298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0);
299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Null();
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayStart =
3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__init_array_start",
307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayEnd =
3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__init_array_end",
317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .fini_array
326cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* fini_array = NULL;
327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasFiniArray()) {
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Create(
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     file_format->getFiniArray().getSectionData()->front(),
330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     0x0);
331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Null();
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayStart =
3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__fini_array_start",
339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayEnd =
3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__fini_array_end",
349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .stack
358cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* stack = NULL;
359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasStack()) {
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Create(
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          file_format->getStack().getSectionData()->front(),
362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          0x0);
363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Null();
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pStack =
3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__stack",
371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             stack, // FragRef
377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // _DYNAMIC
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO: add SectionData for .dynamic section, and then we can get the correct
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol section index for _DYNAMIC. Now it will be ABS.
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  f_pDynamic =
3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                   "_DYNAMIC",
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Object,
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Define,
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Local,
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   0x0, // size
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   0x0, // value
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   FragmentRef::Null(), // FragRef
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Hidden);
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pExecutableStart =
3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__executable_start",
397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
400affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
401affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
404affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEText =
4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "etext",
407affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
408affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
409affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
410affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
411affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_EText =
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "_etext",
417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
418affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
419affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
420affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p__EText =
4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__etext",
427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEData =
4356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "edata",
437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
440affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEnd =
4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "end",
448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _edata is defined forcefully.
457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 186
458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_EData =
4596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "_edata",
461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // __bss_start is defined forcefully.
470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 214
471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pBSSStart =
4726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
4736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__bss_start",
474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _end is defined forcefully.
483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 228
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_End =
4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
4866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "_end",
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::finalizeStandardSymbols()
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayStart) {
507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pPreInitArrayStart->hasFragRef()) {
508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->setValue(0x0);
510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayEnd) {
514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pPreInitArrayEnd->hasFragRef()) {
515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() +
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   file_format->getPreInitArray().size());
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(0x0);
521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayStart) {
525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pInitArrayStart->hasFragRef()) {
526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->setValue(0x0);
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayEnd) {
532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pInitArrayEnd->hasFragRef()) {
533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() +
534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getInitArray().size());
535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(0x0);
539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayStart) {
543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pFiniArrayStart->hasFragRef()) {
544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->setValue(0x0);
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayEnd) {
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pFiniArrayEnd->hasFragRef()) {
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() +
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getFiniArray().size());
553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(0x0);
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pStack) {
561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pStack->hasFragRef()) {
562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute);
563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->setValue(0x0);
564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pDynamic) {
56822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local);
56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setValue(file_format->getDynamic().addr());
57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setSize(file_format->getDynamic().size());
57122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pExecutableStart) {
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* exec_start = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 0x0, 0x0);
576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != exec_start) {
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) {
578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pExecutableStart->setValue(f_pExecutableStart->value() +
579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     exec_start->vaddr());
580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pExecutableStart->setValue(0x0);
584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEText || NULL != f_p_EText || NULL !=f_p__EText) {
587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* etext = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD,
588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_X,
589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_W);
590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != etext) {
591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText && ResolveInfo::ThreadLocal != f_pEText->type()) {
592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(f_pEText->value() +
593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           etext->vaddr() +
594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           etext->memsz());
595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText && ResolveInfo::ThreadLocal != f_p_EText->type()) {
597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(f_p_EText->value() +
598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->vaddr() +
599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->memsz());
600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText && ResolveInfo::ThreadLocal != f_p__EText->type()) {
602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(f_p__EText->value() +
603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->vaddr() +
604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->memsz());
605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText)
609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(0x0);
610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText)
611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(0x0);
612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText)
613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(0x0);
614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEData || NULL != f_p_EData || NULL != f_pBSSStart ||
618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      NULL != f_pEnd || NULL != f_p_End) {
619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* edata = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD,
620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_W,
621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               0x0);
622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != edata) {
623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) {
624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(f_pEData->value() +
625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->vaddr() +
626affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->filesz());
627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) {
629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(f_p_EData->value() +
630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->vaddr() +
631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->filesz());
632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart && ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(f_pBSSStart->value() +
635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              edata->vaddr() +
636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              edata->filesz());
637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) {
640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(f_pEnd->value() +
641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                         edata->vaddr() +
642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                         edata->memsz());
643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) {
645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(f_p_End->value() +
646affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          edata->vaddr() +
647affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          edata->memsz());
648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData)
652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(0x0);
653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData)
654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(0x0);
655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart)
656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(0x0);
657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd)
659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(0x0);
660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End)
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(0x0);
662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
66822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol)
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ignore if symbol has no fragRef
67122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSymbol.hasFragRef())
67222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
67422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the value of a TLS symbol is the offset to the TLS segment
67522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFSegment* tls_seg = m_ELFSegmentTable.find(llvm::ELF::PT_TLS,
67622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                               llvm::ELF::PF_R, 0x0);
67722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t value = pSymbol.fragRef()->getOutputOffset();
67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t addr  = pSymbol.fragRef()->frag()->getParent()->getSection().addr();
67922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSymbol.setValue(value + addr - tls_seg->vaddr());
68022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
68322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFFileFormat* GNULDBackend::getOutputFormat()
684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
68522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
68622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
68722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pDynObjFileFormat);
68822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
690d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pExecFileFormat);
69222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
69322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
69422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pObjectFileFormat);
69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
69722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
70222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst ELFFileFormat* GNULDBackend::getOutputFormat() const
703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
70422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
70622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pDynObjFileFormat);
70722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
70822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
709d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
71022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pExecFileFormat);
71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
71222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pObjectFileFormat);
71422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
715affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
717affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
718affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
719affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab,
72322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab.
724f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::sizeNamePools(Module& pModule)
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
726f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(LinkerConfig::Unset != config().codePosition());
727f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // number of entries in symbol tables starts from 1 to hold the special entry
7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t symtab = 1;
731f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t dynsym = config().isCodeStatic()? 0 : 1;
73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // size of string tables starts from 1 to hold the null character in their
73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // first byte
7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t strtab   = 1;
736f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t dynstr   = config().isCodeStatic()? 0 : 1;
73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t shstrtab = 1;
7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t hash     = 0;
7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t gnuhash  = 0;
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // number of local symbol in the .symtab and .dynsym
7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symtab_local_cnt = 0;
743d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  size_t dynsym_local_cnt = 0;
744d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd;
7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// Compute the size of .symtab, .strtab, and symtab_local_cnt
74822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symEnd = symbols.end();
7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = symbols.begin(); symbol != symEnd; ++symbol) {
75122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++symtab;
752f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (hasEntryInStrTab(**symbol))
7536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtab += (*symbol)->nameSize() + 1;
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symtab_local_cnt = 1 + symbols.numOfFiles() + symbols.numOfLocals() +
7566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                     symbols.numOfLocalDyns();
7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
75822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(config().codeGenType()) {
76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // soname
7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      dynstr += pModule.name().size() + 1;
76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
76522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /** fall through **/
766d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
767d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
768f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (!config().isCodeStatic()) {
7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        /// Compute the size of .dynsym, .dynstr, and dynsym_local_cnt
7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        symEnd = symbols.dynamicEnd();
7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) {
7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ++dynsym;
773f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (hasEntryInStrTab(**symbol))
7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*symbol)->nameSize() + 1;
7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        dynsym_local_cnt = 1 + symbols.numOfLocalDyns();
7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // compute .gnu.hash
7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (GeneralOptions::GNU  == config().options().getHashStyle() ||
7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            GeneralOptions::Both == config().options().getHashStyle()) {
7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // count the number of dynsym to hash
7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          size_t hashed_sym_cnt = 0;
7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          symEnd = symbols.dynamicEnd();
7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          for (symbol = symbols.dynamicBegin(); symbol != symEnd; ++symbol) {
7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            if (DynsymCompare().needGNUHash(**symbol))
7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              ++hashed_sym_cnt;
7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          }
7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Special case for empty .dynsym
7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (hashed_sym_cnt == 0)
7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash = 5 * 4 + config().targets().bitclass() / 8;
7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          else {
7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            size_t nbucket = getHashBucketCount(hashed_sym_cnt, true);
7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash = (4 + nbucket + hashed_sym_cnt) * 4;
7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash += (1U << getGNUHashMaskbitslog2(hashed_sym_cnt)) / 8;
7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
79822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // compute .hash
7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (GeneralOptions::SystemV == config().options().getHashStyle() ||
8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            GeneralOptions::Both == config().options().getHashStyle()) {
8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Both Elf32_Word and Elf64_Word are 4 bytes
8026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                 sizeof(llvm::ELF::Elf32_Word);
8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // add DT_NEEDED
8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        Module::const_lib_iterator lib, libEnd = pModule.lib_end();
8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) {
8106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*lib)->name().size() + 1;
8116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynamic().reserveNeedEntry();
8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          }
8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // add DT_RPATH
8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (!config().options().getRpathList().empty()) {
8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          dynamic().reserveNeedEntry();
8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          GeneralOptions::const_rpath_iterator rpath,
8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            rpathEnd = config().options().rpath_end();
8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          for (rpath = config().options().rpath_begin();
8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               rpath != rpathEnd; ++rpath)
8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*rpath).size() + 1;
8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set size
8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (config().targets().is32Bits()) {
8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          file_format->getDynSymTab().setSize(dynsym *
8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                              sizeof(llvm::ELF::Elf32_Sym));
8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        } else {
8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          file_format->getDynSymTab().setSize(dynsym *
8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                              sizeof(llvm::ELF::Elf64_Sym));
8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynStrTab().setSize(dynstr);
8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getHashTab().setSize(hash);
8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getGNUHashTab().setSize(gnuhash);
8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set .dynsym sh_info to one greater than the symbol table
8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // index of the last local symbol
8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynSymTab().setInfo(dynsym_local_cnt);
8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // Because some entries in .dynamic section need information of .dynsym,
8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // entries until we get the size of the sections mentioned above
8446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        dynamic().reserveEntries(*file_format);
8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynamic().setSize(dynamic().numOfBytes());
8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /* fall through */
84922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
850d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits())
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getStrTab().setSize(strtab);
855d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
856d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // set .symtab sh_info to one greater than the symbol table
857d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // index of the last local symbol
8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      file_format->getSymTab().setInfo(symtab_local_cnt);
8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // compute the size of .shstrtab section.
8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      Module::const_iterator sect, sectEnd = pModule.end();
8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      for (sect = pModule.begin(); sect != sectEnd; ++sect) {
8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        switch ((*sect)->kind()) {
8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        case LDFileFormat::Null:
8656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          break;
8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // take StackNote directly
8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        case LDFileFormat::StackNote:
8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          shstrtab += ((*sect)->name().size() + 1);
8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          break;
8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        case LDFileFormat::EhFrame:
8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (((*sect)->size() != 0) ||
8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              ((*sect)->hasEhFrame() &&
8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               config().codeGenType() == LinkerConfig::Object))
8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            shstrtab += ((*sect)->name().size() + 1);
8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          break;
8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        case LDFileFormat::Relocation:
8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (((*sect)->size() != 0) ||
8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              ((*sect)->hasRelocData() &&
8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               config().codeGenType() == LinkerConfig::Object))
8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            shstrtab += ((*sect)->name().size() + 1);
8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          break;
8826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        default:
8836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (((*sect)->size() != 0) ||
8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              ((*sect)->hasSectionData() &&
8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               config().codeGenType() == LinkerConfig::Object))
8866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            shstrtab += ((*sect)->name().size() + 1);
8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          break;
8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        } // end of switch
8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      } // end of for
8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      shstrtab += (strlen(".shstrtab") + 1);
8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      file_format->getShStrTab().setSize(shstrtab);
8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
89422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
89522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::fatal_illegal_codegen_type) << pModule.name();
89622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of switch
89822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
89922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
90022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol
90122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym,
90222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
90322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
90422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
90522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pSymtabIdx)
90622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
90722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
90822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
909f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines   if (hasEntryInStrTab(pSymbol)) {
91022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = pStrtabsize;
91122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     strcpy((pStrtab + pStrtabsize), pSymbol.name());
91222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
91322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   else {
91422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = 0;
91522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
91722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
91822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
91922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
92022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
92122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
92222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
92322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol
92422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym,
92522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
92622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
92722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
92822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pSymtabIdx)
92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
93022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
93122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
932f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines   if (hasEntryInStrTab(pSymbol)) {
9336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pSym.st_name  = pStrtabsize;
9346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     strcpy((pStrtab + pStrtabsize), pSymbol.name());
9356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   }
9366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   else {
9376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pSym.st_name  = 0;
9386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   }
93922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
94022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
94122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
94222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
94322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
9445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab
9475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
9495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
95022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule,
95122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                    MemoryArea& pOutput)
9525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
95322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
9545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getSymTab();
9565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getStrTab();
9575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
95822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(),
95922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                symtab_sect.size());
96022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(),
96122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                strtab_sect.size());
9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
966d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
968d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
970d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
971d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
972d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
973d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
974d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
9775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit the first ELF symbol
9796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits())
9806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0);
9816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
9826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0);
9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
98422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool sym_exist = false;
98522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  HashTableType::entry_type* entry = NULL;
98622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
9876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry = m_pSymIndexMap->insert(LDSymbol::Null(), sym_exist);
98822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(0);
98922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
99022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symIdx = 1;
9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
9936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const Module::SymbolTable& symbols = pModule.getSymbolTable();
9956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd;
9966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symEnd = symbols.end();
9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = symbols.begin(); symbol != symEnd; ++symbol) {
99922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::Object == config().codeGenType()) {
100022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      entry = m_pSymIndexMap->insert(*symbol, sym_exist);
10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      entry->setValue(symIdx);
10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1003d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
10046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx);
100522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
10066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx);
10076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symIdx;
1008f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (hasEntryInStrTab(**symbol))
100922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
101322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
10145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
10155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
10165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitDynNamePools(Module& pModule, MemoryArea& pOutput)
10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
101922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
102022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file_format->hasDynSymTab() ||
102122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynStrTab() ||
102222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynamic())
102322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
10265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
103222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(),
103322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                symtab_sect.size());
103422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(),
103522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                strtab_sect.size());
103622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* dyn_region    = pOutput.request(dyn_sect.offset(),
103722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                dyn_sect.size());
10385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
10395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
10405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
1041d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
1043d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
10445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
1045d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
1046d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
1047d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
1048d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
10515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
10525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit the first ELF symbol
10546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits())
10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0);
10566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
10576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0);
10585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symIdx = 1;
10605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
10615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .gnu.hash
10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (GeneralOptions::GNU  == config().options().getHashStyle() ||
1065f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      GeneralOptions::Both == config().options().getHashStyle())
10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitGNUHashTab(symbols, pOutput);
1067f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .hash
10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (GeneralOptions::SystemV == config().options().getHashStyle() ||
10706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      GeneralOptions::Both == config().options().getHashStyle())
10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitELFHashTab(symbols, pOutput);
10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category)
10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = symbols.dynamicEnd();
10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) {
1076d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
10776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx);
107822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
10796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx);
10805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // maintain output's symbol and index map
10815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
10826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry->setValue(symIdx);
108322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
10846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symIdx;
1085f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (hasEntryInStrTab(**symbol))
108622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
10875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
10905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
10915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
109222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_lib_iterator lib, libEnd = pModule.lib_end();
109322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
10946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) {
10956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strcpy((strtab + strtabsize), (*lib)->name().c_str());
10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
10976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtabsize += (*lib)->name().size() + 1;
10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++dt_need;
10996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
11006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().options().getRpathList().empty()) {
11036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!config().options().hasNewDTags())
11046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_RPATH, strtabsize);
11056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
11066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_RUNPATH, strtabsize);
11076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++dt_need;
11086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    GeneralOptions::const_rpath_iterator rpath,
11106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rpathEnd = config().options().rpath_end();
11116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (rpath = config().options().rpath_begin(); rpath != rpathEnd; ++rpath) {
11126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      memcpy((strtab + strtabsize), (*rpath).data(), (*rpath).size());
11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtabsize += (*rpath).size();
11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtab[strtabsize++] = (rpath + 1 == rpathEnd ? '\0' : ':');
11155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
111622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
11175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
111922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
112022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set pointer to SONAME entry in dynamic string table.
1121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
112222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  dynamic().applyEntries(*file_format);
11245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().emit(dyn_sect, *dyn_region);
11255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
112622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit soname
112722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
112822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    strcpy((strtab + strtabsize), pModule.name().c_str());
112922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    strtabsize += pModule.name().size() + 1;
113022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
11325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitELFHashTab - emit .hash
11346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitELFHashTab(const Module::SymbolTable& pSymtab,
11356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                  MemoryArea& pOutput)
11366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
11376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
11386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!file_format->hasHashTab())
11396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
11406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSection& hash_sect = file_format->getHashTab();
11416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  MemoryRegion* hash_region = pOutput.request(hash_sect.offset(),
11426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                              hash_sect.size());
11435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
11445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
11455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* word_array = (uint32_t*)hash_region->start();
11465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
11475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
11485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t dynsymSize = 1 + pSymtab.numOfLocalDyns() + pSymtab.numOfDynamics();
11506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  nbucket = getHashBucketCount(dynsymSize, false);
11516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  nchain  = dynsymSize;
11525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
11545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
11555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
1157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  memset((void*)bucket, 0, nbucket);
11585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  hash::StringHash<hash::ELF> hash_func;
11605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t idx = 1;
11626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd();
11636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.localDynBegin(); symbol != symEnd; ++symbol) {
11646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    llvm::StringRef name((*symbol)->name());
11656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    size_t bucket_pos = hash_func(name) % nbucket;
11666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    chain[idx] = bucket[bucket_pos];
11676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bucket[bucket_pos] = idx;
11686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++idx;
11696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
11706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
11716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitGNUHashTab - emit .gnu.hash
11736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitGNUHashTab(Module::SymbolTable& pSymtab,
11746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                  MemoryArea& pOutput)
11756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
11766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
11776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!file_format->hasGNUHashTab())
11786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
11796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  MemoryRegion* gnuhash_region =
11816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pOutput.request(file_format->getGNUHashTab().offset(),
11826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    file_format->getGNUHashTab().size());
11836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* word_array = (uint32_t*)gnuhash_region->start();
11856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // fixed-length fields
11866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& nbucket   = word_array[0];
11876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& symidx    = word_array[1];
11886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& maskwords = word_array[2];
11896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& shift2    = word_array[3];
11906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // variable-length fields
11916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint8_t*  bitmask = (uint8_t*)(word_array + 4);
11926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* bucket  = NULL;
11936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* chain   = NULL;
11946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // count the number of dynsym to hash
11966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t unhashed_sym_cnt = pSymtab.numOfLocalDyns();
11976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t hashed_sym_cnt   = pSymtab.numOfDynamics();
11986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd();
11996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.dynamicBegin(); symbol != symEnd; ++symbol) {
12006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (DynsymCompare().needGNUHash(**symbol))
12016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
12026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++unhashed_sym_cnt;
12036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      --hashed_sym_cnt;
12046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
12056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // special case for the empty hash table
12076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (hashed_sym_cnt == 0) {
12086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    nbucket   = 1; // one empty bucket
12096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    symidx    = 1 + unhashed_sym_cnt; // symidx above unhashed symbols
12106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskwords = 1; // bitmask length
12116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shift2    = 0; // bloom filter
12126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().targets().is32Bits()) {
12146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t* maskval = (uint32_t*)bitmask;
12156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *maskval = 0; // no valid hashes
12166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    } else {
12176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // must be 64
12186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint64_t* maskval = (uint64_t*)bitmask;
12196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *maskval = 0; // no valid hashes
12205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bucket  = (uint32_t*)(bitmask + config().targets().bitclass() / 8);
12226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *bucket = 0; // no hash in the only bucket
12236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
12245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbitslog2 = getGNUHashMaskbitslog2(hashed_sym_cnt);
12276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbits = 1u << maskbitslog2;
12286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t shift1 = config().targets().is32Bits() ? 5 : 6;
12296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t mask = (1u << shift1) - 1;
12306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  nbucket   = getHashBucketCount(hashed_sym_cnt, true);
12326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symidx    = 1 + unhashed_sym_cnt;
12336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  maskwords = 1 << (maskbitslog2 - shift1);
12346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  shift2    = maskbitslog2;
12356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // setup bucket and chain
12376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bucket = (uint32_t*)(bitmask + maskbits / 8);
12386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  chain  = (bucket + nbucket);
12396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // build the gnu style hash table
12416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef std::multimap<uint32_t,
12426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                        std::pair<LDSymbol*, uint32_t> > SymMapType;
12436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  SymMapType symmap;
12446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symEnd = pSymtab.dynamicEnd();
12456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.localDynBegin() + symidx - 1; symbol != symEnd;
12466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symbol) {
1247f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    hash::StringHash<hash::DJB> hasher;
12486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t djbhash = hasher((*symbol)->name());
12496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t hash = djbhash % nbucket;
12506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    symmap.insert(std::make_pair(hash, std::make_pair(*symbol, djbhash)));
12516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
12526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // compute bucket, chain, and bitmask
12546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  std::vector<uint64_t> bitmasks(maskwords);
12556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t hashedidx = symidx;
12566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (size_t idx = 0; idx < nbucket; ++idx) {
12576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    size_t count = 0;
12586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    std::pair<SymMapType::iterator, SymMapType::iterator> ret;
12596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ret = symmap.equal_range(idx);
12606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (SymMapType::iterator it = ret.first; it != ret.second; ) {
12616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // rearrange the hashed symbol ordering
12626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *(pSymtab.localDynBegin() + hashedidx - 1) = it->second.first;
12636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t djbhash = it->second.second;
12646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t val = ((djbhash >> shift1) & ((maskbits >> shift1) - 1));
12656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bitmasks[val] |= 1u << (djbhash & mask);
12666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bitmasks[val] |= 1u << ((djbhash >> shift2) & mask);
12676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      val = djbhash & ~1u;
12686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // advance the iterator and check if we're dealing w/ the last elment
12696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (++it == ret.second) {
12706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // last element terminates the chain
12716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        val |= 1;
12726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
12736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      chain[hashedidx - symidx] = val;
12746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++hashedidx;
12766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++count;
12775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (count == 0)
12806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bucket[idx] = 0;
12816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
12826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bucket[idx] = hashedidx - count;
12836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
12846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // write the bitmasks
12866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits()) {
12876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t* maskval = (uint32_t*)bitmask;
12886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (size_t i = 0; i < maskwords; ++i)
12896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      std::memcpy(maskval + i, &bitmasks[i], 4);
12906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else {
12916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // must be 64
12926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint64_t* maskval = (uint64_t*)bitmask;
12936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (size_t i = 0; i < maskwords; ++i)
12946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      std::memcpy(maskval + i, &bitmasks[i], 8);
12955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section
129922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::sizeInterp()
1300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const char* dyld_name;
130222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasDyld())
130322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dyld_name = config().options().dyld().c_str();
1304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
13056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dyld_name = m_pInfo->dyld();
1306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
130722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& interp = getOutputFormat()->getInterp();
1308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  interp.setSize(std::strlen(dyld_name) + 1);
1309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp
131222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitInterp(MemoryArea& pOutput)
1313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
131422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasInterp()) {
131522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const LDSection& interp = getOutputFormat()->getInterp();
131622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    MemoryRegion *region = pOutput.request(interp.offset(), interp.size());
131722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const char* dyld_name;
131822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasDyld())
131922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      dyld_name = config().options().dyld().c_str();
132022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
13216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      dyld_name = m_pInfo->dyld();
1322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
132322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    std::memcpy(region->start(), dyld_name, interp.size());
132422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1327f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool GNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const
1328f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
1329f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ResolveInfo::Section != pSym.type();
1330f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
1331f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1332f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::orderSymbolTable(Module& pModule)
1333f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
1334f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
1335f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1336f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (GeneralOptions::GNU  == config().options().getHashStyle() ||
1337f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      GeneralOptions::Both == config().options().getHashStyle())
1338f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // Currently we may add output symbols after sizeNamePools(), and a
1339f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // non-stable sort is used in SymbolCategory::arrange(), so we just
1340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // sort .dynsym right before emitting .gnu.hash
1341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(),
1342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                     DynsymCompare());
1343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
1344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
13455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder
134622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaounsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const
13475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
134822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
134922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // NULL section should be the "1st" section
13515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (LDFileFormat::Null == pSectHdr.kind())
13525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0;
13535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
135422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (&pSectHdr == &file_format->getStrTab())
135522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return SHO_STRTAB;
135622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the section is not ALLOC, lay it out until the last possible moment
13585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC))
13595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_UNDEFINED;
13605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0;
13625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0;
13635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: need to take care other possible output sections
13645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pSectHdr.kind()) {
13655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Regular:
13665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (is_exec) {
13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getInit())
13685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_INIT;
13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getFini())
13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_FINI;
13715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_TEXT;
13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else if (!is_write) {
13735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RO;
13745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else {
137522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (config().options().hasRelro()) {
137622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (&pSectHdr == &file_format->getPreInitArray() ||
137722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getInitArray() ||
137822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getFiniArray() ||
1379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getCtors() ||
1380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getDtors() ||
1381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getJCR() ||
1382d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao              &pSectHdr == &file_format->getDataRelRo())
1383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO;
1384d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          if (&pSectHdr == &file_format->getDataRelRoLocal())
1385affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO_LOCAL;
1386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
138722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) {
138822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return SHO_TLS_DATA;
138922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
13905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_DATA;
13915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
13925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::BSS:
139422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0)
139522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return SHO_TLS_BSS;
13965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_BSS;
13975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
139822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LDFileFormat::NamePool: {
13995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getDynamic())
14005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RELRO;
14015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_NAMEPOOL;
140222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
14035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Relocation:
14045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getRelPlt() ||
14055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          &pSectHdr == &file_format->getRelaPlt())
14065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_REL_PLT;
14075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_RELOCATION;
14085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // get the order from target for target specific sections
14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Target:
141122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return getTargetSectionOrder(pSectHdr);
14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // handle .interp and .note.* sections
14145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Note:
14156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (file_format->hasInterp() && (&pSectHdr == &file_format->getInterp()))
14166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_INTERP;
14176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      else if (is_write)
14186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_RW_NOTE;
14196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      else
14206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_RO_NOTE;
14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrame:
1423f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // set writable .eh_frame as relro
1424f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (is_write)
1425f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        return SHO_RELRO;
1426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrameHdr:
1427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::GCCExceptTable:
1428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_EXCEPTION;
14295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::MetaData:
14315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Debug:
14325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
14335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_UNDEFINED;
14345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize
14385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const
14395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold linker: symtab.cc: 2780
14415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // undefined and dynamic symbols should have zero size.
14425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined)
14435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
14445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.resolveInfo()->size();
14455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo
14485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const
14495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set binding
14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t bind = 0x0;
14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isLocal())
14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isGlobal())
14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isWeak())
14575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_WEAK;
14585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isAbsolute()) {
14595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // (Luba) Is a absolute but not global (weak or local) symbol meaningful?
14605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1463d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().codeGenType() != LinkerConfig::Object &&
1464d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
1465d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pSymbol.visibility() == llvm::ELF::STV_HIDDEN))
14665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t type = pSymbol.resolveInfo()->type();
1469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change
1470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // its type to Function
1471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn())
1472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    type = ResolveInfo::Function;
1473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (type | (bind << 4));
14745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout()
14775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const
14785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn())
14805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
14815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.value();
14835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout()
14865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t
148722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const
14885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isAbsolute())
14905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_ABS;
14915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isCommon())
14925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_COMMON;
14935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn())
14945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_UNDEF;
14955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSymbol.resolveInfo()->isLocal() &&
14976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      LinkerConfig::Object != config().codeGenType()) {
14985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch (pSymbol.type()) {
14995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case ResolveInfo::NoType:
15005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case ResolveInfo::File:
15015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return llvm::ELF::SHN_ABS;
15025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
15035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
15045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
150522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef())
150622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return llvm::ELF::SHN_ABS;
150722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSymbol.hasFragRef() && "symbols must have fragment reference to get its index");
150922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pSymbol.fragRef()->frag()->getParent()->getSection().index();
15105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index
15136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinessize_t GNULDBackend::getSymbolIdx(const LDSymbol* pSymbol) const
15145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
15156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   HashTableType::iterator entry = m_pSymIndexMap->find(const_cast<LDSymbol *>(pSymbol));
15166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   assert(entry != m_pSymIndexMap->end() && "symbol not found in the symbol table");
15175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao   return entry.getEntry()->value();
15185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isTemporary - Whether pSymbol is a local label.
15216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::isTemporary(const LDSymbol& pSymbol) const
15226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
15236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (ResolveInfo::Local != pSymbol.binding())
15246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
15256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSymbol.nameSize() < 2)
15276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
15286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const char* name = pSymbol.name();
15306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if ('.' == name[0] && 'L' == name[1])
15316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
15326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // UnixWare 2.1 cc generate DWARF debugging symbols with `..' prefix.
15346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name()
15356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (name[0] == '.' && name[1] == '.')
15366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
15376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Work arround for gcc's bug
15396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // gcc sometimes generate symbols with '_.L_' prefix.
15406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name()
15416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSymbol.nameSize() < 4)
15426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
15436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
15456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
15466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return false;
15486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
15496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding
155122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage.
1552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @refer Google gold linker: common.cc: 214
1553affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool
155422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::allocateCommonSymbols(Module& pModule)
15555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
155622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SymbolCategory& symbol_list = pModule.getSymbolTable();
1557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (symbol_list.emptyCommons() && symbol_list.emptyFiles() &&
15596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      symbol_list.emptyLocals() && symbol_list.emptyLocalDyns())
1560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
1563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: If the order of common symbols is defined, then sort common symbols
1565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // std::sort(com_sym, com_end, some kind of order);
1566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
156722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // get corresponding BSS LDSection
156822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
156922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& bss_sect = file_format->getBSS();
157022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& tbss_sect = file_format->getTBSS();
1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1572cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
157322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_sect_data = NULL;
157422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect.hasSectionData())
157522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = bss_sect.getSectionData();
157622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
157722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
157822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
157922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* tbss_sect_data = NULL;
158022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (tbss_sect.hasSectionData())
158122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = tbss_sect.getSectionData();
158222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
158322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
1584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
158622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t bss_offset  = bss_sect.size();
158722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t tbss_offset = tbss_sect.size();
1588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all local common symbols
1590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.localEnd();
1591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
1593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::Common == (*com_sym)->desc()) {
1594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // We have to reset the description of the symbol here. When doing
1595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // incremental linking, the output relocatable object may have common
1596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // symbols. Therefore, we can not treat common symbols as normal symbols
1597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // when emitting the regular name pools. We must change the symbols'
1598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // description here.
1599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1600cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
160122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
160522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        tbss_offset += ObjectBuilder::AppendFragment(*frag,
160622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     *tbss_sect_data,
160722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     (*com_sym)->value());
1608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      else {
161022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        bss_offset += ObjectBuilder::AppendFragment(*frag,
161122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    *bss_sect_data,
161222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    (*com_sym)->value());
1613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
16165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all global common symbols
1618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.commonEnd();
1619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
1620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // We have to reset the description of the symbol here. When doing
1621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // incremental linking, the output relocatable object may have common
1622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // symbols. Therefore, we can not treat common symbols as normal symbols
1623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // when emitting the regular name pools. We must change the symbols'
1624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // description here.
1625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1626cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
162722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
163122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tbss_offset += ObjectBuilder::AppendFragment(*frag,
163222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   *tbss_sect_data,
163322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   (*com_sym)->value());
1634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
163622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      bss_offset += ObjectBuilder::AppendFragment(*frag,
163722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  *bss_sect_data,
163822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  (*com_sym)->value());
1639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
164222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bss_sect.setSize(bss_offset);
164322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  tbss_sect.setSize(tbss_offset);
1644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  symbol_list.changeCommonsToGlobal();
1645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
16465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
16475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// updateSectionFlags - update pTo's flags when merging pFrom
16496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// update the output section flags based on input section flags.
16506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref The Google gold linker:
16516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines///      output.cc: 2809: Output_section::update_flags_for_input_section
16526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::updateSectionFlags(LDSection& pTo, const LDSection& pFrom)
16536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
16546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // union the flags from input
16556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t flags = pTo.flag();
16566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  flags |= (pFrom.flag() &
16576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              (llvm::ELF::SHF_WRITE |
16586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               llvm::ELF::SHF_ALLOC |
16596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               llvm::ELF::SHF_EXECINSTR));
16606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // if there is an input section is not SHF_MERGE, clean this flag
16626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (0 == (pFrom.flag() & llvm::ELF::SHF_MERGE))
16636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    flags &= ~llvm::ELF::SHF_MERGE;
16646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // if there is an input section is not SHF_STRINGS, clean this flag
16666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (0 == (pFrom.flag() & llvm::ELF::SHF_STRINGS))
16676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    flags &= ~llvm::ELF::SHF_STRINGS;
16686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  pTo.setFlag(flags);
16706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
16716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
16735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers
16746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::createProgramHdrs(Module& pModule)
16755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
167622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat *file_format = getOutputFormat();
1677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
16785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_PHDR
16795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_ELFSegmentTable.produce(llvm::ELF::PT_PHDR);
16805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_INTERP
1682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInterp()) {
16835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ELFSegment* interp_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_INTERP);
1684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    interp_seg->addSection(&file_format->getInterp());
1685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
168722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t cur_flag, prev_flag = getSegmentFlag(0);
16885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegment* load_seg = NULL;
16895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make possible PT_LOAD segments
1690f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::AddressMap::iterator addrEnd
1691f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                      = pModule.getScript().addressMap().end();
169222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator sect, sect_end = pModule.end();
169322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (sect = pModule.begin(); sect != sect_end; ++sect) {
1694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
16955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0 == ((*sect)->flag() & llvm::ELF::SHF_ALLOC) &&
16965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        LDFileFormat::Null != (*sect)->kind())
16975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
16985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
169922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    cur_flag = getSegmentFlag((*sect)->flag());
170022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bool createPT_LOAD = false;
170122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LDFileFormat::Null == (*sect)->kind()) {
170222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. create text segment
170322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
170422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
170522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if (!config().options().omagic() &&
170622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) {
170722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. create data segment if w/o omagic set
170822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
170922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
171022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if ((*sect)->kind() == LDFileFormat::BSS &&
171122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             load_seg->isDataSegment() &&
1712f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines             addrEnd != pModule.getScript().addressMap().find(".bss")) {
171322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 3. create bss segment if w/ -Tbss and there is a data segment
171422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
171522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
171622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
171722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((*sect != &(file_format->getText())) &&
171822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*sect != &(file_format->getData())) &&
171922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*sect != &(file_format->getBSS())) &&
1720f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          (addrEnd != pModule.getScript().addressMap().find((*sect)->name())))
172122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 4. create PT_LOAD for sections in address map except for text, data,
172222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // and bss
172322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        createPT_LOAD = true;
172422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
172622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (createPT_LOAD) {
172722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // create new PT_LOAD segment
172822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      load_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_LOAD, cur_flag);
17296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (!config().options().nmagic() && !config().options().omagic())
17306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        load_seg->setAlign(abiPageSize());
17315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
17325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != load_seg);
1734affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    load_seg->addSection((*sect));
173522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (cur_flag != prev_flag)
173622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      load_seg->updateFlag(cur_flag);
17375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
173822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    prev_flag = cur_flag;
17395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
17405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_DYNAMIC
1742affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasDynamic()) {
1743affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* dyn_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_DYNAMIC,
1744affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_R |
1745affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_W);
1746affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyn_seg->addSection(&file_format->getDynamic());
1747affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1748affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
174922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasRelro()) {
1750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // make PT_GNU_RELRO
1751affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* relro_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_RELRO);
175222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
175322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) {
175422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (llvm::ELF::PT_LOAD != (*seg).type())
175522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
175622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
175722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (ELFSegment::sect_iterator sect = (*seg).begin(),
175822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             sectEnd = (*seg).end(); sect != sectEnd; ++sect) {
175922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        unsigned int order = getSectionOrder(**sect);
176022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (SHO_RELRO_LOCAL == order ||
176122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            SHO_RELRO == order ||
176222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            SHO_RELRO_LAST == order) {
176322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          relro_seg->addSection(*sect);
176422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
1765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1766affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
17675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
17685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1769affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // make PT_GNU_EH_FRAME
1770affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasEhFrameHdr()) {
1771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* eh_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_EH_FRAME);
1772affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    eh_seg->addSection(&file_format->getEhFrameHdr());
1773affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
177422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
177522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_TLS
177622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasTData() || file_format->hasTBSS()) {
177722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFSegment* tls_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_TLS);
177822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTData())
177922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tls_seg->addSection(&file_format->getTData());
178022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTBSS())
178122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tls_seg->addSection(&file_format->getTBSS());
178222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
178322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
178422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_GNU_STACK
178522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasStackNote()) {
178622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_STACK,
178722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              llvm::ELF::PF_R |
178822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              llvm::ELF::PF_W |
178922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              getSegmentFlag(file_format->getStackNote().flag()));
179022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
179122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // make PT_NOTE
17936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFSegment *note_seg = NULL;
17946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  prev_flag = getSegmentFlag(0);
17956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (sect = pModule.begin(); sect != sect_end; ++sect) {
17966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if ((*sect)->kind() != LDFileFormat::Note ||
17976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        ((*sect)->flag() & llvm::ELF::SHF_ALLOC) == 0)
17986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      continue;
17996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
18006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    cur_flag = getSegmentFlag((*sect)->flag());
18016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // we have different section orders for read-only and writable notes, so
18026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create 2 segments if needed.
18036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (note_seg == NULL ||
18046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        (cur_flag & llvm::ELF::PF_W) != (prev_flag & llvm::ELF::PF_W))
18056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      note_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_NOTE, cur_flag);
18066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
18076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    note_seg->addSection(*sect);
18086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    prev_flag = cur_flag;
18096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
18106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
181122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // create target dependent segments
18126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  doCreateProgramHdrs(pModule);
1813affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1814affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments
1816f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::setupProgramHdrs(const LinkerScript& pScript)
1817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
18185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update segment info
1819f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  uint64_t seg_start_addr = getSegmentStartAddr(pScript);
18205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegmentFactory::iterator seg, seg_end = m_ELFSegmentTable.end();
18215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (seg = m_ELFSegmentTable.begin(); seg != seg_end; ++seg) {
18225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ELFSegment& segment = *seg;
18235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // update PT_PHDR
18255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (llvm::ELF::PT_PHDR == segment.type()) {
1826f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      uint64_t offset = 0, phdr_size = 0;
1827d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits()) {
18285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf32_Ehdr);
18295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
18305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
18315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else {
18325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf64_Ehdr);
18335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf64_Phdr);
18345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
18355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setOffset(offset);
1836f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      segment.setVaddr(seg_start_addr + offset);
18375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setPaddr(segment.vaddr());
18385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setFilesz(numOfSegments() * phdr_size);
18395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setMemsz(numOfSegments() * phdr_size);
1840d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      segment.setAlign(config().targets().bitclass() / 8);
18415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
18425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
18435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1844affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // bypass if there is no section in this segment (e.g., PT_GNU_STACK)
1845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (segment.numOfSections() == 0)
1846affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      continue;
1847affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
184822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    segment.setOffset(segment.front()->offset());
1849affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::PT_LOAD == segment.type() &&
185022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDFileFormat::Null == segment.front()->kind())
1851f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      segment.setVaddr(seg_start_addr);
1852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
185322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      segment.setVaddr(segment.front()->addr());
18545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setPaddr(segment.vaddr());
18555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
185622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const LDSection* last_sect = segment.back();
18575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != last_sect);
1858affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    uint64_t file_size = last_sect->offset() - segment.offset();
18595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (LDFileFormat::BSS != last_sect->kind())
18605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_size += last_sect->size();
18615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setFilesz(file_size);
18625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setMemsz(last_sect->addr() - segment.vaddr() + last_sect->size());
18645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
18655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
18665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
186722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
1868affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: layout.cc:2608
18696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::setupGNUStackInfo(Module& pModule)
18705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1871affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t flag = 0x0;
187222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasStackSet()) {
1873affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 1. check the command line option (-z execstack or -z noexecstack)
187422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasExecStack())
1875affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      flag = llvm::ELF::SHF_EXECINSTR;
187622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
187722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
1878affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2. check the stack info from the input objects
187922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // FIXME: since we alway emit .note.GNU-stack in output now, we may be able
188022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // to check this from the output .note.GNU-stack directly after section
188122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // merging is done
1882affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    size_t object_count = 0, stack_note_count = 0;
188322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::const_obj_iterator obj, objEnd = pModule.obj_end();
188422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (obj = pModule.obj_begin(); obj != objEnd; ++obj) {
188522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++object_count;
188622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack");
188722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL != sect) {
188822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++stack_note_count;
188922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 2.1 found a stack note that is set as executable
189022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) {
189122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          flag = llvm::ELF::SHF_EXECINSTR;
189222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
1893affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
1894affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1895affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
18965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1897affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.2 there are no stack note sections in all input objects
1898affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (0 == stack_note_count)
1899affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
19005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1901affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.3 a special case. Use the target default to decide if the stack should
1902affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //     be executable
1903affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count)
19046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (m_pInfo->isDefaultExecStack())
1905affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        flag = llvm::ELF::SHF_EXECINSTR;
19065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
19075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
190822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasStackNote()) {
190922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    getOutputFormat()->getStackNote().setFlag(flag);
191022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
191122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
191222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
191322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupRelro - setup the offset constraint of PT_RELRO
191422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupRelro(Module& pModule)
191522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
191622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(config().options().hasRelro());
191722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if -z relro is given, we need to adjust sections' offset again, and let
191822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // PT_GNU_RELRO end on a common page boundary
191922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
192022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator sect = pModule.begin();
192122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (Module::iterator sect_end = pModule.end(); sect != sect_end; ++sect) {
192222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // find the first non-relro section
192322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (getSectionOrder(**sect) > SHO_RELRO_LAST)
192422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
192522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
192622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
192722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // align the first non-relro section to page boundary
192822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t offset = (*sect)->offset();
192922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  alignAddress(offset, commonPageSize());
193022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  (*sect)->setOffset(offset);
193122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
193222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // It seems that compiler think .got and .got.plt are continuous (w/o any
193322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // padding between). If .got is the last section in PT_RELRO and it's not
193422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // continuous to its next section (i.e. .got.plt), we need to add padding
193522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // in front of .got instead.
193622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // FIXME: Maybe we can handle this in a more general way.
193722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& got = getOutputFormat()->getGOT();
193822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if ((getSectionOrder(got) == SHO_RELRO_LAST) &&
193922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      (got.offset() + got.size() != offset)) {
194022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    got.setOffset(offset - got.size());
194122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
194222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
194322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up remaining section's offset
194422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  setOutputSectionOffset(pModule, ++sect, pModule.end());
194522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
194622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
194722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set a group of output sections'
194822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// offset, and set pSectBegin to pStartOffset if pStartOffset is not -1U.
194922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setOutputSectionOffset(Module& pModule,
195022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          Module::iterator pSectBegin,
195122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          Module::iterator pSectEnd,
195222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          uint64_t pStartOffset)
195322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
195422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSectBegin == pModule.end())
195522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
195622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
195722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(pSectEnd == pModule.end() ||
195822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         (pSectEnd != pModule.end() &&
195922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*pSectBegin)->index() <= (*pSectEnd)->index()));
196022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
196122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pStartOffset != -1U) {
196222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*pSectBegin)->setOffset(pStartOffset);
196322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++pSectBegin;
196422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
196522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
196622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up the "cur" and "prev" iterator
196722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator cur = pSectBegin;
196822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator prev = pSectBegin;
196922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (cur != pModule.begin())
197022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    --prev;
1971affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
197222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++cur;
197322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
197422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (; cur != pSectEnd; ++cur, ++prev) {
197522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint64_t offset = 0x0;
197622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch ((*prev)->kind()) {
197722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Null:
197822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        offset = sectionStartOffset();
197922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
198022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::BSS:
198122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        offset = (*prev)->offset();
198222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
198322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
198422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        offset = (*prev)->offset() + (*prev)->size();
198522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
198622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
198722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
198822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    alignAddress(offset, (*cur)->align());
198922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    (*cur)->setOffset(offset);
199022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
199122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
199222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
199322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set output sections' address
19946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::setOutputSectionAddress(Module& pModule,
199522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           Module::iterator pSectBegin,
199622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                           Module::iterator pSectEnd)
199722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
199822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSectBegin == pModule.end())
199922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
200022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
200122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(pSectEnd == pModule.end() ||
200222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         (pSectEnd != pModule.end() &&
200322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*pSectBegin)->index() <= (*pSectEnd)->index()));
200422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2005f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  const LinkerScript& script = pModule.getScript();
2006f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  uint64_t seg_start_addr = getSegmentStartAddr(script);
200722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
200822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         segEnd = elfSegmentTable().end(), prev = elfSegmentTable().end();
200922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao       seg != segEnd; prev = seg, ++seg) {
201022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (llvm::ELF::PT_LOAD != (*seg).type())
201122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
201222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
201322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint64_t start_addr = 0x0;
2014f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    LinkerScript::AddressMap::const_iterator mapping;
201522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((*seg).front()->kind() == LDFileFormat::Null)
2016f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      mapping = script.addressMap().find(".text");
201722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if ((*seg).isDataSegment())
2018f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      mapping = script.addressMap().find(".data");
201922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if ((*seg).isBssSegment())
2020f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      mapping = script.addressMap().find(".bss");
202122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
2022f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      mapping = script.addressMap().find((*seg).front()->name());
202322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2024f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (mapping != script.addressMap().end()) {
20256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // use address mapping in script options
202622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      start_addr = mapping.getEntry()->value();
202722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
202822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
202922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((*seg).front()->kind() == LDFileFormat::Null) {
203022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 1st PT_LOAD
2031f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        start_addr = seg_start_addr;
203222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
203322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else if ((*prev).front()->kind() == LDFileFormat::Null) {
203422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // prev segment is 1st PT_LOAD
2035f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        start_addr = seg_start_addr + (*seg).front()->offset();
203622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
203722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else {
203822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // Others
203922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        start_addr = (*prev).front()->addr() + (*seg).front()->offset();
204022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
20416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Try to align p_vaddr at page boundary if not in script options.
20426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // To do so will add more padding in file, but can save one page
20436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // at runtime.
20446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      alignAddress(start_addr, (*seg).align());
20456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
204622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
20476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf
20486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // p_align: As "Program Loading" describes in this chapter of the
20496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // processor supplement, loadable process segments must have congruent
20506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // values for p_vaddr and p_offset, modulo the page size.
20516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if ((start_addr & ((*seg).align() - 1)) !=
20526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        ((*seg).front()->offset() & ((*seg).align() - 1))) {
20536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint64_t padding = (*seg).align() +
20546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         (start_addr & ((*seg).align() - 1)) -
20556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         ((*seg).front()->offset() & ((*seg).align() - 1));
20566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      setOutputSectionOffset(pModule,
20576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                             pModule.begin() + (*seg).front()->index(),
20586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                             pModule.end(),
20596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                             (*seg).front()->offset() + padding);
20606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (config().options().hasRelro())
20616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        setupRelro(pModule);
206222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
206322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
206422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (ELFSegment::sect_iterator sect = (*seg).begin(),
206522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao           sectEnd = (*seg).end(); sect != sectEnd; ++sect) {
206622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((*sect)->index() < (*pSectBegin)->index())
206722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
206822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
206922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (LDFileFormat::Null == (*sect)->kind())
207022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
207122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
207222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (sect == pSectEnd)
207322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return;
207422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
207522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (sect != (*seg).begin())
207622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*sect)->setAddr(start_addr + (*sect)->offset() -
207722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                         (*seg).front()->offset());
207822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      else
207922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (*sect)->setAddr(start_addr);
208022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
208122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
20825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
20835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2084d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// layout - layout method
20856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::layout(Module& pModule)
2086d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
2087d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::vector<SHOEntry> output_list;
2088d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 1. determine what sections will go into final output, and push the needed
2089d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // sections into output_list for later processing
2090d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie;
2091d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       ++it) {
2092d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    switch ((*it)->kind()) {
20936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // take NULL and StackNote directly
20946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Null:
20956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::StackNote:
20966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
20976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
20986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // ignore if section size is 0
20996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::EhFrame:
21006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (((*it)->size() != 0) ||
21016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ((*it)->hasEhFrame() &&
21026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines           config().codeGenType() == LinkerConfig::Object))
2103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
21046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
21056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Relocation:
21066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (((*it)->size() != 0) ||
21076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ((*it)->hasRelocData() &&
21086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines           config().codeGenType() == LinkerConfig::Object))
21096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
21106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
21116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Regular:
21126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Target:
21136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::MetaData:
21146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::BSS:
21156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Debug:
21166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::GCCExceptTable:
21176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Note:
21186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::NamePool:
21196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::EhFrameHdr:
21206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (((*it)->size() != 0) ||
21216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ((*it)->hasSectionData() &&
21226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines           config().codeGenType() == LinkerConfig::Object))
21236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
21246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
21256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Group:
21266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (LinkerConfig::Object == config().codeGenType()) {
21276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        //TODO: support incremental linking
21286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        ;
21296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
21306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
21316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Version:
21326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (0 != (*it)->size()) {
21336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        output_list.push_back(std::make_pair(*it, getSectionOrder(**it)));
21346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name();
21356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
21366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
21376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    default:
21386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (0 != (*it)->size()) {
21396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        error(diag::err_unsupported_section) << (*it)->name() << (*it)->kind();
21406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
21416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
2142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
2143d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  } // end of for
2144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 2. sort output section orders
2146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::stable_sort(output_list.begin(), output_list.end(), SHOCompare());
2147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 3. update output sections in Module
2149d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pModule.getSectionTable().clear();
2150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  for(size_t index = 0; index < output_list.size(); ++index) {
2151d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    (output_list[index].first)->setIndex(index);
2152d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    pModule.getSectionTable().push_back(output_list[index].first);
2153d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
2154d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2155d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 4. create program headers
2156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
21576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    createProgramHdrs(pModule);
2158d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
2159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2160d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 5. set output section offset
2161d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  setOutputSectionOffset(pModule, pModule.begin(), pModule.end(), 0x0);
2162d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
2163d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
21645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// preLayout - Backend can do any needed modification before layout
21656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::preLayout(Module& pModule, IRBuilder& pBuilder)
21665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
21675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // prelayout target first
21686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  doPreLayout(pBuilder);
2169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
21706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType() &&
21716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // init EhFrameHdr and size the output section
217322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* format = getOutputFormat();
217422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pEhFrameHdr = new EhFrameHdr(format->getEhFrameHdr(),
217522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   format->getEhFrame());
2176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr->sizeOutput();
2177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
217822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // change .tbss and .tdata section symbol from Local to LocalDyn category
218022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pTDATA)
2181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pModule.getSymbolTable().changeToDynamic(*f_pTDATA);
218222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
218322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pTBSS)
2184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pModule.getSymbolTable().changeToDynamic(*f_pTBSS);
218522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
218622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // To merge input's relocation sections into output's relocation sections.
218722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //
218822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are generating relocatables (-r), move input relocation sections
218922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // to corresponding output relocation sections.
219022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
219122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::obj_iterator input, inEnd = pModule.obj_end();
219222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (input = pModule.obj_begin(); input != inEnd; ++input) {
219322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
219422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
219522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
219622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the output relocation LDSection with identical name.
219722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_sect = pModule.getSection((*rs)->name());
219822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == output_sect) {
219922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect = LDSection::Create((*rs)->name(),
220022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->kind(),
220122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->type(),
220222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->flag());
220322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
220422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setAlign((*rs)->align());
220522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          pModule.getSectionTable().push_back(output_sect);
220622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
220722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
220822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // set output relocation section link
220922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        const LDSection* input_link = (*rs)->getLink();
221022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != input_link && "Illegal input relocation section.");
221122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
221222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the linked output section
221322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_link = pModule.getSection(input_link->name());
221422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != output_link);
221522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
221622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        output_sect->setLink(output_link);
221722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
221822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get output relcoationData, create one if not exist
221922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!output_sect->hasRelocData())
222022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          IRBuilder::CreateRelocData(*output_sect);
222122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
222222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        RelocData* out_reloc_data = output_sect->getRelocData();
222322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
222422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // move relocations from input's to output's RelcoationData
2225d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& out_list =
2226d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                             out_reloc_data->getRelocationList();
2227d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& in_list =
2228d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      (*rs)->getRelocData()->getRelocationList();
222922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        out_list.splice(out_list.end(), in_list);
223022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
223122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // size output
223222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (llvm::ELF::SHT_REL == output_sect->type())
223322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelEntrySize());
223422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else if (llvm::ELF::SHT_RELA == output_sect->type())
223522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelaEntrySize());
223622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else {
223722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          fatal(diag::unknown_reloc_section_type) << output_sect->type()
223822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << output_sect->name();
223922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
224022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // end of for each relocation section
224122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // end of for each input
224222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of if
224322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
224422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up the section flag of .note.GNU-stack section
22456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  setupGNUStackInfo(pModule);
22465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
22475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2248cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout
22496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::postLayout(Module& pModule, IRBuilder& pBuilder)
22505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2251d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 1. set up section address and segment attributes
225222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
225322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasRelro()) {
2254d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // 1.1 set up the offset constraint of PT_RELRO
225522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setupRelro(pModule);
225622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
225722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2258d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // 1.2 set up the output sections' address
22596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    setOutputSectionAddress(pModule, pModule.begin(), pModule.end());
226022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2261d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // 1.3 do relaxation
22626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relax(pModule, pBuilder);
2263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2264d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // 1.4 set up the attributes of program headers
2265f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    setupProgramHdrs(pModule.getScript());
2266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 2. target specific post layout
22696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  doPostLayout(pModule, pBuilder);
22705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
22715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
22726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::postProcessing(MemoryArea& pOutput)
2273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
22746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType() &&
22756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // emit eh_frame_hdr
2277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pEhFrameHdr->emitOutput<32>(pOutput);
2278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
22815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count.
22825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker, dynobj.cc:791
22835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols,
22845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          bool pIsGNUStyle)
22855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
22865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold, dynobj.cc:loc 791
22875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static const unsigned int buckets[] =
22885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
22895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
22905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    16411, 32771, 65537, 131101, 262147
22915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
22925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const unsigned buckets_count = sizeof buckets / sizeof buckets[0];
22935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
22945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int result = 1;
22955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (unsigned i = 0; i < buckets_count; ++i) {
22965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pNumOfSymbols < buckets[i])
22975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
22985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = buckets[i];
22995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
23005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pIsGNUStyle && result < 2)
23025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = 2;
23035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
23055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
23065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
23086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref binutils gold, dynobj.cc:1165
23096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned GNULDBackend::getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const
23106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
23116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbitslog2 = 1;
23126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (uint32_t x = pNumOfSymbols >> 1; x != 0; x >>=1)
23136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++maskbitslog2;
23146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
23156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (maskbitslog2 < 3)
23166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 = 5;
23176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (((1U << (maskbitslog2 - 2)) & pNumOfSymbols) != 0)
23186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 += 3;
23196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
23206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 += 2;
23216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
23226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().bitclass() == 64 && maskbitslog2 == 5)
23236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 = 6;
23246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
23256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return maskbitslog2;
23266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
23276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
23285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol
23295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker: symtab.cc:311
233022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol)
23315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
23325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
23335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // symbol. We should not add it
23345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.binding() == ResolveInfo::Local)
23355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
23365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If we are building shared object, and the visibility is external, we
23385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // need to add it.
233922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
2340d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Exec   == config().codeGenType() ||
2341d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
23425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default ||
23436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected)
23445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return true;
234522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
234622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
234722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
234822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
234922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol
235022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker: symtab.cc:311
235122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo)
235222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
235322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
235422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol. We should not add it
235522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pResolveInfo.binding() == ResolveInfo::Local)
235622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
235722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
235822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are building shared object, and the visibility is external, we
235922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // need to add it.
236022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
2361d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Exec   == config().codeGenType() ||
2362d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
236322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (pResolveInfo.visibility() == ResolveInfo::Default ||
23646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        pResolveInfo.visibility() == ResolveInfo::Protected)
236522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
236622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
2368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine.
2371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:135
237222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::commonPageSize() const
2373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
237422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().commPageSize() > 0)
237522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return std::min(config().options().commPageSize(), abiPageSize());
2376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
23776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return std::min(m_pInfo->commonPageSize(), abiPageSize());
2378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine.
2381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:125
238222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::abiPageSize() const
2383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
238422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().maxPageSize() > 0)
238522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return config().options().maxPageSize();
2386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
23876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_pInfo->abiPageSize();
2388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other
2391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit
2392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:551
239322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const
2394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
2395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.other() != ResolveInfo::Default)
2396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
239822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This is because the codeGenType of pie is DynObj. And gold linker check
239922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the "shared" option instead.
240022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
240122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
240222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
240322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj != config().codeGenType())
240422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
240522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
240622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().Bsymbolic())
2407affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2408affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
240922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // A local defined symbol should be non-preemptible.
241022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32
241122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relocation refers to a local defined symbol, and we should generate a
241222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relative dynamic relocation when applying the relocation.
241322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local)
2414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2415affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
2417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2418affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
241922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
242022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, symtab.h:645
24216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsDynRel(const ResolveInfo& pSym,
242222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     bool pSymHasPLT,
242322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     bool isAbsReloc) const
242422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
242522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // an undefined reference in the executables should be statically
242622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // resolved to 0 and no need a dynamic relocation
242722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isUndef() &&
242822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !pSym.isDyn() &&
2429d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::Exec   == config().codeGenType() ||
2430d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary == config().codeGenType()))
243122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
243222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // An absolute symbol can be resolved directly if it is either local
24346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // or we are linking statically. Otherwise it can still be overridden
24356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // at runtime.
24366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSym.isAbsolute() &&
24376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (pSym.binding() == ResolveInfo::Local || config().isCodeStatic()))
243822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
24396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() && isAbsReloc)
244022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
244122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymHasPLT && ResolveInfo::Function == pSym.type())
244222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
24436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().isCodeIndep() && pSymHasPLT)
244422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
244522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDyn() || pSym.isUndef() ||
244622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      isSymbolPreemptible(pSym))
244722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
244822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
244922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
245022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
245122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry
2453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:596
24546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsPLT(const ResolveInfo& pSym) const
2455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
245622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isUndef() &&
245722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !pSym.isDyn() &&
245822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LinkerConfig::DynObj != config().codeGenType())
2459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry
2462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() == ResolveInfo::IndirectFunc)
2463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() != ResolveInfo::Function)
2466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
24686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeStatic())
246922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
247022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
247122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
2472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (pSym.isDyn() ||
2475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          pSym.isUndef() ||
247622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          isSymbolPreemptible(pSym));
2477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
247922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at
248022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time
248122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, Symbol::final_value_is_known
24826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolFinalValueIsKnown(const ResolveInfo& pSym) const
2483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
248422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the output is pic code or if not executables, symbols' value may change
248522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // at runtime
24866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: CodeIndep() || LinkerConfig::Relocatable == CodeGenType
24876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() ||
2488d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::Exec != config().codeGenType() &&
2489d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary != config().codeGenType()))
2490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
249122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
249222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is from dynamic object, then its value is unknown
249322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDyn())
2494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
249522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
249622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is not in dynamic object and is not undefined, then its value
249722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // is known
249822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSym.isUndef())
2499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
250122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is undefined and not in dynamic objects, for example, a weak
250222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // undefined symbol, then whether the symbol's final value can be known
250322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // depends on whrther we're doing static link
25046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return config().isCodeStatic();
2505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
25086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsCopyReloc(const Relocation& pReloc,
250922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                        const ResolveInfo& pSym) const
2510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
2511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // only the reference from dynamic executable to non-function symbol in
2512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // the dynamic objects may need copy relocation
25136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() ||
2514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !pSym.isDyn() ||
2515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.type() == ResolveInfo::Function ||
2516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.size() == 0)
2517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // check if the option -z nocopyreloc is given
252022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasNoCopyReloc())
2521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // TODO: Is this check necessary?
2524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if relocation target place is readonly, a copy relocation is needed
252522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag();
252622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE))
2527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
25285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
25295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
25305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
253222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTDATASymbol()
253322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
253422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTDATA);
253522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
253622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
253722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
253822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTDATASymbol() const
253922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
254022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTDATA);
254122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
254222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
254322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
254422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTBSSSymbol()
254522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
254622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTBSS);
254722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
254822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
254922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
255022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTBSSSymbol() const
255122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
255222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTBSS);
255322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
255422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
255522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
255622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection)
255722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
255822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_bHasTextRel)
255922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
256022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
256122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the target section of the dynamic relocation is ALLOCATE but is not
256222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // writable, than we should set DF_TEXTREL
256322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const uint32_t flag = pSection.flag();
256422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC))
256522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasTextRel = true;
256622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
256722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return;
256822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
256922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
257022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation
257122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initBRIslandFactory()
257222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
257322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pBRIslandFactory) {
257422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pBRIslandFactory = new BranchIslandFactory(maxBranchOffset());
257522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
257622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
257722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
257822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
257922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation
258022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStubFactory()
258122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
258222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pStubFactory) {
258322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pStubFactory = new StubFactory();
258422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
258522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
258622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
258722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::relax(Module& pModule, IRBuilder& pBuilder)
258922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
259022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!mayRelax())
259122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
259222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
259322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool finished = true;
259422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  do {
25956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (doRelax(pModule, pBuilder, finished)) {
259622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // If the sections (e.g., .text) are relaxed, the layout is also changed
259722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // We need to do the following:
259822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
259922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. set up the offset
260022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      setOutputSectionOffset(pModule, pModule.begin(), pModule.end());
260122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
260222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. set up the offset constraint of PT_RELRO
260322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (config().options().hasRelro())
260422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        setupRelro(pModule);
260522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
260622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 3. set up the output sections' address
26076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      setOutputSectionAddress(pModule, pModule.begin(), pModule.end());
260822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
260922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } while (!finished);
261022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
261122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
261222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
261322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::needGNUHash(const LDSymbol& X) const
26156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
26166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: in bfd and gold linker, an undefined symbol might be hashed
26176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // when the ouput is not PIC, if the symbol is referred by a non pc-relative
26186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // reloc, and its value is set to the addr of the plt entry.
26196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return !X.resolveInfo()->isUndef() && !X.isDyn();
26206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
26216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
26226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::operator()(const LDSymbol* X,
26236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             const LDSymbol* Y) const
26246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
26256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return !needGNUHash(*X) && needGNUHash(*Y);
26266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
26276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2628