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
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h>
1387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LinkerScript.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h>
16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Config/Config.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h>
18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/LDSymbol.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrameHdr.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h>
23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocationFactory.h>
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIslandFactory.h>
2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFSegmentFactory.h>
2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFSegment.h>
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/StubFactory.h>
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFFileFormat.h>
2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFObjectFileFormat.h>
3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFDynObjFileFormat.h>
3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFExecFileFormat.h>
3287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Target/ELFAttribute.h>
3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Target/ELFDynamic.h>
3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Target/GNUInfo.h>
3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/FileOutputBuffer.h>
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/MsgHandling.h>
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Object/SectionMap.h>
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/RpnEvaluator.h>
4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/Operand.h>
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/OutputSectDesc.h>
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Fragment/FillFragment.h>
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/MC/Attribute.h>
4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
45a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <llvm/ADT/StringRef.h>
4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Host.h>
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
48a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <algorithm>
49a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <cstring>
50a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <cassert>
51a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <map>
52a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <string>
53a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <vector>
54a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace {
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===--------------------------------------------------------------------===//
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesstatic const std::string simple_c_identifier_allowed_chars =
61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "0123456789"
62f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "ABCDEFGHIJKLMNOPWRSTUVWXYZ"
63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "abcdefghijklmnopqrstuvwxyz"
64f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  "_";
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatic bool isCIdentifier(const std::string& pName)
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return (pName.find_first_not_of(simple_c_identifier_allowed_chars)
70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines              == std::string::npos);
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} // anonymous namespace
74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesusing namespace mcld;
76f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend
79cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
80d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : TargetLDBackend(pConfig),
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pObjectReader(NULL),
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pDynObjFileFormat(NULL),
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pExecFileFormat(NULL),
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pObjectFileFormat(NULL),
86d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_pInfo(pInfo),
8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    m_pELFSegmentTable(NULL),
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pBRIslandFactory(NULL),
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pStubFactory(NULL),
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr(NULL),
9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    m_pAttribute(NULL),
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasTextRel(false),
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasStaticTLS(false),
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayStart(NULL),
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayEnd(NULL),
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayStart(NULL),
97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayEnd(NULL),
98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayStart(NULL),
99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayEnd(NULL),
100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pStack(NULL),
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic(NULL),
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pTDATA(NULL),
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pTBSS(NULL),
104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pExecutableStart(NULL),
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEText(NULL),
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EText(NULL),
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p__EText(NULL),
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEData(NULL),
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EData(NULL),
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pBSSStart(NULL),
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEnd(NULL),
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_End(NULL) {
11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pELFSegmentTable = new ELFSegmentFactory();
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pSymIndexMap = new HashTableType(1024);
11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pAttribute = new ELFAttribute(*this, pConfig);
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::~GNULDBackend()
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  delete m_pELFSegmentTable;
121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pInfo;
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynObjFileFormat;
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pExecFileFormat;
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pObjectFileFormat;
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pSymIndexMap;
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pEhFrameHdr;
12787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  delete m_pAttribute;
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pBRIslandFactory;
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pStubFactory;
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::sectionStartOffset() const
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Binary == config().codeGenType())
135d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return 0x0;
136d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
137d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (config().targets().bitclass()) {
138d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 32u:
139d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf32_Ehdr) +
14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             elfSegmentTable().size() * sizeof(llvm::ELF::Elf32_Phdr);
141d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 64u:
142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf64_Ehdr) +
14387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             elfSegmentTable().size() * sizeof(llvm::ELF::Elf64_Phdr);
144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default:
145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      fatal(diag::unsupported_bitclass) << config().targets().triple().str()
146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        << config().targets().bitclass();
147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return 0;
148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesuint64_t GNULDBackend::getSegmentStartAddr(const LinkerScript& pScript) const
152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::AddressMap::const_iterator mapping =
154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pScript.addressMap().find(".text");
155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pScript.addressMap().end() != mapping)
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return mapping.getEntry()->value();
1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (config().isCodeIndep())
158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return 0x0;
159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_pInfo->defaultTextSegmentAddr();
161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader*
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::createArchiveReader(Module& pModule)
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != m_pObjectReader);
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new GNUArchiveReader(pModule, *m_pObjectReader);
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
170d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder)
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
172d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_pObjectReader = new ELFObjectReader(*this, pBuilder, config());
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_pObjectReader;
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
176d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder)
177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFDynObjReader(*this, pBuilder, config());
179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
180d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
181d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder)
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
18387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return new ELFBinaryReader(pBuilder, config());
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter* GNULDBackend::createWriter()
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
188d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFObjectWriter(*this, config());
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStdSections(ObjectBuilder& pBuilder)
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pDynObjFileFormat)
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pDynObjFileFormat = new ELFDynObjFileFormat();
197d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pDynObjFileFormat->initStdSections(pBuilder,
198d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
201d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
202d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pExecFileFormat)
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pExecFileFormat = new ELFExecFileFormat();
205d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pExecFileFormat->initStdSections(pBuilder,
206d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         config().targets().bitclass());
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL == m_pObjectFileFormat)
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pObjectFileFormat = new ELFObjectFileFormat();
212d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pObjectFileFormat->initStdSections(pBuilder,
213d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return false;
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols.
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations.
2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::initStandardSymbols(IRBuilder& pBuilder,
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       Module& pModule)
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // GNU extension: define __start and __stop symbols for the sections whose
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name can be presented as C symbol
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ref: GNU gold, Layout::define_section_symbols
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator iter, iterEnd = pModule.end();
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (iter = pModule.begin(); iter != iterEnd; ++iter) {
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection* section = *iter;
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch (section->kind()) {
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame:
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasEhFrame())
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasSectionData())
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // end of switch
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isCIdentifier(section->name())) {
251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      std::string start_name = "__start_" + section->name();
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      FragmentRef* start_fragref = FragmentRef::Create(
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                       section->getSectionData()->front(), 0x0);
2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    start_name,
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::NoType,
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Define,
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Global,
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // size
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // value
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    start_fragref, // FragRef
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Default);
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
264f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      std::string stop_name = "__stop_" + section->name();
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      FragmentRef* stop_fragref = FragmentRef::Create(
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           section->getSectionData()->front(), section->size());
2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                    stop_name,
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::NoType,
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Define,
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Global,
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // size
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    0x0, // value
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    stop_fragref, // FragRef
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    ResolveInfo::Default);
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .preinit_array
283cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* preinit_array = NULL;
284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasPreInitArray()) {
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Create(
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                   file_format->getPreInitArray().getSectionData()->front(),
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                   0x0);
288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Null();
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayStart =
2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__preinit_array_start",
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             preinit_array, // FragRef
301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayEnd =
3036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__preinit_array_end",
305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .init_array
314cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* init_array = NULL;
315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInitArray()) {
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Create(
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      file_format->getInitArray().getSectionData()->front(),
318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0);
319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Null();
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayStart =
3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__init_array_start",
327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
334affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayEnd =
3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__init_array_end",
337affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .fini_array
346cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* fini_array = NULL;
347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasFiniArray()) {
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Create(
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     file_format->getFiniArray().getSectionData()->front(),
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     0x0);
351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Null();
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayStart =
3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__fini_array_start",
359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
365affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayEnd =
3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__fini_array_end",
369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .stack
378cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* stack = NULL;
379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasStack()) {
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Create(
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          file_format->getStack().getSectionData()->front(),
382affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          0x0);
383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Null();
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pStack =
3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__stack",
391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             stack, // FragRef
397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // _DYNAMIC
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO: add SectionData for .dynamic section, and then we can get the correct
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol section index for _DYNAMIC. Now it will be ABS.
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  f_pDynamic =
4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                                   "_DYNAMIC",
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Object,
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Define,
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Local,
40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   0x0, // size
40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   0x0, // value
41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   FragmentRef::Null(), // FragRef
41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   ResolveInfo::Hidden);
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pExecutableStart =
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__executable_start",
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_pEText =
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_p_EText =
4356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "_etext",
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  f_p__EText =
4456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__etext",
447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEData =
4556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "edata",
457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEnd =
4666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
4676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "end",
468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _edata is defined forcefully.
477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 186
478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_EData =
4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "_edata",
481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // __bss_start is defined forcefully.
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 214
491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pBSSStart =
4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "__bss_start",
494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _end is defined forcefully.
503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 228
504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_End =
5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             "_end",
507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             FragmentRef::Null(), // FragRef
513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::finalizeStandardSymbols()
519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayStart) {
527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pPreInitArrayStart->hasFragRef()) {
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->setValue(0x0);
530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayEnd) {
534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pPreInitArrayEnd->hasFragRef()) {
535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() +
536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   file_format->getPreInitArray().size());
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(0x0);
541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayStart) {
545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pInitArrayStart->hasFragRef()) {
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->setValue(0x0);
548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayEnd) {
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pInitArrayEnd->hasFragRef()) {
553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() +
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getInitArray().size());
555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(0x0);
559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayStart) {
563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pFiniArrayStart->hasFragRef()) {
564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->setValue(0x0);
566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayEnd) {
570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pFiniArrayEnd->hasFragRef()) {
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() +
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getFiniArray().size());
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(0x0);
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pStack) {
581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pStack->hasFragRef()) {
582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute);
583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->setValue(0x0);
584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
58722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pDynamic) {
58822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local);
58922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setValue(file_format->getDynamic().addr());
59022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setSize(file_format->getDynamic().size());
59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
59222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pExecutableStart) {
59587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::const_iterator exec_start =
59687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      elfSegmentTable().find(llvm::ELF::PT_LOAD, 0x0, 0x0);
59787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (elfSegmentTable().end() != exec_start) {
598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) {
599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pExecutableStart->setValue(f_pExecutableStart->value() +
60087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                     (*exec_start)->vaddr());
601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pExecutableStart->setValue(0x0);
605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEText || NULL != f_p_EText || NULL !=f_p__EText) {
60887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::const_iterator etext =
60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      elfSegmentTable().find(llvm::ELF::PT_LOAD,
61087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                             llvm::ELF::PF_X,
61187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                             llvm::ELF::PF_W);
61287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (elfSegmentTable().end() != etext) {
613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText && ResolveInfo::ThreadLocal != f_pEText->type()) {
614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(f_pEText->value() +
61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                           (*etext)->vaddr() +
61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                           (*etext)->memsz());
617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText && ResolveInfo::ThreadLocal != f_p_EText->type()) {
619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(f_p_EText->value() +
62087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*etext)->vaddr() +
62187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*etext)->memsz());
622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText && ResolveInfo::ThreadLocal != f_p__EText->type()) {
624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(f_p__EText->value() +
62587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*etext)->vaddr() +
62687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*etext)->memsz());
627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText)
631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(0x0);
632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText)
633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(0x0);
634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText)
635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(0x0);
636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEData || NULL != f_p_EData || NULL != f_pBSSStart ||
640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      NULL != f_pEnd || NULL != f_p_End) {
64187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::const_iterator edata =
64287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      elfSegmentTable().find(llvm::ELF::PT_LOAD, llvm::ELF::PF_W, 0x0);
64387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (elfSegmentTable().end() != edata) {
644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) {
645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(f_pEData->value() +
64687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                           (*edata)->vaddr() +
64787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                           (*edata)->filesz());
648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) {
650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(f_p_EData->value() +
65187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*edata)->vaddr() +
65287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*edata)->filesz());
653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart && ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(f_pBSSStart->value() +
65687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              (*edata)->vaddr() +
65787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              (*edata)->filesz());
658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) {
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(f_pEnd->value() +
66287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (*edata)->vaddr() +
66387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (*edata)->memsz());
664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) {
666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(f_p_End->value() +
66787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          (*edata)->vaddr() +
66887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          (*edata)->memsz());
669affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData)
673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(0x0);
674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData)
675affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(0x0);
676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart)
677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(0x0);
678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd)
680affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(0x0);
681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End)
682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(0x0);
683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol)
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ignore if symbol has no fragRef
69222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSymbol.hasFragRef())
69322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the value of a TLS symbol is the offset to the TLS segment
69687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator tls_seg =
69787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    elfSegmentTable().find(llvm::ELF::PT_TLS, llvm::ELF::PF_R, 0x0);
69887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(tls_seg != elfSegmentTable().end());
69922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t value = pSymbol.fragRef()->getOutputOffset();
70022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t addr  = pSymbol.fragRef()->frag()->getParent()->getSection().addr();
70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymbol.setValue(value + addr - (*tls_seg)->vaddr());
70222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFFileFormat* GNULDBackend::getOutputFormat()
706affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
70722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
70822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
70922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pDynObjFileFormat);
71022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
712d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pExecFileFormat);
71422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
71522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pObjectFileFormat);
71722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
718affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
71922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
721affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
722affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
723affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst ELFFileFormat* GNULDBackend::getOutputFormat() const
725affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pDynObjFileFormat);
72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
731d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pExecFileFormat);
73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      assert(NULL != m_pObjectFileFormat);
73622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
737affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
739affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
740affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
741affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
742affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
74387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sizeShstrtab - compute the size of .shstrtab
74487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::sizeShstrtab(Module& pModule)
74587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
74687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t shstrtab = 0;
74787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // compute the size of .shstrtab section.
74887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::const_iterator sect, sectEnd = pModule.end();
74987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
75087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    shstrtab += (*sect)->name().size() + 1;
75187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // end of for
75287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  getOutputFormat()->getShStrTab().setSize(shstrtab);
75387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
75487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab,
75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab.
758f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::sizeNamePools(Module& pModule)
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
760f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(LinkerConfig::Unset != config().codePosition());
761f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // number of entries in symbol tables starts from 1 to hold the special entry
7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t symtab = 1;
765f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t dynsym = config().isCodeStatic()? 0 : 1;
76622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
76722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // size of string tables starts from 1 to hold the null character in their
76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // first byte
7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t strtab   = 1;
770f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t dynstr   = config().isCodeStatic()? 0 : 1;
7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t hash     = 0;
7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t gnuhash  = 0;
7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // number of local symbol in the .symtab and .dynsym
7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symtab_local_cnt = 0;
776d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  size_t dynsym_local_cnt = 0;
777d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd;
7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// Compute the size of .symtab, .strtab, and symtab_local_cnt
78122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
78287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /* TODO:
78387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       1. discard locals and temporary locals
78487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       2. check whether the symbol is used
78587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines   */
78687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  switch (config().options().getStripSymbolMode()) {
78787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case GeneralOptions::StripAllSymbols: {
78887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symtab = strtab = 0;
78987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
79087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
79187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    default: {
79287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symEnd = symbols.end();
79387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (symbol = symbols.begin(); symbol != symEnd; ++symbol) {
79487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ++symtab;
79587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (hasEntryInStrTab(**symbol))
79687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          strtab += (*symbol)->nameSize() + 1;
79787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
79887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symtab_local_cnt = 1 + symbols.numOfFiles() + symbols.numOfLocals() +
79987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         symbols.numOfLocalDyns();
80087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
80187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
80287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // end of switch
8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
80422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(config().codeGenType()) {
80722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // soname
80987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      dynstr += config().options().soname().size() + 1;
81022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
81122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /** fall through **/
812d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
813d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
814f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (!config().isCodeStatic()) {
8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        /// Compute the size of .dynsym, .dynstr, and dynsym_local_cnt
8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        symEnd = symbols.dynamicEnd();
8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) {
8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ++dynsym;
819f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (hasEntryInStrTab(**symbol))
8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*symbol)->nameSize() + 1;
8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        dynsym_local_cnt = 1 + symbols.numOfLocalDyns();
8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // compute .gnu.hash
8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (GeneralOptions::GNU  == config().options().getHashStyle() ||
8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            GeneralOptions::Both == config().options().getHashStyle()) {
8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // count the number of dynsym to hash
8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          size_t hashed_sym_cnt = 0;
8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          symEnd = symbols.dynamicEnd();
8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          for (symbol = symbols.dynamicBegin(); symbol != symEnd; ++symbol) {
8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            if (DynsymCompare().needGNUHash(**symbol))
8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              ++hashed_sym_cnt;
8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          }
8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Special case for empty .dynsym
8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (hashed_sym_cnt == 0)
8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash = 5 * 4 + config().targets().bitclass() / 8;
8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          else {
8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            size_t nbucket = getHashBucketCount(hashed_sym_cnt, true);
8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash = (4 + nbucket + hashed_sym_cnt) * 4;
8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash += (1U << getGNUHashMaskbitslog2(hashed_sym_cnt)) / 8;
8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
84422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // compute .hash
8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (GeneralOptions::SystemV == config().options().getHashStyle() ||
8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            GeneralOptions::Both == config().options().getHashStyle()) {
8476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Both Elf32_Word and Elf64_Word are 4 bytes
8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                 sizeof(llvm::ELF::Elf32_Word);
8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // add DT_NEEDED
8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        Module::const_lib_iterator lib, libEnd = pModule.lib_end();
8546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) {
8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*lib)->name().size() + 1;
8576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynamic().reserveNeedEntry();
8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          }
8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // add DT_RPATH
8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (!config().options().getRpathList().empty()) {
8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          dynamic().reserveNeedEntry();
8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          GeneralOptions::const_rpath_iterator rpath,
8656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            rpathEnd = config().options().rpath_end();
8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          for (rpath = config().options().rpath_begin();
8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               rpath != rpathEnd; ++rpath)
8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*rpath).size() + 1;
8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set size
8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (config().targets().is32Bits()) {
8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          file_format->getDynSymTab().setSize(dynsym *
8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                              sizeof(llvm::ELF::Elf32_Sym));
8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        } else {
8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          file_format->getDynSymTab().setSize(dynsym *
8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                              sizeof(llvm::ELF::Elf64_Sym));
8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynStrTab().setSize(dynstr);
8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getHashTab().setSize(hash);
8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getGNUHashTab().setSize(gnuhash);
8826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set .dynsym sh_info to one greater than the symbol table
8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // index of the last local symbol
8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynSymTab().setInfo(dynsym_local_cnt);
8866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // Because some entries in .dynamic section need information of .dynsym,
8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // entries until we get the size of the sections mentioned above
8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        dynamic().reserveEntries(*file_format);
8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynamic().setSize(dynamic().numOfBytes());
8926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /* fall through */
89522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
896d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits())
8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getStrTab().setSize(strtab);
901d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
902d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // set .symtab sh_info to one greater than the symbol table
903d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // index of the last local symbol
9046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      file_format->getSymTab().setInfo(symtab_local_cnt);
9056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
90687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // The size of .shstrtab should be decided after output sections are all
90787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // set, so we just set it to 1 here.
90887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      file_format->getShStrTab().setSize(0x1);
9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
91122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
91222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::fatal_illegal_codegen_type) << pModule.name();
91322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of switch
91522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
91722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol
91822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym,
91922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
92022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
92122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
92222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pSymtabIdx)
92322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
92422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
92522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
926f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines   if (hasEntryInStrTab(pSymbol)) {
92722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = pStrtabsize;
92822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     strcpy((pStrtab + pStrtabsize), pSymbol.name());
92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
93022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   else {
93122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao     pSym.st_name  = 0;
93222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   }
93322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
93422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
93522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
93622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
93722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
93822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
93922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
94022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol
94122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym,
94222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
94322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
94422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
94522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pSymtabIdx)
94622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
94722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // FIXME: check the endian between host and target
94822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   // write out symbol
949f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines   if (hasEntryInStrTab(pSymbol)) {
9506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pSym.st_name  = pStrtabsize;
9516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     strcpy((pStrtab + pStrtabsize), pSymbol.name());
9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   }
9536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   else {
9546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines     pSym.st_name  = 0;
9556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   }
95622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_value = pSymbol.value();
95722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_size  = getSymbolSize(pSymbol);
95822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_info  = getSymbolInfo(pSymbol);
95922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_other = pSymbol.visibility();
96022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   pSym.st_shndx = getSymbolShndx(pSymbol);
9615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab
9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
9665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
96722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule,
96887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                    FileOutputBuffer& pOutput)
9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
97022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
97187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!file_format->hasSymTab())
97287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
9735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getSymTab();
9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getStrTab();
9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
97787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion symtab_region = pOutput.request(symtab_sect.offset(),
97887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                               symtab_sect.size());
97987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion strtab_region = pOutput.request(strtab_sect.offset(),
98087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                               strtab_sect.size());
9815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
9845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
985d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
98687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin();
987d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
98887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin();
989d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
990d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
991d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
992d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
993d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
9945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
99587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  char* strtab = (char*)strtab_region.begin();
9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit the first ELF symbol
9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits())
9996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0);
10006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0);
10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
100322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool sym_exist = false;
100422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  HashTableType::entry_type* entry = NULL;
100522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
10066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry = m_pSymIndexMap->insert(LDSymbol::Null(), sym_exist);
100722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(0);
100822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
100922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symIdx = 1;
10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
10126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const Module::SymbolTable& symbols = pModule.getSymbolTable();
10146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd;
10156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symEnd = symbols.end();
10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = symbols.begin(); symbol != symEnd; ++symbol) {
101822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::Object == config().codeGenType()) {
101922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      entry = m_pSymIndexMap->insert(*symbol, sym_exist);
10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      entry->setValue(symIdx);
10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1022d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
10236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx);
102422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx);
10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symIdx;
1027f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (hasEntryInStrTab(**symbol))
102822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
103222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
10345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
103687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput)
10375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
103822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!file_format->hasDynSymTab() ||
104022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynStrTab() ||
104122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynamic())
104222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
10435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
10455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
10465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
10485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
10505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
105187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion symtab_region = pOutput.request(symtab_sect.offset(),
105287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                               symtab_sect.size());
105387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion strtab_region = pOutput.request(strtab_sect.offset(),
105487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                               strtab_sect.size());
105587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion dyn_region = pOutput.request(dyn_sect.offset(),
105687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                            dyn_sect.size());
10575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
10585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
10595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
1060d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
106187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin();
1062d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
106387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin();
1064d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
1065d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
1066d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
1067d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
10685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
107087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  char* strtab = (char*)strtab_region.begin();
10715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit the first ELF symbol
10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits())
10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0);
10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0);
10775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symIdx = 1;
10795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
10805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
10826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .gnu.hash
10836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (GeneralOptions::GNU  == config().options().getHashStyle() ||
1084f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      GeneralOptions::Both == config().options().getHashStyle())
10856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitGNUHashTab(symbols, pOutput);
1086f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
10876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .hash
10886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (GeneralOptions::SystemV == config().options().getHashStyle() ||
10896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      GeneralOptions::Both == config().options().getHashStyle())
10906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitELFHashTab(symbols, pOutput);
10916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category)
10936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = symbols.dynamicEnd();
10946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) {
1095d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx);
109722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx);
10995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // maintain output's symbol and index map
11005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry->setValue(symIdx);
110222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
11036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symIdx;
1104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (hasEntryInStrTab(**symbol))
110522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
11065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
11075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
11095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
11105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
111122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_lib_iterator lib, libEnd = pModule.lib_end();
111222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) {
11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strcpy((strtab + strtabsize), (*lib)->name().c_str());
11156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
11166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtabsize += (*lib)->name().size() + 1;
11176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++dt_need;
11186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
11196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
11206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().options().getRpathList().empty()) {
11226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!config().options().hasNewDTags())
11236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_RPATH, strtabsize);
11246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
11256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_RUNPATH, strtabsize);
11266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++dt_need;
11276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    GeneralOptions::const_rpath_iterator rpath,
11296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rpathEnd = config().options().rpath_end();
11306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (rpath = config().options().rpath_begin(); rpath != rpathEnd; ++rpath) {
11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      memcpy((strtab + strtabsize), (*rpath).data(), (*rpath).size());
11326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtabsize += (*rpath).size();
11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtab[strtabsize++] = (rpath + 1 == rpathEnd ? '\0' : ':');
11345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
113522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
11365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
113822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
113922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set pointer to SONAME entry in dynamic string table.
1140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
114122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  dynamic().applyEntries(*file_format);
114387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  dynamic().emit(dyn_sect, dyn_region);
11445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
114522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit soname
114622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
114787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    strcpy((strtab + strtabsize), config().options().soname().c_str());
114887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    strtabsize += config().options().soname().size() + 1;
114922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
11506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
11515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitELFHashTab - emit .hash
11536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitELFHashTab(const Module::SymbolTable& pSymtab,
115487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  FileOutputBuffer& pOutput)
11556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
11566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
11576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!file_format->hasHashTab())
11586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
11596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSection& hash_sect = file_format->getHashTab();
116087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion hash_region = pOutput.request(hash_sect.offset(),
116187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                             hash_sect.size());
11625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
11635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
116487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t* word_array = (uint32_t*)hash_region.begin();
11655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
11665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
11675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t dynsymSize = 1 + pSymtab.numOfLocalDyns() + pSymtab.numOfDynamics();
11696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  nbucket = getHashBucketCount(dynsymSize, false);
11706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  nchain  = dynsymSize;
11715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
11735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
11745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
1176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  memset((void*)bucket, 0, nbucket);
11775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  hash::StringHash<hash::ELF> hash_func;
11795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t idx = 1;
11816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd();
11826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.localDynBegin(); symbol != symEnd; ++symbol) {
11836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    llvm::StringRef name((*symbol)->name());
11846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    size_t bucket_pos = hash_func(name) % nbucket;
11856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    chain[idx] = bucket[bucket_pos];
11866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bucket[bucket_pos] = idx;
11876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++idx;
11886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
11896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
11906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitGNUHashTab - emit .gnu.hash
11926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitGNUHashTab(Module::SymbolTable& pSymtab,
119387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  FileOutputBuffer& pOutput)
11946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
11956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
11966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!file_format->hasGNUHashTab())
11976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
11986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
119987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion gnuhash_region =
12006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pOutput.request(file_format->getGNUHashTab().offset(),
12016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    file_format->getGNUHashTab().size());
12026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
120387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t* word_array = (uint32_t*)gnuhash_region.begin();
12046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // fixed-length fields
12056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& nbucket   = word_array[0];
12066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& symidx    = word_array[1];
12076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& maskwords = word_array[2];
12086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& shift2    = word_array[3];
12096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // variable-length fields
12106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint8_t*  bitmask = (uint8_t*)(word_array + 4);
12116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* bucket  = NULL;
12126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t* chain   = NULL;
12136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // count the number of dynsym to hash
12156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t unhashed_sym_cnt = pSymtab.numOfLocalDyns();
12166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t hashed_sym_cnt   = pSymtab.numOfDynamics();
12176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd();
12186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.dynamicBegin(); symbol != symEnd; ++symbol) {
12196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (DynsymCompare().needGNUHash(**symbol))
12206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
12216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++unhashed_sym_cnt;
12226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      --hashed_sym_cnt;
12236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
12246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // special case for the empty hash table
12266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (hashed_sym_cnt == 0) {
12276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    nbucket   = 1; // one empty bucket
12286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    symidx    = 1 + unhashed_sym_cnt; // symidx above unhashed symbols
12296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskwords = 1; // bitmask length
12306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shift2    = 0; // bloom filter
12316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().targets().is32Bits()) {
12336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t* maskval = (uint32_t*)bitmask;
12346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *maskval = 0; // no valid hashes
12356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    } else {
12366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // must be 64
12376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint64_t* maskval = (uint64_t*)bitmask;
12386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *maskval = 0; // no valid hashes
12395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bucket  = (uint32_t*)(bitmask + config().targets().bitclass() / 8);
12416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    *bucket = 0; // no hash in the only bucket
12426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
12435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbitslog2 = getGNUHashMaskbitslog2(hashed_sym_cnt);
12466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbits = 1u << maskbitslog2;
12476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t shift1 = config().targets().is32Bits() ? 5 : 6;
12486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t mask = (1u << shift1) - 1;
12496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  nbucket   = getHashBucketCount(hashed_sym_cnt, true);
12516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symidx    = 1 + unhashed_sym_cnt;
12526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  maskwords = 1 << (maskbitslog2 - shift1);
12536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  shift2    = maskbitslog2;
12546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // setup bucket and chain
12566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bucket = (uint32_t*)(bitmask + maskbits / 8);
12576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  chain  = (bucket + nbucket);
12586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // build the gnu style hash table
12606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef std::multimap<uint32_t,
12616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                        std::pair<LDSymbol*, uint32_t> > SymMapType;
12626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  SymMapType symmap;
12636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symEnd = pSymtab.dynamicEnd();
12646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.localDynBegin() + symidx - 1; symbol != symEnd;
12656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symbol) {
1266f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    hash::StringHash<hash::DJB> hasher;
12676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t djbhash = hasher((*symbol)->name());
12686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t hash = djbhash % nbucket;
12696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    symmap.insert(std::make_pair(hash, std::make_pair(*symbol, djbhash)));
12706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
12716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // compute bucket, chain, and bitmask
12736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  std::vector<uint64_t> bitmasks(maskwords);
12746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t hashedidx = symidx;
12756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (size_t idx = 0; idx < nbucket; ++idx) {
12766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    size_t count = 0;
12776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    std::pair<SymMapType::iterator, SymMapType::iterator> ret;
12786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ret = symmap.equal_range(idx);
12796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (SymMapType::iterator it = ret.first; it != ret.second; ) {
12806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // rearrange the hashed symbol ordering
12816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *(pSymtab.localDynBegin() + hashedidx - 1) = it->second.first;
12826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t djbhash = it->second.second;
12836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t val = ((djbhash >> shift1) & ((maskbits >> shift1) - 1));
12846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bitmasks[val] |= 1u << (djbhash & mask);
12856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bitmasks[val] |= 1u << ((djbhash >> shift2) & mask);
12866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      val = djbhash & ~1u;
12876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // advance the iterator and check if we're dealing w/ the last elment
12886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (++it == ret.second) {
12896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // last element terminates the chain
12906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        val |= 1;
12916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
12926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      chain[hashedidx - symidx] = val;
12936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++hashedidx;
12956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++count;
12965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (count == 0)
12996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bucket[idx] = 0;
13006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
13016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bucket[idx] = hashedidx - count;
13026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
13036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
13046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // write the bitmasks
13056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits()) {
13066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t* maskval = (uint32_t*)bitmask;
13076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (size_t i = 0; i < maskwords; ++i)
13086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      std::memcpy(maskval + i, &bitmasks[i], 4);
13096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else {
13106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // must be 64
13116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint64_t* maskval = (uint64_t*)bitmask;
13126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (size_t i = 0; i < maskwords; ++i)
13136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      std::memcpy(maskval + i, &bitmasks[i], 8);
13145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
13155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
13165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section
131822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::sizeInterp()
1319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const char* dyld_name;
132122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasDyld())
132222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dyld_name = config().options().dyld().c_str();
1323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
13246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dyld_name = m_pInfo->dyld();
1325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
132622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& interp = getOutputFormat()->getInterp();
1327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  interp.setSize(std::strlen(dyld_name) + 1);
1328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp
133187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitInterp(FileOutputBuffer& pOutput)
1332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
133322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasInterp()) {
133422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const LDSection& interp = getOutputFormat()->getInterp();
133587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    MemoryRegion region = pOutput.request(interp.offset(), interp.size());
133622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const char* dyld_name;
133722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasDyld())
133822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      dyld_name = config().options().dyld().c_str();
133922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
13406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      dyld_name = m_pInfo->dyld();
1341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
134287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    std::memcpy(region.begin(), dyld_name, interp.size());
134322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool GNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const
1347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
1348f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ResolveInfo::Section != pSym.type();
1349f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
1350f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1351f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::orderSymbolTable(Module& pModule)
1352f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
1353f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
1354f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (GeneralOptions::GNU  == config().options().getHashStyle() ||
1356f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      GeneralOptions::Both == config().options().getHashStyle())
1357f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // Currently we may add output symbols after sizeNamePools(), and a
1358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // non-stable sort is used in SymbolCategory::arrange(), so we just
1359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // sort .dynsym right before emitting .gnu.hash
1360f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(),
1361f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                     DynsymCompare());
1362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
1363f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
13645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder
136522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaounsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const
13665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
136722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
136822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // NULL section should be the "1st" section
13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (LDFileFormat::Null == pSectHdr.kind())
137187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return SHO_NULL;
13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
137322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (&pSectHdr == &file_format->getStrTab())
137422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return SHO_STRTAB;
137522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the section is not ALLOC, lay it out until the last possible moment
13775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC))
13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_UNDEFINED;
13795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0;
13815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0;
13825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: need to take care other possible output sections
13835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pSectHdr.kind()) {
1384a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    case LDFileFormat::TEXT:
1385a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    case LDFileFormat::DATA:
13865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (is_exec) {
13875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getInit())
13885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_INIT;
13895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getFini())
13905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_FINI;
13915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_TEXT;
13925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else if (!is_write) {
13935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RO;
13945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else {
139522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (config().options().hasRelro()) {
139622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (&pSectHdr == &file_format->getPreInitArray() ||
139722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getInitArray() ||
139822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getFiniArray() ||
1399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getCtors() ||
1400affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getDtors() ||
1401affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getJCR() ||
1402d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao              &pSectHdr == &file_format->getDataRelRo())
1403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO;
1404d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          if (&pSectHdr == &file_format->getDataRelRoLocal())
1405affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO_LOCAL;
1406affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
140722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) {
140822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return SHO_TLS_DATA;
140922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_DATA;
14115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::BSS:
141422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0)
141522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return SHO_TLS_BSS;
14165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_BSS;
14175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
141822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LDFileFormat::NamePool: {
14195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getDynamic())
14205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RELRO;
14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_NAMEPOOL;
142222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
14235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Relocation:
14245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getRelPlt() ||
14255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          &pSectHdr == &file_format->getRelaPlt())
14265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_REL_PLT;
14275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_RELOCATION;
14285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // get the order from target for target specific sections
14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Target:
143122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return getTargetSectionOrder(pSectHdr);
14325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // handle .interp and .note.* sections
14345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Note:
14356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (file_format->hasInterp() && (&pSectHdr == &file_format->getInterp()))
14366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_INTERP;
14376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      else if (is_write)
14386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_RW_NOTE;
14396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      else
14406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_RO_NOTE;
14415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrame:
1443f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // set writable .eh_frame as relro
1444f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (is_write)
1445f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        return SHO_RELRO;
1446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrameHdr:
1447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::GCCExceptTable:
1448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_EXCEPTION;
14495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::MetaData:
14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Debug:
14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_UNDEFINED;
14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize
14585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const
14595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold linker: symtab.cc: 2780
14615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // undefined and dynamic symbols should have zero size.
14625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined)
14635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
14645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.resolveInfo()->size();
14655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo
14685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const
14695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set binding
14715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t bind = 0x0;
14725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isLocal())
14735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isGlobal())
14755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isWeak())
14775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_WEAK;
14785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isAbsolute()) {
14795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // (Luba) Is a absolute but not global (weak or local) symbol meaningful?
14805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1483d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().codeGenType() != LinkerConfig::Object &&
1484d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
1485d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pSymbol.visibility() == llvm::ELF::STV_HIDDEN))
14865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t type = pSymbol.resolveInfo()->type();
1489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change
1490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // its type to Function
1491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn())
1492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    type = ResolveInfo::Function;
1493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (type | (bind << 4));
14945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout()
14975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const
14985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn())
15005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
15015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.value();
15035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout()
15065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t
150722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const
15085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
15095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isAbsolute())
15105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_ABS;
15115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isCommon())
15125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_COMMON;
15135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn())
15145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_UNDEF;
15155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
151622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef())
151722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return llvm::ELF::SHN_ABS;
151822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSymbol.hasFragRef() && "symbols must have fragment reference to get its index");
152022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pSymbol.fragRef()->frag()->getParent()->getSection().index();
15215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index
15246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinessize_t GNULDBackend::getSymbolIdx(const LDSymbol* pSymbol) const
15255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
15266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   HashTableType::iterator entry = m_pSymIndexMap->find(const_cast<LDSymbol *>(pSymbol));
15276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines   assert(entry != m_pSymIndexMap->end() && "symbol not found in the symbol table");
15285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao   return entry.getEntry()->value();
15295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isTemporary - Whether pSymbol is a local label.
15326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::isTemporary(const LDSymbol& pSymbol) const
15336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
15346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (ResolveInfo::Local != pSymbol.binding())
15356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
15366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSymbol.nameSize() < 2)
15386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
15396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const char* name = pSymbol.name();
15416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if ('.' == name[0] && 'L' == name[1])
15426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
15436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // UnixWare 2.1 cc generate DWARF debugging symbols with `..' prefix.
15456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name()
15466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (name[0] == '.' && name[1] == '.')
15476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
15486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Work arround for gcc's bug
15506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // gcc sometimes generate symbols with '_.L_' prefix.
15516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name()
15526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSymbol.nameSize() < 4)
15536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
15546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
15566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
15576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
15586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return false;
15596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
15606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding
156222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage.
1563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @refer Google gold linker: common.cc: 214
1564affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool
156522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::allocateCommonSymbols(Module& pModule)
15665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
156722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SymbolCategory& symbol_list = pModule.getSymbolTable();
1568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (symbol_list.emptyCommons() && symbol_list.emptyFiles() &&
15706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      symbol_list.emptyLocals() && symbol_list.emptyLocalDyns())
1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
1574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: If the order of common symbols is defined, then sort common symbols
1576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // std::sort(com_sym, com_end, some kind of order);
1577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
157822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // get corresponding BSS LDSection
157922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
158022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& bss_sect = file_format->getBSS();
158122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& tbss_sect = file_format->getTBSS();
1582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1583cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
158422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_sect_data = NULL;
158522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect.hasSectionData())
158622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = bss_sect.getSectionData();
158722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
158822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
158922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
159022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* tbss_sect_data = NULL;
159122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (tbss_sect.hasSectionData())
159222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = tbss_sect.getSectionData();
159322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
159422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
1595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
159722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t bss_offset  = bss_sect.size();
159822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t tbss_offset = tbss_sect.size();
1599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all local common symbols
1601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.localEnd();
1602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
1604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::Common == (*com_sym)->desc()) {
1605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // We have to reset the description of the symbol here. When doing
1606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // incremental linking, the output relocatable object may have common
1607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // symbols. Therefore, we can not treat common symbols as normal symbols
1608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // when emitting the regular name pools. We must change the symbols'
1609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // description here.
1610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1611cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
1612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
161522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        tbss_offset += ObjectBuilder::AppendFragment(*frag,
161622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     *tbss_sect_data,
161722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                     (*com_sym)->value());
1618551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines        ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
161987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      else {
162222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        bss_offset += ObjectBuilder::AppendFragment(*frag,
162322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    *bss_sect_data,
162422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                    (*com_sym)->value());
1625551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines        ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
162687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
16305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all global common symbols
1632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.commonEnd();
1633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
1634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // We have to reset the description of the symbol here. When doing
1635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // incremental linking, the output relocatable object may have common
1636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // symbols. Therefore, we can not treat common symbols as normal symbols
1637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // when emitting the regular name pools. We must change the symbols'
1638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // description here.
1639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1640cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
1641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
164422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      tbss_offset += ObjectBuilder::AppendFragment(*frag,
164522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   *tbss_sect_data,
164622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   (*com_sym)->value());
1647551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
164887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
165122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      bss_offset += ObjectBuilder::AppendFragment(*frag,
165222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  *bss_sect_data,
165322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  (*com_sym)->value());
1654551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
165587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
165922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bss_sect.setSize(bss_offset);
166022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  tbss_sect.setSize(tbss_offset);
1661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  symbol_list.changeCommonsToGlobal();
1662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
16635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
16645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// updateSectionFlags - update pTo's flags when merging pFrom
16666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// update the output section flags based on input section flags.
16676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref The Google gold linker:
16686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines///      output.cc: 2809: Output_section::update_flags_for_input_section
16696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::updateSectionFlags(LDSection& pTo, const LDSection& pFrom)
16706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
16716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // union the flags from input
16726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t flags = pTo.flag();
16736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  flags |= (pFrom.flag() &
16746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              (llvm::ELF::SHF_WRITE |
16756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               llvm::ELF::SHF_ALLOC |
16766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               llvm::ELF::SHF_EXECINSTR));
16776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // if there is an input section is not SHF_MERGE, clean this flag
16796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (0 == (pFrom.flag() & llvm::ELF::SHF_MERGE))
16806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    flags &= ~llvm::ELF::SHF_MERGE;
16816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // if there is an input section is not SHF_STRINGS, clean this flag
16836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (0 == (pFrom.flag() & llvm::ELF::SHF_STRINGS))
16846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    flags &= ~llvm::ELF::SHF_STRINGS;
16856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  pTo.setFlag(flags);
16876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
16886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
169087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rel entry
169187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel,
169287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type& pType,
169387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t& pSymIdx,
169487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t& pOffset) const
169587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
169687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t r_info = 0x0;
169787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
169887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
169987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = pRel.r_info;
170087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
170187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else {
170287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap32(pRel.r_offset);
170387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = mcld::bswap32(pRel.r_info);
170487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
170587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
170687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<unsigned char>(r_info);
170787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 8);
170887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
170987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
171087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
171187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rela entry
171287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel,
171387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type& pType,
171487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t& pSymIdx,
171587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t& pOffset,
171687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  int32_t& pAddend) const
171787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
171887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t r_info   = 0x0;
171987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
172087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
172187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = pRel.r_info;
172287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = pRel.r_addend;
172387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
172487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else {
172587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap32(pRel.r_offset);
172687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = mcld::bswap32(pRel.r_info);
172787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = mcld::bswap32(pRel.r_addend);
172887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
172987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
173087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<unsigned char>(r_info);
173187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 8);
173287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
173387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
173487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
173587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF64_Rel entry
173687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel,
173787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              Relocation::Type& pType,
173887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
173987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset) const
174087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
174187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t r_info = 0x0;
174287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
174387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
174487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = pRel.r_info;
174587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
174687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else {
174787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap64(pRel.r_offset);
174887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = mcld::bswap64(pRel.r_info);
174987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
175087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
175187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<uint32_t>(r_info);
175287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 32);
175387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
175487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
175587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
175687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRel - read ELF64_Rela entry
175787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel,
175887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              Relocation::Type& pType,
175987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
176087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset,
176187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int64_t& pAddend) const
176287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
176387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t r_info = 0x0;
176487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
176587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
176687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = pRel.r_info;
176787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = pRel.r_addend;
176887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
176987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else {
177087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap64(pRel.r_offset);
177187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    r_info  = mcld::bswap64(pRel.r_info);
177287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = mcld::bswap64(pRel.r_addend);
177387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
177487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
177587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<uint32_t>(r_info);
177687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 32);
177787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
177887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
177987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
178087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rel entry
178187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel,
178287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
178387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
178487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pOffset) const
178587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
178687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
178787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
178887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
178987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
179087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rela entry
179187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel,
179287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
179387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
179487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pOffset,
179587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  int32_t pAddend) const
179687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
179787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
179887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_addend = pAddend;
179987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
180087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
180187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
180287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rel entry
180387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel,
180487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
180587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
180687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint64_t pOffset) const
180787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
180887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
180987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
181087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
181187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
181287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rela entry
181387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel,
181487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
181587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
181687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint64_t pOffset,
181787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  int64_t pAddend) const
181887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
181987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
182087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_addend = pAddend;
182187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
182287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
182387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
18245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers
18256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::createProgramHdrs(Module& pModule)
18265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
182722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat *file_format = getOutputFormat();
1828affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
18295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_INTERP
1830affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInterp()) {
183187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // make PT_PHDR
183287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    elfSegmentTable().produce(llvm::ELF::PT_PHDR);
183387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
183487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* interp_seg = elfSegmentTable().produce(llvm::ELF::PT_INTERP);
183587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    interp_seg->append(&file_format->getInterp());
1836affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1837affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
183887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t cur_flag, prev_flag = 0x0;
18395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegment* load_seg = NULL;
18405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make possible PT_LOAD segments
184187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& ldscript = pModule.getScript();
184287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript::AddressMap::iterator addrEnd= ldscript.addressMap().end();
184387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::iterator out, prev, outBegin, outEnd;
184487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outBegin = ldscript.sectionMap().begin();
184587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outEnd = ldscript.sectionMap().end();
184687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin, prev = outEnd; out != outEnd; prev = out, ++out) {
184787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    LDSection* sect = (*out)->getSection();
184887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
184987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (0 == (sect->flag() & llvm::ELF::SHF_ALLOC) &&
185087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        LDFileFormat::Null != sect->kind())
185187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
1852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
185387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // bypass empty sections
185487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (!(*out)->hasContent() &&
185587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() != LDFileFormat::Null)
18565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
18575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
185887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur_flag = getSegmentFlag(sect->flag());
185922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bool createPT_LOAD = false;
186087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (LDFileFormat::Null == sect->kind()) {
186122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. create text segment
186222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
186322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
186422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else if (!config().options().omagic() &&
186522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) {
186622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. create data segment if w/o omagic set
186722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
186822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
186987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else if (sect->kind() == LDFileFormat::BSS &&
187022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             load_seg->isDataSegment() &&
187187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             addrEnd != ldscript.addressMap().find(".bss")) {
187222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 3. create bss segment if w/ -Tbss and there is a data segment
187322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
187422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
187587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else if ((sect != &(file_format->getText())) &&
187687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             (sect != &(file_format->getData())) &&
187787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             (sect != &(file_format->getBSS())) &&
187887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             (addrEnd != ldscript.addressMap().find(sect->name()))) {
187987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 4. create PT_LOAD for sections in address map except for text, data,
188087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // and bss
188187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      createPT_LOAD = true;
188287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
188387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else if (LDFileFormat::Null == (*prev)->getSection()->kind() &&
188487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             !config().options().getScriptList().empty()) {
188587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 5. create PT_LOAD to hold NULL section if there is a default ldscript
188687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      createPT_LOAD = true;
188722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
18885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
188922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (createPT_LOAD) {
189022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // create new PT_LOAD segment
189187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      load_seg = elfSegmentTable().produce(llvm::ELF::PT_LOAD, cur_flag);
18926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (!config().options().nmagic() && !config().options().omagic())
18936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        load_seg->setAlign(abiPageSize());
18945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
18955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != load_seg);
189787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    load_seg->append(sect);
189822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (cur_flag != prev_flag)
189922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      load_seg->updateFlag(cur_flag);
19005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
190122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    prev_flag = cur_flag;
19025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
19035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
19045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_DYNAMIC
1905affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasDynamic()) {
190687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* dyn_seg = elfSegmentTable().produce(llvm::ELF::PT_DYNAMIC,
1907affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_R |
1908affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_W);
190987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    dyn_seg->append(&file_format->getDynamic());
1910affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1911affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
191222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasRelro()) {
1913affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // make PT_GNU_RELRO
191487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* relro_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_RELRO);
191522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
191687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) {
191787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (llvm::ELF::PT_LOAD != (*seg)->type())
191822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
191922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
192087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (ELFSegment::iterator sect = (*seg)->begin(),
192187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        sectEnd = (*seg)->end(); sect != sectEnd; ++sect) {
192222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        unsigned int order = getSectionOrder(**sect);
192322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (SHO_RELRO_LOCAL == order ||
192422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            SHO_RELRO == order ||
192522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            SHO_RELRO_LAST == order) {
192687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          relro_seg->append(*sect);
192722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
1928affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1929affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
19305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
19315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1932affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // make PT_GNU_EH_FRAME
1933affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasEhFrameHdr()) {
193487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* eh_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_EH_FRAME);
193587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    eh_seg->append(&file_format->getEhFrameHdr());
1936affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
193722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
193822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_TLS
193922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasTData() || file_format->hasTBSS()) {
194087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* tls_seg = elfSegmentTable().produce(llvm::ELF::PT_TLS);
194122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTData())
194287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      tls_seg->append(&file_format->getTData());
194322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTBSS())
194487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      tls_seg->append(&file_format->getTBSS());
194522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
194622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
194722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_GNU_STACK
194822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasStackNote()) {
194987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    elfSegmentTable().produce(llvm::ELF::PT_GNU_STACK,
195022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              llvm::ELF::PF_R |
195122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              llvm::ELF::PF_W |
195222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              getSegmentFlag(file_format->getStackNote().flag()));
195322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
195422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // make PT_NOTE
19566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFSegment *note_seg = NULL;
195787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  prev_flag = 0x0;
195887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::iterator sect, sectBegin, sectEnd;
195987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sectBegin = pModule.begin();
196087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sectEnd = pModule.end();
196187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (sect = sectBegin; sect != sectEnd; ++sect) {
196287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*sect)->type() != llvm::ELF::SHT_NOTE ||
19636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        ((*sect)->flag() & llvm::ELF::SHF_ALLOC) == 0)
19646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      continue;
19656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
19666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    cur_flag = getSegmentFlag((*sect)->flag());
19676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // we have different section orders for read-only and writable notes, so
19686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create 2 segments if needed.
19696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (note_seg == NULL ||
19706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        (cur_flag & llvm::ELF::PF_W) != (prev_flag & llvm::ELF::PF_W))
197187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      note_seg = elfSegmentTable().produce(llvm::ELF::PT_NOTE, cur_flag);
19726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
197387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    note_seg->append(*sect);
19746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    prev_flag = cur_flag;
19756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
19766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
197722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // create target dependent segments
19786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  doCreateProgramHdrs(pModule);
1979affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1980affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1981affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments
1982f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::setupProgramHdrs(const LinkerScript& pScript)
1983affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
19845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update segment info
198587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
198687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) {
198787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
198887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // bypass if there is no section in this segment (e.g., PT_GNU_STACK)
198987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*seg)->size() == 0)
199087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
199187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
199287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // bypass the PT_LOAD that only has NULL section now
199387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*seg)->type() == llvm::ELF::PT_LOAD &&
199487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->front()->kind() == LDFileFormat::Null &&
199587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->size() == 1)
199687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       continue;
199787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
199887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*seg)->setOffset((*seg)->front()->offset());
199987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*seg)->type() == llvm::ELF::PT_LOAD &&
200087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->front()->kind() == LDFileFormat::Null) {
200187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      const LDSection* second = *((*seg)->begin() + 1);
200287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      assert(second != NULL);
200387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*seg)->setVaddr(second->addr() - second->offset());
200487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
200587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*seg)->setVaddr((*seg)->front()->addr());
200687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
200787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*seg)->setPaddr((*seg)->vaddr());
200887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
200987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment::reverse_iterator sect, sectREnd = (*seg)->rend();
201087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (sect = (*seg)->rbegin(); sect != sectREnd; ++sect) {
201187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*sect)->kind() != LDFileFormat::BSS)
201287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        break;
201387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
201487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (sect != sectREnd) {
201587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*seg)->setFilesz((*sect)->offset() +
201687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                        (*sect)->size() -
201787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                        (*seg)->offset());
201887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
201987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*seg)->setFilesz(0x0);
202087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
202187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
202287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*seg)->setMemsz((*seg)->back()->addr() +
202387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                     (*seg)->back()->size() -
202487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                     (*seg)->vaddr());
202587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // end of for
202687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
202787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // handle the case if text segment only has NULL section
202887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* null_sect = &getOutputFormat()->getNULLSection();
202987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator null_seg =
203087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect);
203187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
203287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((*null_seg)->size() == 1) {
203387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // find 2nd PT_LOAD
203487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end();
203587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (seg = null_seg + 1; seg != segEnd; ++seg) {
203687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*seg)->type() == llvm::ELF::PT_LOAD)
203787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        break;
203887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
203987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (seg != segEnd) {
204087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t addr = (*seg)->front()->addr() - (*seg)->front()->offset();
204187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t size = sectionStartOffset();
204287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (addr + size == (*seg)->front()->addr()) {
204387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // if there is no space between the 2 segments, we can merge them.
204487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->setOffset(0x0);
204587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->setVaddr(addr);
204687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->setPaddr(addr);
204787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
204887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ELFSegment::iterator sect, sectEnd = (*seg)->end();
204987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        for (sect = (*seg)->begin(); sect != sectEnd; ++sect) {
205087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if ((*sect)->kind() == LDFileFormat::BSS) {
205187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            --sect;
205287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            break;
205387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          }
205487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
205587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (sect == sectEnd) {
205687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*seg)->setFilesz((*seg)->back()->offset() +
205787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*seg)->back()->size() -
205887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*seg)->offset());
205987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        } else if (*sect != (*seg)->front()) {
206087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          --sect;
206187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*seg)->setFilesz((*sect)->offset() +
206287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*sect)->size() -
206387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*seg)->offset());
206487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        } else {
206587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*seg)->setFilesz(0x0);
206687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
206787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
206887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->setMemsz((*seg)->back()->addr() +
206987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (*seg)->back()->size() -
207087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (*seg)->vaddr());
207187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
207287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->insert((*seg)->begin(), null_sect);
207387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        elfSegmentTable().erase(null_seg);
207487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
207587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else if (addr + size < (*seg)->vaddr()) {
207687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setOffset(0x0);
207787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setVaddr(addr);
207887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setPaddr(addr);
207987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setFilesz(size);
208087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setMemsz(size);
208187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
208287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // erase the non valid segment contains NULL.
208387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        elfSegmentTable().erase(null_seg);
208487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
208587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
208687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
208787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
208887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // set up PT_PHDR
208987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator phdr =
209087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    elfSegmentTable().find(llvm::ELF::PT_PHDR, llvm::ELF::PF_R, 0x0);
209187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
209287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (phdr != elfSegmentTable().end()) {
209387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::iterator null_seg =
209487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect);
209587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (null_seg != elfSegmentTable().end()) {
209687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t offset = 0x0, phdr_size = 0x0;
2097d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits()) {
20985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf32_Ehdr);
20995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
210087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
21015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf64_Ehdr);
21025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf64_Phdr);
21035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
210487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setOffset(offset);
210587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setVaddr((*null_seg)->vaddr() + offset);
210687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setPaddr((*phdr)->vaddr());
210787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setFilesz(elfSegmentTable().size() * phdr_size);
210887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setMemsz(elfSegmentTable().size() * phdr_size);
210987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setAlign(config().targets().bitclass() / 8);
211087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
211187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      elfSegmentTable().erase(phdr);
21125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
21135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
21145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
21155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
211687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// getSegmentFlag - give a section flag and return the corresponding segment
211787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// flag
211887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesuint32_t GNULDBackend::getSegmentFlag(const uint32_t pSectionFlag)
211987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
212087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t flag = 0x0;
212187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((pSectionFlag & llvm::ELF::SHF_ALLOC) != 0x0)
212287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    flag |= llvm::ELF::PF_R;
212387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((pSectionFlag & llvm::ELF::SHF_WRITE) != 0x0)
212487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    flag |= llvm::ELF::PF_W;
212587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((pSectionFlag & llvm::ELF::SHF_EXECINSTR) != 0x0)
212687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    flag |= llvm::ELF::PF_X;
212787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return flag;
212887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
212987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
213022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
2131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: layout.cc:2608
21326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::setupGNUStackInfo(Module& pModule)
21335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t flag = 0x0;
213522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasStackSet()) {
2136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 1. check the command line option (-z execstack or -z noexecstack)
213722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasExecStack())
2138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      flag = llvm::ELF::SHF_EXECINSTR;
213922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
214022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
2141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2. check the stack info from the input objects
214222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // FIXME: since we alway emit .note.GNU-stack in output now, we may be able
214322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // to check this from the output .note.GNU-stack directly after section
214422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // merging is done
2145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    size_t object_count = 0, stack_note_count = 0;
214622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::const_obj_iterator obj, objEnd = pModule.obj_end();
214722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (obj = pModule.obj_begin(); obj != objEnd; ++obj) {
214822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++object_count;
214922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack");
215022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if (NULL != sect) {
215122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++stack_note_count;
215222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 2.1 found a stack note that is set as executable
215322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) {
215422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          flag = llvm::ELF::SHF_EXECINSTR;
215522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
2156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
2157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
2158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
21595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.2 there are no stack note sections in all input objects
2161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (0 == stack_note_count)
2162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
21635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.3 a special case. Use the target default to decide if the stack should
2165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //     be executable
2166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count)
21676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (m_pInfo->isDefaultExecStack())
2168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        flag = llvm::ELF::SHF_EXECINSTR;
21695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
21705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
217122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasStackNote()) {
217222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    getOutputFormat()->getStackNote().setFlag(flag);
217322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
217422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
217522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
217687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionOffset - helper function to set output sections' offset.
217787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::setOutputSectionOffset(Module& pModule)
217822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
217987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& script = pModule.getScript();
218087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t offset = 0x0;
218187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* cur = NULL;
218287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* prev = NULL;
218387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::iterator out, outBegin, outEnd;
218487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outBegin = script.sectionMap().begin();
218587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outEnd = script.sectionMap().end();
218687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out, prev = cur) {
218787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur = (*out)->getSection();
218887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (cur->kind() == LDFileFormat::Null) {
218987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      cur->setOffset(0x0);
219087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
219187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
219222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
219387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    switch (prev->kind()) {
219487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case LDFileFormat::Null:
219587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset = sectionStartOffset();
219687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
219787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case LDFileFormat::BSS:
219887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset = prev->offset();
219987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
220087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    default:
220187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset = prev->offset() + prev->size();
220222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
220322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
220487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    alignAddress(offset, cur->align());
220587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur->setOffset(offset);
220687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
220787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
220887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
220987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionAddress - helper function to set output sections' address.
221087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::setOutputSectionAddress(Module& pModule)
221187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
221287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  RpnEvaluator evaluator(pModule, *this);
221387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& script = pModule.getScript();
221487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t vma = 0x0, offset = 0x0;
221587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* cur = NULL;
221687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* prev = NULL;
221787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript::AddressMap::iterator addr, addrEnd = script.addressMap().end();
221887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end();
221987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::Output::dot_iterator dot;
222087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::iterator out, outBegin, outEnd;
222187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outBegin = script.sectionMap().begin();
222287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outEnd = script.sectionMap().end();
222387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; prev = cur, ++out) {
222487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur = (*out)->getSection();
222587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
222687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (cur->kind() == LDFileFormat::Null) {
222787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      cur->setOffset(0x0);
222822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
222987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
223022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
223187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // process dot assignments between 2 output sections
223287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (SectionMap::Output::dot_iterator it = (*out)->dot_begin(),
223387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      ie = (*out)->dot_end(); it != ie; ++it) {
223487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*it).assign(evaluator);
223587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
223687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
223787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    seg = elfSegmentTable().find(llvm::ELF::PT_LOAD, cur);
223887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (seg != segEnd && cur == (*seg)->front()) {
223987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*seg)->isBssSegment())
224087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        addr = script.addressMap().find(".bss");
224187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      else if ((*seg)->isDataSegment())
224287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        addr = script.addressMap().find(".data");
224387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      else
224487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        addr = script.addressMap().find(cur->name());
224587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else
224687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      addr = addrEnd;
224722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
224887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (addr != addrEnd) {
22496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // use address mapping in script options
225087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      vma = addr.getEntry()->value();
225187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else if ((*out)->prolog().hasVMA()) {
225287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // use address from output section description
225387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      evaluator.eval((*out)->prolog().vma(), vma);
225487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else if ((dot = (*out)->find_last_explicit_dot()) != (*out)->dot_end()) {
225587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // assign address based on `.' symbol in ldscript
225687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      vma = (*dot).symbol().value();
225787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      alignAddress(vma, cur->align());
225887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
225987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*out)->prolog().type() == OutputSectDesc::NOLOAD) {
226087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        vma = prev->addr() + prev->size();
226187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0) {
226287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (prev->kind() == LDFileFormat::Null) {
226387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          // Let SECTIONS starts at 0 if we have a default ldscript but don't
226487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          // have any initial value (VMA or `.').
226587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (!config().options().getScriptList().empty())
226687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = 0x0;
226787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          else
226887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = getSegmentStartAddr(script) + sectionStartOffset();
226987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        } else {
227087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if ((prev->kind() == LDFileFormat::BSS))
227187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = prev->addr();
227287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          else
227387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = prev->addr() + prev->size();
227487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
227587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        alignAddress(vma, cur->align());
227687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (config().options().getScriptList().empty()) {
227787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (seg != segEnd && cur == (*seg)->front()) {
227887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            // Try to align p_vaddr at page boundary if not in script options.
227987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            // To do so will add more padding in file, but can save one page
228087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            // at runtime.
228187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            alignAddress(vma, (*seg)->align());
228287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          }
228387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
228487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
228587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        vma = 0x0;
228622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
22876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
228822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
228987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (config().options().hasRelro()) {
229087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // if -z relro is given, we need to adjust sections' offset again, and
229187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // let PT_GNU_RELRO end on a abi page boundary
229287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
229387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // check if current is the first non-relro section
229487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      SectionMap::iterator relro_last = out - 1;
229587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (relro_last != outEnd &&
229687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*relro_last)->order() <= SHO_RELRO_LAST &&
229787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*out)->order() > SHO_RELRO_LAST) {
229887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // align the first non-relro section to page boundary
229987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        alignAddress(vma, abiPageSize());
230087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
230187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // It seems that compiler think .got and .got.plt are continuous (w/o
230287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // any padding between). If .got is the last section in PT_RELRO and
230387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // it's not continuous to its next section (i.e. .got.plt), we need to
230487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // add padding in front of .got instead.
230587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // FIXME: Maybe we can handle this in a more general way.
230687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        LDSection& got = getOutputFormat()->getGOT();
230787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((getSectionOrder(got) == SHO_RELRO_LAST) &&
230887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            (got.addr() + got.size() < vma)) {
230987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          uint64_t diff = vma - got.addr() - got.size();
231087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          got.setAddr(vma - got.size());
231187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          got.setOffset(got.offset() + diff);
231287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
231387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
231487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } // end of if - for relro processing
231587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
231687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur->setAddr(vma);
231787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
231887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    switch (prev->kind()) {
231987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case LDFileFormat::Null:
232087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset = sectionStartOffset();
232187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
232287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    case LDFileFormat::BSS:
232387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset = prev->offset();
232487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
232587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    default:
232687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset = prev->offset() + prev->size();
232787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
232887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
232987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    alignAddress(offset, cur->align());
23306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf
23316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // p_align: As "Program Loading" describes in this chapter of the
23326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // processor supplement, loadable process segments must have congruent
23336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // values for p_vaddr and p_offset, modulo the page size.
233487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // FIXME: Now make all sh_addr and sh_offset are congruent, modulo the page
233587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // size. Otherwise, old objcopy (e.g., binutils 2.17) may fail with our
233687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // output!
233787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0 &&
233887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (vma & (abiPageSize() - 1)) != (offset & (abiPageSize() - 1))) {
233987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t padding = abiPageSize() +
234087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (vma & (abiPageSize() - 1)) -
234187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (offset & (abiPageSize() - 1));
234287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset += padding;
234322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
234422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
234587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur->setOffset(offset);
234622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
234787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // process dot assignments in the output section
234887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool changed = false;
234987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    Fragment* invalid = NULL;
235087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (SectionMap::Output::iterator in = (*out)->begin(),
235187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      inEnd = (*out)->end(); in != inEnd; ++in) {
235222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
235387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (invalid != NULL && !(*in)->dotAssignments().empty()) {
235487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        while (invalid != (*in)->dotAssignments().front().first) {
235587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          Fragment* prev = invalid->getPrevNode();
235687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          invalid->setOffset(prev->getOffset() + prev->size());
235787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          invalid = invalid->getNextNode();
235887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
235987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        invalid = NULL;
236087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
236122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
236287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (SectionMap::Input::dot_iterator it = (*in)->dot_begin(),
236387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ie = (*in)->dot_end(); it != ie; ++it) {
236487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*it).second.assign(evaluator);
236587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((*it).first != NULL) {
236687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          uint64_t new_offset = (*it).second.symbol().value() - vma;
236787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (new_offset != (*it).first->getOffset()) {
236887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            (*it).first->setOffset(new_offset);
236987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            invalid = (*it).first->getNextNode();
237087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            changed = true;
237187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          }
237287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
237387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } // for each dot assignment
237487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } // for each input description
237587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
237687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (changed) {
237787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      while (invalid != NULL) {
237887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        Fragment* prev = invalid->getPrevNode();
237987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        invalid->setOffset(prev->getOffset() + prev->size());
238087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        invalid = invalid->getNextNode();
238187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
238287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
238387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      cur->setSize(cur->getSectionData()->back().getOffset() +
238487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                   cur->getSectionData()->back().size());
238522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
238687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
238787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each output section description
23885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
23895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
239087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// placeOutputSections - place output sections based on SectionMap
239187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::placeOutputSections(Module& pModule)
2392d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
239387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef std::vector<LDSection*> Orphans;
239487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Orphans orphans;
239587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap& sectionMap = pModule.getScript().sectionMap();
239687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2397d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie;
239887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ++it) {
239987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool wanted = false;
240087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2401d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    switch ((*it)->kind()) {
24026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // take NULL and StackNote directly
24036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Null:
24046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::StackNote:
240587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      wanted = true;
24066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
24076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // ignore if section size is 0
24086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::EhFrame:
24096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (((*it)->size() != 0) ||
24106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ((*it)->hasEhFrame() &&
24116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines           config().codeGenType() == LinkerConfig::Object))
241287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        wanted = true;
24136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
24146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Relocation:
24156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (((*it)->size() != 0) ||
24166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ((*it)->hasRelocData() &&
24176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines           config().codeGenType() == LinkerConfig::Object))
241887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        wanted = true;
24196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
2420a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    case LDFileFormat::TEXT:
2421a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    case LDFileFormat::DATA:
24226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Target:
24236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::MetaData:
24246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::BSS:
24256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Debug:
24266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::GCCExceptTable:
24276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Note:
24286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::NamePool:
24296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::EhFrameHdr:
24306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (((*it)->size() != 0) ||
24316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ((*it)->hasSectionData() &&
24326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines           config().codeGenType() == LinkerConfig::Object))
243387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        wanted = true;
24346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
24356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Group:
24366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (LinkerConfig::Object == config().codeGenType()) {
24376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        //TODO: support incremental linking
24386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        ;
24396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
24406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
24416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Version:
244287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*it)->size() != 0) {
244387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        wanted = true;
24446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name();
24456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
24466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
24476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    default:
244887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*it)->size() != 0) {
24496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        error(diag::err_unsupported_section) << (*it)->name() << (*it)->kind();
24506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
24516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
245287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } // end of switch
245387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
245487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (wanted) {
245587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      SectionMap::iterator out, outBegin, outEnd;
245687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      outBegin = sectionMap.begin();
245787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      outEnd = sectionMap.end();
245887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (out = outBegin; out != outEnd; ++out) {
245987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        bool matched = false;
246087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((*it)->name().compare((*out)->name()) == 0) {
246187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          switch ((*out)->prolog().constraint()) {
246287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          case OutputSectDesc::NO_CONSTRAINT:
246387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            matched = true;
246487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            break;
246587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          case OutputSectDesc::ONLY_IF_RO:
246687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) == 0;
246787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            break;
246887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          case OutputSectDesc::ONLY_IF_RW:
246987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) != 0;
247087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            break;
247187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          } // end of switch
247287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
247387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (matched)
247487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            break;
247587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
247687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } // for each output section description
247787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
247887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (out != outEnd) {
247987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // set up the section
248087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->setSection(*it);
248187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->setOrder(getSectionOrder(**it));
248287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
248387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        orphans.push_back(*it);
248487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
2485d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
248687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each section in Module
248787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
248887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // set up sections in SectionMap but do not exist at all.
248987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t flag = 0x0;
249087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  unsigned int order = SHO_UNDEFINED;
249187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  OutputSectDesc::Type type = OutputSectDesc::LOAD;
249287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (SectionMap::reverse_iterator out = sectionMap.rbegin(),
249387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    outEnd = sectionMap.rend(); out != outEnd; ++out) {
249487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->hasContent() ||
249587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::Null ||
249687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::StackNote) {
249787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      flag = (*out)->getSection()->flag();
249887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      order = (*out)->order();
249987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      type = (*out)->prolog().type();
250087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
250187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->getSection()->setFlag(flag);
250287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->setOrder(order);
250387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->prolog().setType(type);
250487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
250587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each output section description
250687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
250787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // place orphan sections
250887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (Orphans::iterator it = orphans.begin(), ie = orphans.end(); it != ie;
250987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ++it) {
251087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    size_t order = getSectionOrder(**it);
251187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SectionMap::iterator out, outBegin, outEnd;
251287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    outBegin = sectionMap.begin();
251387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    outEnd = sectionMap.end();
251487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
251587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*it)->kind() == LDFileFormat::Null)
251687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      out = sectionMap.insert(outBegin, *it);
251787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else {
251887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (out = outBegin; out != outEnd; ++out) {
251987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((*out)->order() > order)
252087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          break;
252187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
252287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      out = sectionMap.insert(out, *it);
252387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
252487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*out)->setOrder(order);
252587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each orphan section
252687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
252787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // sort output section orders if there is no default ldscript
252887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (config().options().getScriptList().empty()) {
252987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    std::stable_sort(sectionMap.begin(),
253087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                     sectionMap.end(),
253187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                     SectionMap::SHOCompare());
253287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
2533d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
253487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // when section ordering is fixed, now we can make sure dot assignments are
253587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // all set appropriately
253687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sectionMap.fixupDotSymbols();
253787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
253887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
253987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// layout - layout method
254087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::layout(Module& pModule)
254187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
254287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 1. place output sections based on SectionMap from SECTIONS command
254387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  placeOutputSections(pModule);
2544d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
254587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 2. update output sections in Module
254687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap& sectionMap = pModule.getScript().sectionMap();
2547d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pModule.getSectionTable().clear();
254887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (SectionMap::iterator out = sectionMap.begin(), outEnd = sectionMap.end();
254987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    out != outEnd; ++out) {
255087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->hasContent() ||
255187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::Null ||
255287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::StackNote ||
255387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        config().codeGenType() == LinkerConfig::Object) {
255487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->getSection()->setIndex(pModule.size());
255587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      pModule.getSectionTable().push_back((*out)->getSection());
255687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
255787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } // for each output section description
255887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
255987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 3. update the size of .shstrtab
256087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sizeShstrtab(pModule);
2561d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2562d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 4. create program headers
2563d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
25646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    createProgramHdrs(pModule);
2565d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
2566d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
256787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 5. set output section address/offset
256887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (LinkerConfig::Object != config().codeGenType())
256987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    setOutputSectionAddress(pModule);
257087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else
257187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    setOutputSectionOffset(pModule);
2572d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
2573d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
257487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::createAndSizeEhFrameHdr(Module& pModule)
25755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
25766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType() &&
25776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // init EhFrameHdr and size the output section
257922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* format = getOutputFormat();
258022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pEhFrameHdr = new EhFrameHdr(format->getEhFrameHdr(),
258122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   format->getEhFrame());
2582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr->sizeOutput();
2583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
258487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
258587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2586a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
2587a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines/// function pointer access
2588a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesbool GNULDBackend::mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection)
2589a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    const
2590a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines{
2591a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  llvm::StringRef name(pSection.name());
2592a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  return !name.startswith(".rodata._ZTV") &&
2593a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines         !name.startswith(".data.rel.ro._ZTV") &&
2594a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines         !name.startswith(".rodata._ZTC") &&
2595a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines         !name.startswith(".data.rel.ro._ZTC") &&
2596a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines         !name.startswith(".eh_frame");
2597a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines}
2598a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
259987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// preLayout - Backend can do any needed modification before layout
260087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::preLayout(Module& pModule, IRBuilder& pBuilder)
260187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
260287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // prelayout target first
260387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  doPreLayout(pBuilder);
260422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // change .tbss and .tdata section symbol from Local to LocalDyn category
260622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pTDATA)
2607f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pModule.getSymbolTable().changeToDynamic(*f_pTDATA);
260822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
260922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != f_pTBSS)
2610f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pModule.getSymbolTable().changeToDynamic(*f_pTBSS);
261122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
261222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // To merge input's relocation sections into output's relocation sections.
261322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //
261422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are generating relocatables (-r), move input relocation sections
261522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // to corresponding output relocation sections.
261622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
261722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::obj_iterator input, inEnd = pModule.obj_end();
261822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (input = pModule.obj_begin(); input != inEnd; ++input) {
261922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
262022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
262122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
262222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the output relocation LDSection with identical name.
262322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_sect = pModule.getSection((*rs)->name());
262422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == output_sect) {
262522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect = LDSection::Create((*rs)->name(),
262622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->kind(),
262722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->type(),
262822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*rs)->flag());
262922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
263022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setAlign((*rs)->align());
263122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          pModule.getSectionTable().push_back(output_sect);
263222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
263322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
263422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // set output relocation section link
263522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        const LDSection* input_link = (*rs)->getLink();
263622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != input_link && "Illegal input relocation section.");
263722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
263822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the linked output section
263922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_link = pModule.getSection(input_link->name());
264022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        assert(NULL != output_link);
264122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
264222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        output_sect->setLink(output_link);
264322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
264422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get output relcoationData, create one if not exist
264522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!output_sect->hasRelocData())
264622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          IRBuilder::CreateRelocData(*output_sect);
264722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
264822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        RelocData* out_reloc_data = output_sect->getRelocData();
264922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
265022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // move relocations from input's to output's RelcoationData
2651d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& out_list =
2652d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                             out_reloc_data->getRelocationList();
2653d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& in_list =
2654d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      (*rs)->getRelocData()->getRelocationList();
265522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        out_list.splice(out_list.end(), in_list);
265622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
265722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // size output
265822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (llvm::ELF::SHT_REL == output_sect->type())
265922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelEntrySize());
266022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else if (llvm::ELF::SHT_RELA == output_sect->type())
266122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelaEntrySize());
266222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else {
266322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          fatal(diag::unknown_reloc_section_type) << output_sect->type()
266422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << output_sect->name();
266522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
266622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      } // end of for each relocation section
266722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // end of for each input
266822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of if
266922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
267022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up the section flag of .note.GNU-stack section
26716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  setupGNUStackInfo(pModule);
26725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
26735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2674cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout
26756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::postLayout(Module& pModule, IRBuilder& pBuilder)
26765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
267722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
267887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // do relaxation
26796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relax(pModule, pBuilder);
268087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // set up the attributes of program headers
2681f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    setupProgramHdrs(pModule.getScript());
2682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
26846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  doPostLayout(pModule, pBuilder);
26855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
26865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
268787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::postProcessing(FileOutputBuffer& pOutput)
2688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
26896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType() &&
26906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // emit eh_frame_hdr
2692f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pEhFrameHdr->emitOutput<32>(pOutput);
2693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
26965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count.
26975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker, dynobj.cc:791
26985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols,
26995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          bool pIsGNUStyle)
27005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
27015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold, dynobj.cc:loc 791
27025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static const unsigned int buckets[] =
27035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
27045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
27055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    16411, 32771, 65537, 131101, 262147
27065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
27075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const unsigned buckets_count = sizeof buckets / sizeof buckets[0];
27085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int result = 1;
27105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (unsigned i = 0; i < buckets_count; ++i) {
27115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pNumOfSymbols < buckets[i])
27125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
27135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = buckets[i];
27145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
27155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pIsGNUStyle && result < 2)
27175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = 2;
27185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
27205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
27215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
27236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref binutils gold, dynobj.cc:1165
27246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned GNULDBackend::getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const
27256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
27266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbitslog2 = 1;
27276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (uint32_t x = pNumOfSymbols >> 1; x != 0; x >>=1)
27286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++maskbitslog2;
27296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
27306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (maskbitslog2 < 3)
27316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 = 5;
27326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (((1U << (maskbitslog2 - 2)) & pNumOfSymbols) != 0)
27336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 += 3;
27346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
27356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 += 2;
27366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
27376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().bitclass() == 64 && maskbitslog2 == 5)
27386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 = 6;
27396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
27406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return maskbitslog2;
27416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
27426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
27435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol
27445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker: symtab.cc:311
274587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol) const
27465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
27475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
27485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // symbol. We should not add it
27495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.binding() == ResolveInfo::Local)
27505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
27515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If we are building shared object, and the visibility is external, we
27535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // need to add it.
275422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
2755d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Exec   == config().codeGenType() ||
2756d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
27575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default ||
27586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected)
27595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return true;
276022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
276122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
276222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
276322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
276422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol
276522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker: symtab.cc:311
276687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo) const
276722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
276822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
276922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol. We should not add it
277022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pResolveInfo.binding() == ResolveInfo::Local)
277122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
277222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
277322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are building shared object, and the visibility is external, we
277422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // need to add it.
277522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
2776d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Exec   == config().codeGenType() ||
2777d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
277822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (pResolveInfo.visibility() == ResolveInfo::Default ||
27796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        pResolveInfo.visibility() == ResolveInfo::Protected)
278022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
278122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2782affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
2783affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2784affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
278587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table
278687f34658dec9097d987d254a990ea7f311bfc95fStephen HinesELFSegmentFactory& GNULDBackend::elfSegmentTable()
278787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
278887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!");
278987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return *m_pELFSegmentTable;
279087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
279187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
279287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table
279387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesconst ELFSegmentFactory& GNULDBackend::elfSegmentTable() const
279487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
279587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!");
279687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return *m_pELFSegmentTable;
279787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
279887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2799affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine.
2800affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:135
280122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::commonPageSize() const
2802affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
280322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().commPageSize() > 0)
280422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return std::min(config().options().commPageSize(), abiPageSize());
2805affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
28066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return std::min(m_pInfo->commonPageSize(), abiPageSize());
2807affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2808affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2809affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine.
2810affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:125
281122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::abiPageSize() const
2812affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
281322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().maxPageSize() > 0)
281422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return config().options().maxPageSize();
2815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
28166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_pInfo->abiPageSize();
2817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2818affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2819affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other
2820affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit
2821affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:551
282222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const
2823affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
2824affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.other() != ResolveInfo::Default)
2825affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2826affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
282722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This is because the codeGenType of pie is DynObj. And gold linker check
282822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the "shared" option instead.
282922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
283022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
283122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
283222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj != config().codeGenType())
283322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
283422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
283522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().Bsymbolic())
2836affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2837affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
283822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // A local defined symbol should be non-preemptible.
283922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32
284022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relocation refers to a local defined symbol, and we should generate a
284122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relative dynamic relocation when applying the relocation.
284222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local)
2843affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2844affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
2846affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2847affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
284822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
284922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, symtab.h:645
28506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsDynRel(const ResolveInfo& pSym,
285122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     bool pSymHasPLT,
285222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     bool isAbsReloc) const
285322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
285422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // an undefined reference in the executables should be statically
285522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // resolved to 0 and no need a dynamic relocation
285622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isUndef() &&
285722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !pSym.isDyn() &&
2858d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::Exec   == config().codeGenType() ||
2859d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary == config().codeGenType()))
286022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
286122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // An absolute symbol can be resolved directly if it is either local
28636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // or we are linking statically. Otherwise it can still be overridden
28646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // at runtime.
28656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSym.isAbsolute() &&
28666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (pSym.binding() == ResolveInfo::Local || config().isCodeStatic()))
286722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
28686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() && isAbsReloc)
286922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
287022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymHasPLT && ResolveInfo::Function == pSym.type())
287122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
28726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().isCodeIndep() && pSymHasPLT)
287322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
287422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDyn() || pSym.isUndef() ||
287522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      isSymbolPreemptible(pSym))
287622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
287722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
287822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
287922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
288022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2881affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry
2882affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:596
28836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsPLT(const ResolveInfo& pSym) const
2884affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
288522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isUndef() &&
288622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !pSym.isDyn() &&
288722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LinkerConfig::DynObj != config().codeGenType())
2888affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2889affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2890affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry
2891affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() == ResolveInfo::IndirectFunc)
2892affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2893affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2894affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() != ResolveInfo::Function)
2895affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2896affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
28976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeStatic())
289822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
289922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
290022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
2901affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2902affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2903affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (pSym.isDyn() ||
2904affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          pSym.isUndef() ||
290522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          isSymbolPreemptible(pSym));
2906affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2907affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
290822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at
290922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time
291022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, Symbol::final_value_is_known
29116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolFinalValueIsKnown(const ResolveInfo& pSym) const
2912affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
291322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the output is pic code or if not executables, symbols' value may change
291422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // at runtime
29156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: CodeIndep() || LinkerConfig::Relocatable == CodeGenType
29166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() ||
2917d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::Exec != config().codeGenType() &&
2918d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary != config().codeGenType()))
2919affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
292022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
292122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is from dynamic object, then its value is unknown
292222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDyn())
2923affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
292422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
292522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is not in dynamic object and is not undefined, then its value
292622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // is known
292722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSym.isUndef())
2928affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2929affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
293022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is undefined and not in dynamic objects, for example, a weak
293122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // undefined symbol, then whether the symbol's final value can be known
293222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // depends on whrther we're doing static link
29336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return config().isCodeStatic();
2934affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2935affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2936affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
29376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsCopyReloc(const Relocation& pReloc,
293822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                        const ResolveInfo& pSym) const
2939affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
2940affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // only the reference from dynamic executable to non-function symbol in
2941affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // the dynamic objects may need copy relocation
29426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() ||
2943affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !pSym.isDyn() ||
2944affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.type() == ResolveInfo::Function ||
2945affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.size() == 0)
2946affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2947affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2948affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // check if the option -z nocopyreloc is given
294922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasNoCopyReloc())
2950affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2951affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2952affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // TODO: Is this check necessary?
2953affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if relocation target place is readonly, a copy relocation is needed
295422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag();
295522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE))
2956affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
29575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
29585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
29595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2960affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
296122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTDATASymbol()
296222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
296322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTDATA);
296422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
296522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
296622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
296722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTDATASymbol() const
296822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
296922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTDATA);
297022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
297122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
297222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
297322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTBSSSymbol()
297422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
297522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTBSS);
297622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
297722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
297822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
297922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTBSSSymbol() const
298022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
298122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(NULL != f_pTBSS);
298222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
298322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
298422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
298587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef GNULDBackend::getEntry(const Module& pModule) const
298687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
298787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pModule.getScript().hasEntry())
298887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return pModule.getScript().entry();
298987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else
299087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return getInfo().entry();
299187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
299287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
299322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection)
299422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
299522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_bHasTextRel)
299622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
299722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
299822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the target section of the dynamic relocation is ALLOCATE but is not
299922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // writable, than we should set DF_TEXTREL
300022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const uint32_t flag = pSection.flag();
300122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC))
300222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasTextRel = true;
300322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
300422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return;
300522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
300622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
300787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sortRelocation - sort the dynamic relocations to let dynamic linker
300887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// process relocations more efficiently
300987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::sortRelocation(LDSection& pSection)
301087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
301187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!config().options().hasCombReloc())
301287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
301387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
301487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(pSection.kind() == LDFileFormat::Relocation);
301587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
301687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  switch (config().codeGenType()) {
301787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  case LinkerConfig::DynObj:
301887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  case LinkerConfig::Exec:
301987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (&pSection == &getOutputFormat()->getRelDyn() ||
302087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        &pSection == &getOutputFormat()->getRelaDyn()) {
302187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (pSection.hasRelocData())
302287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        pSection.getRelocData()->sort(RelocCompare(*this));
302387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
302487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  default:
302587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
302687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
302787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
302887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
302922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation
303022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initBRIslandFactory()
303122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
303222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pBRIslandFactory) {
3033a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    m_pBRIslandFactory = new BranchIslandFactory(maxFwdBranchOffset(),
3034a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines                                                 maxBwdBranchOffset());
303522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
303622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
303722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
303822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
303922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation
304022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStubFactory()
304122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
304222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == m_pStubFactory) {
304322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pStubFactory = new StubFactory();
304422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
304522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
304622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
304722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::relax(Module& pModule, IRBuilder& pBuilder)
304922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
305022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!mayRelax())
305122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
305222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
305387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  getBRIslandFactory()->group(pModule);
305487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
305522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool finished = true;
305622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  do {
30576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (doRelax(pModule, pBuilder, finished)) {
305887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      setOutputSectionAddress(pModule);
305922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
306022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } while (!finished);
306122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
306222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
306322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
306422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::needGNUHash(const LDSymbol& X) const
30666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
30676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: in bfd and gold linker, an undefined symbol might be hashed
30686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // when the ouput is not PIC, if the symbol is referred by a non pc-relative
30696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // reloc, and its value is set to the addr of the plt entry.
30706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return !X.resolveInfo()->isUndef() && !X.isDyn();
30716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
30726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
30736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::operator()(const LDSymbol* X,
30746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             const LDSymbol* Y) const
30756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
30766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return !needGNUHash(*X) && needGNUHash(*Y);
30776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
30786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
307987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::RelocCompare::operator()(const Relocation* X,
308087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                            const Relocation* Y) const
308187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
308287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 1. compare if relocation is relative
308387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (X->symInfo() == NULL) {
308487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (Y->symInfo() != NULL)
308587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return true;
308687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } else if (Y->symInfo() == NULL) {
308787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
308887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } else {
308987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // 2. compare the symbol index
309087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    size_t symIdxX = m_Backend.getSymbolIdx(X->symInfo()->outSymbol());
309187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    size_t symIdxY = m_Backend.getSymbolIdx(Y->symInfo()->outSymbol());
309287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (symIdxX < symIdxY)
309387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return true;
309487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (symIdxX > symIdxY)
309587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return false;
309687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
309787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
309887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 3. compare the relocation address
309987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (X->place() < Y->place())
310087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return true;
310187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (X->place() > Y->place())
310287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
310387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
310487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 4. compare the relocation type
310587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (X->type() < Y->type())
310687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return true;
310787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (X->type() > Y->type())
310887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
310987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
311087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 5. compare the addend
311187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (X->addend() < Y->addend())
311287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return true;
311387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (X->addend() > Y->addend())
311487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
311587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
311687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return false;
311787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
3118