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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/InputTree.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerScript.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/ADT/SizeTraits.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Config/Config.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h"
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/BranchIslandFactory.h"
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h"
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrameHdr.h"
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFDynObjFileFormat.h"
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFExecFileFormat.h"
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h"
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFObjectFileFormat.h"
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegment.h"
2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegmentFactory.h"
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h"
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h"
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h"
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocationFactory.h"
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/StubFactory.h"
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Attribute.h"
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h"
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/SectionMap.h"
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operand.h"
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/OutputSectDesc.h"
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnEvaluator.h"
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileOutputBuffer.h"
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h"
4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFAttribute.h"
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFDynamic.h"
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNUInfo.h"
4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
450dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/ADT/StringRef.h>
4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Host.h>
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
480dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <algorithm>
490dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <cstring>
500dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <cassert>
510dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <map>
520dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <string>
530dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <vector>
540dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace {
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===----------------------------------------------------------------------===//
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesstatic const std::string simple_c_identifier_allowed_chars =
6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    "0123456789"
62b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    "abcdefghijklmnopqrstuvwxyz"
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    "_";
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier
6737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic bool isCIdentifier(const std::string& pName) {
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return (pName.find_first_not_of(simple_c_identifier_allowed_chars) ==
6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          std::string::npos);
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // anonymous namespace
73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend
78cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
79d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : TargetLDBackend(pConfig),
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pObjectReader(NULL),
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pDynObjFileFormat(NULL),
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pExecFileFormat(NULL),
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pObjectFileFormat(NULL),
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pInfo(pInfo),
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pELFSegmentTable(NULL),
8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pBRIslandFactory(NULL),
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pStubFactory(NULL),
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pEhFrameHdr(NULL),
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pAttribute(NULL),
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_bHasTextRel(false),
9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_bHasStaticTLS(false),
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pPreInitArrayStart(NULL),
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pPreInitArrayEnd(NULL),
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pInitArrayStart(NULL),
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pInitArrayEnd(NULL),
9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pFiniArrayStart(NULL),
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pFiniArrayEnd(NULL),
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pStack(NULL),
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pDynamic(NULL),
10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pTDATA(NULL),
10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pTBSS(NULL),
10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pExecutableStart(NULL),
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pEText(NULL),
10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_p_EText(NULL),
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_p__EText(NULL),
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pEData(NULL),
10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_p_EData(NULL),
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pBSSStart(NULL),
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pEnd(NULL),
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_p_End(NULL) {
11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pELFSegmentTable = new ELFSegmentFactory();
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pSymIndexMap = new HashTableType(1024);
11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pAttribute = new ELFAttribute(*this, pConfig);
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11737b74a387bb3993387029859c2d9d051c41c724eStephen HinesGNULDBackend::~GNULDBackend() {
11887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  delete m_pELFSegmentTable;
119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  delete m_pInfo;
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pDynObjFileFormat;
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pExecFileFormat;
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pObjectFileFormat;
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pSymIndexMap;
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pEhFrameHdr;
12587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  delete m_pAttribute;
1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pBRIslandFactory;
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  delete m_pStubFactory;
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13037b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t GNULDBackend::sectionStartOffset() const {
131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Binary == config().codeGenType())
132d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return 0x0;
133d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (config().targets().bitclass()) {
135d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 32u:
136d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf32_Ehdr) +
13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             elfSegmentTable().size() * sizeof(llvm::ELF::Elf32_Phdr);
138d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case 64u:
139d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return sizeof(llvm::ELF::Elf64_Ehdr) +
14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             elfSegmentTable().size() * sizeof(llvm::ELF::Elf64_Phdr);
141d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default:
142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      fatal(diag::unsupported_bitclass) << config().targets().triple().str()
143d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        << config().targets().bitclass();
144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return 0;
145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSegmentStartAddr(const LinkerScript& pScript) const {
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LinkerScript::AddressMap::const_iterator mapping =
15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pScript.addressMap().find(".text");
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pScript.addressMap().end() != mapping)
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return mapping.getEntry()->value();
1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (config().isCodeIndep())
154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return 0x0;
155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_pInfo->defaultTextSegmentAddr();
157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15937b74a387bb3993387029859c2d9d051c41c724eStephen HinesGNUArchiveReader* GNULDBackend::createArchiveReader(Module& pModule) {
16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pObjectReader != NULL);
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new GNUArchiveReader(pModule, *m_pObjectReader);
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16437b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder) {
165d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_pObjectReader = new ELFObjectReader(*this, pBuilder, config());
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_pObjectReader;
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16937b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder) {
170d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFDynObjReader(*this, pBuilder, config());
171d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
172d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
17337b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder) {
17487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return new ELFBinaryReader(pBuilder, config());
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17737b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFObjectWriter* GNULDBackend::createWriter() {
178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return new ELFObjectWriter(*this, config());
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initStdSections(ObjectBuilder& pBuilder) {
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
18437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (m_pDynObjFileFormat == NULL)
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pDynObjFileFormat = new ELFDynObjFileFormat();
186d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pDynObjFileFormat->initStdSections(pBuilder,
187d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (m_pExecFileFormat == NULL)
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pExecFileFormat = new ELFExecFileFormat();
194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pExecFileFormat->initStdSections(pBuilder,
195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         config().targets().bitclass());
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
19937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (m_pObjectFileFormat == NULL)
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        m_pObjectFileFormat = new ELFObjectFileFormat();
201d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_pObjectFileFormat->initStdSections(pBuilder,
202d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                           config().targets().bitclass());
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return false;
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols.
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations.
21337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initStandardSymbols(IRBuilder& pBuilder, Module& pModule) {
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // GNU extension: define __start and __stop symbols for the sections whose
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name can be presented as C symbol
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator iter, iterEnd = pModule.end();
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (iter = pModule.begin(); iter != iterEnd; ++iter) {
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    LDSection* section = *iter;
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch (section->kind()) {
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame:
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasEhFrame())
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!section->hasSectionData())
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          continue;
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
23437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }  // end of switch
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (isCIdentifier(section->name())) {
237f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      std::string start_name = "__start_" + section->name();
23837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef* start_fragref =
23937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          FragmentRef::Create(section->getSectionData()->front(), 0x0);
24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
24237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          start_name,
24337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
24437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
24537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
24637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,            // size
24737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,            // value
24837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          start_fragref,  // FragRef
24937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Default);
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      std::string stop_name = "__stop_" + section->name();
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      FragmentRef* stop_fragref = FragmentRef::Create(
25337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          section->getSectionData()->front(), section->size());
2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
25537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          stop_name,
25637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
25737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
25837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
25937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,           // size
26037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,           // value
26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          stop_fragref,  // FragRef
26237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Default);
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .preinit_array
270cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* preinit_array = NULL;
271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasPreInitArray()) {
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Create(
27337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        file_format->getPreInitArray().getSectionData()->front(), 0x0);
27437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    preinit_array = FragmentRef::Null();
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
27737b74a387bb3993387029859c2d9d051c41c724eStephen Hines
278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayStart =
27937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
28037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          "__preinit_array_start",
28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
28237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
28337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
28437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,            // size
28537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,            // value
28637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          preinit_array,  // FragRef
28737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Hidden);
28837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayEnd =
29037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
29137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          "__preinit_array_end",
29237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
29337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
29437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
29537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,                  // size
29637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,                  // value
29737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          FragmentRef::Null(),  // FragRef
29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Hidden);
299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .init_array
301cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* init_array = NULL;
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInitArray()) {
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Create(
30437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        file_format->getInitArray().getSectionData()->front(), 0x0);
30537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    init_array = FragmentRef::Null();
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayStart =
31037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
31137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          "__init_array_start",
31237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
31337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
31437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
31537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // size
31637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // value
31737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          init_array,  // FragRef
31837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Hidden);
31937b74a387bb3993387029859c2d9d051c41c724eStephen Hines
320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayEnd =
32137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
32237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          "__init_array_end",
32337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
32437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
32537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
32637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // size
32737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // value
32837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          init_array,  // FragRef
32937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Hidden);
330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .fini_array
332cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* fini_array = NULL;
333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasFiniArray()) {
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Create(
33537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        file_format->getFiniArray().getSectionData()->front(), 0x0);
33637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fini_array = FragmentRef::Null();
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayStart =
34137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
34237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          "__fini_array_start",
34337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
34437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
34537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
34637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // size
34737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // value
34837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          fini_array,  // FragRef
34937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Hidden);
35037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayEnd =
35237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
35337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          "__fini_array_end",
35437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
35537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
35637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Global,
35737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // size
35837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,         // value
35937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          fini_array,  // FragRef
36037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Hidden);
361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .stack
363cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* stack = NULL;
364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasStack()) {
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Create(
36637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        file_format->getStack().getSectionData()->front(), 0x0);
36737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    stack = FragmentRef::Null();
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_pStack = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
37237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "__stack",
37337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
37537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Global,
37637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,    // size
37737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,    // value
37837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      stack,  // FragRef
37937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Hidden);
380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // _DYNAMIC
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO: add SectionData for .dynamic section, and then we can get the correct
38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol section index for _DYNAMIC. Now it will be ABS.
38437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_pDynamic = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
38537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "_DYNAMIC",
38637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Object,
38737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
38837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Local,
38937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
39037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
39137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
39237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Hidden);
39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pExecutableStart =
39637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
39737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          "__executable_start",
39837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::NoType,
39937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Define,
40037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Absolute,
40137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,                  // size
40237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          0x0,                  // value
40337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          FragmentRef::Null(),  // FragRef
40437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Default);
40537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
40637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_pEText = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
40737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "etext",
40837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
40937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
41037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
41137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
41237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
41337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
41437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
41537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
41637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_p_EText = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
41737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "_etext",
41837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
41937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
42037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
42137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
42237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
42337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
42437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
42537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_p__EText = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
42637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "__etext",
42737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
42837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
42937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
43037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
43137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
43237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
43437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_pEData = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
43537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "edata",
43637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
43737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
43837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
43937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
44037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
44137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
44237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
44337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
44437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_pEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
44537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "end",
44637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
44737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
44837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
44937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
45037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
45137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
45237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _edata is defined forcefully.
45537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_p_EData = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
45637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "_edata",
45737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
45837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
45937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
46037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
46137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
46237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
46337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // __bss_start is defined forcefully.
46637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_pBSSStart = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
46737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "__bss_start",
46837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
46937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
47037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
47137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
47237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
47337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
47437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _end is defined forcefully.
47737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  f_p_End = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
47837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      "_end",
47937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::NoType,
48037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Define,
48137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Absolute,
48237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // size
48337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      0x0,                  // value
48437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      FragmentRef::Null(),  // FragRef
48537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ResolveInfo::Default);
486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
49037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::finalizeStandardSymbols() {
49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType())
49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
49737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pPreInitArrayStart != NULL) {
498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pPreInitArrayStart->hasFragRef()) {
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->setValue(0x0);
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
50437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pPreInitArrayEnd != NULL) {
505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pPreInitArrayEnd->hasFragRef()) {
506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() +
507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   file_format->getPreInitArray().size());
50837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(0x0);
511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
51437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pInitArrayStart != NULL) {
515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pInitArrayStart->hasFragRef()) {
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->setValue(0x0);
518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
52137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pInitArrayEnd != NULL) {
522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pInitArrayEnd->hasFragRef()) {
523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() +
524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getInitArray().size());
52537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(0x0);
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
53137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pFiniArrayStart != NULL) {
532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pFiniArrayStart->hasFragRef()) {
533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->setValue(0x0);
535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
53837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pFiniArrayEnd != NULL) {
539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pFiniArrayEnd->hasFragRef()) {
540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() +
541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getFiniArray().size());
54237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(0x0);
545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
54837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pStack != NULL) {
549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pStack->hasFragRef()) {
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute);
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->setValue(0x0);
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
55537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pDynamic != NULL) {
55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local);
55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setValue(file_format->getDynamic().addr());
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    f_pDynamic->setSize(file_format->getDynamic().size());
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
56237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pExecutableStart != NULL) {
56387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::const_iterator exec_start =
56437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        elfSegmentTable().find(llvm::ELF::PT_LOAD, 0x0, 0x0);
56587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (elfSegmentTable().end() != exec_start) {
566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) {
567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pExecutableStart->setValue(f_pExecutableStart->value() +
56887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                     (*exec_start)->vaddr());
569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
57037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pExecutableStart->setValue(0x0);
57237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
57537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pEText != NULL || f_p_EText != NULL || f_p__EText != NULL) {
57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ELFSegmentFactory::const_iterator etext = elfSegmentTable().find(
57737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        llvm::ELF::PT_LOAD, llvm::ELF::PF_X, llvm::ELF::PF_W);
57887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (elfSegmentTable().end() != etext) {
57937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pEText != NULL && ResolveInfo::ThreadLocal != f_pEText->type()) {
58037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_pEText->setValue(f_pEText->value() + (*etext)->vaddr() +
58187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                           (*etext)->memsz());
582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
58337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p_EText != NULL && ResolveInfo::ThreadLocal != f_p_EText->type()) {
58437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_p_EText->setValue(f_p_EText->value() + (*etext)->vaddr() +
58587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*etext)->memsz());
586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
58737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p__EText != NULL &&
58837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::ThreadLocal != f_p__EText->type()) {
58937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_p__EText->setValue(f_p__EText->value() + (*etext)->vaddr() +
59037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                             (*etext)->memsz());
591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
59237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
59337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pEText != NULL)
594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(0x0);
59537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p_EText != NULL)
596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(0x0);
59737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p__EText != NULL)
598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(0x0);
599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
60237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pEData != NULL || f_p_EData != NULL || f_pBSSStart != NULL ||
60337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      f_pEnd != NULL || f_p_End != NULL) {
60487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::const_iterator edata =
60537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        elfSegmentTable().find(llvm::ELF::PT_LOAD, llvm::ELF::PF_W, 0x0);
60687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (elfSegmentTable().end() != edata) {
60737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pEData != NULL && ResolveInfo::ThreadLocal != f_pEData->type()) {
60837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_pEData->setValue(f_pEData->value() + (*edata)->vaddr() +
60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                           (*edata)->filesz());
610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
61137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p_EData != NULL && ResolveInfo::ThreadLocal != f_p_EData->type()) {
61237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_p_EData->setValue(f_p_EData->value() + (*edata)->vaddr() +
61387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*edata)->filesz());
614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
61537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pBSSStart != NULL &&
61637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
61737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_pBSSStart->setValue(f_pBSSStart->value() + (*edata)->vaddr() +
61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              (*edata)->filesz());
619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
62137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pEnd != NULL && ResolveInfo::ThreadLocal != f_pEnd->type()) {
62237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_pEnd->setValue(f_pEnd->value() + (*edata)->vaddr() +
62387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (*edata)->memsz());
624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
62537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p_End != NULL && ResolveInfo::ThreadLocal != f_p_End->type()) {
62637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        f_p_End->setValue(f_p_End->value() + (*edata)->vaddr() +
62787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          (*edata)->memsz());
628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
62937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
63037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pEData != NULL)
631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(0x0);
63237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p_EData != NULL)
633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(0x0);
63437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pBSSStart != NULL)
635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(0x0);
636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
63737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_pEnd != NULL)
638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(0x0);
63937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (f_p_End != NULL)
640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(0x0);
641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
64737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol) {
64822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ignore if symbol has no fragRef
64922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSymbol.hasFragRef())
65022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
65222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the value of a TLS symbol is the offset to the TLS segment
65387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator tls_seg =
65437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      elfSegmentTable().find(llvm::ELF::PT_TLS, llvm::ELF::PF_R, 0x0);
65587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(tls_seg != elfSegmentTable().end());
65622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t value = pSymbol.fragRef()->getOutputOffset();
65737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint64_t addr = pSymbol.fragRef()->frag()->getParent()->getSection().addr();
65887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymbol.setValue(value + addr - (*tls_seg)->vaddr());
65922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
66237b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFFileFormat* GNULDBackend::getOutputFormat() {
66322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
66422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
66537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(m_pDynObjFileFormat != NULL);
66622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
66722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
668d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
66937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(m_pExecFileFormat != NULL);
67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
67122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
67237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(m_pObjectFileFormat != NULL);
67322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
67522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
68037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ELFFileFormat* GNULDBackend::getOutputFormat() const {
68122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch (config().codeGenType()) {
68222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj:
68337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(m_pDynObjFileFormat != NULL);
68422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pDynObjFileFormat;
68522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Exec:
686d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary:
68737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(m_pExecFileFormat != NULL);
68822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pExecFileFormat;
68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object:
69037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(m_pObjectFileFormat != NULL);
69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return m_pObjectFileFormat;
692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
69322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unrecognized_output_file) << config().codeGenType();
694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
69887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sizeShstrtab - compute the size of .shstrtab
69937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sizeShstrtab(Module& pModule) {
70087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t shstrtab = 0;
70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // compute the size of .shstrtab section.
70287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::const_iterator sect, sectEnd = pModule.end();
70387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
70487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    shstrtab += (*sect)->name().size() + 1;
70537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of for
70687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  getOutputFormat()->getShStrTab().setSize(shstrtab);
70787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
70887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab,
71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab.
71237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sizeNamePools(Module& pModule) {
713f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  assert(LinkerConfig::Unset != config().codePosition());
714f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // number of entries in symbol tables starts from 1 to hold the special entry
7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
71722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t symtab = 1;
71837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t dynsym = config().isCodeStatic() ? 0 : 1;
71922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
72022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // size of string tables starts from 1 to hold the null character in their
72122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // first byte
72237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t strtab = 1;
72337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t dynstr = config().isCodeStatic() ? 0 : 1;
72437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t hash = 0;
72537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t gnuhash = 0;
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // number of local symbol in the .symtab and .dynsym
7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symtab_local_cnt = 0;
729d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  size_t dynsym_local_cnt = 0;
730d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd;
7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// Compute the size of .symtab, .strtab, and symtab_local_cnt
73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @{
73587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /* TODO:
73687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       1. discard locals and temporary locals
73787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines       2. check whether the symbol is used
73887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines   */
73987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  switch (config().options().getStripSymbolMode()) {
7402bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar    case GeneralOptions::StripSymbolMode::StripAllSymbols: {
74187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symtab = strtab = 0;
74287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
74387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
74487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    default: {
74587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symEnd = symbols.end();
74687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (symbol = symbols.begin(); symbol != symEnd; ++symbol) {
74787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ++symtab;
74887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (hasEntryInStrTab(**symbol))
74987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          strtab += (*symbol)->nameSize() + 1;
75087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
75187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      symtab_local_cnt = 1 + symbols.numOfFiles() + symbols.numOfLocals() +
75287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         symbols.numOfLocalDyns();
75387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
75487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
75537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of switch
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
75937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  switch (config().codeGenType()) {
76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::DynObj: {
76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // soname
76287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      dynstr += config().options().soname().size() + 1;
76322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    /** fall through **/
765d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Exec:
766d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case LinkerConfig::Binary: {
767f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (!config().isCodeStatic()) {
7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        /// Compute the size of .dynsym, .dynstr, and dynsym_local_cnt
7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        symEnd = symbols.dynamicEnd();
7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) {
7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          ++dynsym;
772f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (hasEntryInStrTab(**symbol))
7736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*symbol)->nameSize() + 1;
7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        dynsym_local_cnt = 1 + symbols.numOfLocalDyns();
7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // compute .gnu.hash
7782bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar        if (config().options().hasGNUHash()) {
7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // count the number of dynsym to hash
7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          size_t hashed_sym_cnt = 0;
7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          symEnd = symbols.dynamicEnd();
7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          for (symbol = symbols.dynamicBegin(); symbol != symEnd; ++symbol) {
7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            if (DynsymCompare().needGNUHash(**symbol))
7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              ++hashed_sym_cnt;
7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          }
7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Special case for empty .dynsym
7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (hashed_sym_cnt == 0)
7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash = 5 * 4 + config().targets().bitclass() / 8;
7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          else {
7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            size_t nbucket = getHashBucketCount(hashed_sym_cnt, true);
7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash = (4 + nbucket + hashed_sym_cnt) * 4;
7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            gnuhash += (1U << getGNUHashMaskbitslog2(hashed_sym_cnt)) / 8;
7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
79622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // compute .hash
7972bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar        if (config().options().hasSysVHash()) {
7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // Both Elf32_Word and Elf64_Word are 4 bytes
7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                 sizeof(llvm::ELF::Elf32_Word);
8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // add DT_NEEDED
8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        Module::const_lib_iterator lib, libEnd = pModule.lib_end();
8056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) {
8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*lib)->name().size() + 1;
8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynamic().reserveNeedEntry();
8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          }
8106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // add DT_RPATH
8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (!config().options().getRpathList().empty()) {
8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          dynamic().reserveNeedEntry();
8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          GeneralOptions::const_rpath_iterator rpath,
81637b74a387bb3993387029859c2d9d051c41c724eStephen Hines              rpathEnd = config().options().rpath_end();
81737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          for (rpath = config().options().rpath_begin(); rpath != rpathEnd;
81837b74a387bb3993387029859c2d9d051c41c724eStephen Hines               ++rpath)
8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            dynstr += (*rpath).size() + 1;
8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set size
8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (config().targets().is32Bits()) {
8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          file_format->getDynSymTab().setSize(dynsym *
8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                              sizeof(llvm::ELF::Elf32_Sym));
8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        } else {
8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          file_format->getDynSymTab().setSize(dynsym *
8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                              sizeof(llvm::ELF::Elf64_Sym));
8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynStrTab().setSize(dynstr);
8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getHashTab().setSize(hash);
8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getGNUHashTab().setSize(gnuhash);
8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // set .dynsym sh_info to one greater than the symbol table
8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // index of the last local symbol
8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynSymTab().setInfo(dynsym_local_cnt);
8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // Because some entries in .dynamic section need information of .dynsym,
8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // entries until we get the size of the sections mentioned above
8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        dynamic().reserveEntries(*file_format);
8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        file_format->getDynamic().setSize(dynamic().numOfBytes());
8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /* fall through */
84622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LinkerConfig::Object: {
847d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits())
84837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        file_format->getSymTab().setSize(symtab * sizeof(llvm::ELF::Elf32_Sym));
8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
85037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        file_format->getSymTab().setSize(symtab * sizeof(llvm::ELF::Elf64_Sym));
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getStrTab().setSize(strtab);
852d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
853d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // set .symtab sh_info to one greater than the symbol table
854d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // index of the last local symbol
8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      file_format->getSymTab().setInfo(symtab_local_cnt);
8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
85787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // The size of .shstrtab should be decided after output sections are all
85887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // set, so we just set it to 1 here.
85987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      file_format->getShStrTab().setSize(0x1);
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
86222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    default:
86322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::fatal_illegal_codegen_type) << pModule.name();
86422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      break;
86537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of switch
86622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
86722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
86822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol
86922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym,
87022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
87122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
87222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
87337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                size_t pSymtabIdx) {
87437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // FIXME: check the endian between host and target
87537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // write out symbol
87637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (hasEntryInStrTab(pSymbol)) {
87737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    pSym.st_name = pStrtabsize;
87837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ::memcpy((pStrtab + pStrtabsize), pSymbol.name(), pSymbol.nameSize());
87937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
88037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    pSym.st_name = 0;
88137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
88237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_value = pSymbol.value();
88337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_size = getSymbolSize(pSymbol);
88437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_info = getSymbolInfo(pSymbol);
88537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_other = pSymbol.visibility();
88637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_shndx = getSymbolShndx(pSymbol);
88722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
88822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
88922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol
89022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym,
89122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                LDSymbol& pSymbol,
89222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                char* pStrtab,
89322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                size_t pStrtabsize,
89437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                size_t pSymtabIdx) {
89537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // FIXME: check the endian between host and target
89637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // write out symbol
89737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (hasEntryInStrTab(pSymbol)) {
89837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    pSym.st_name = pStrtabsize;
89937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ::memcpy((pStrtab + pStrtabsize), pSymbol.name(), pSymbol.nameSize());
90037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
90137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    pSym.st_name = 0;
90237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
90337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_value = pSymbol.value();
90437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_size = getSymbolSize(pSymbol);
90537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_info = getSymbolInfo(pSymbol);
90637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_other = pSymbol.visibility();
90737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSym.st_shndx = getSymbolShndx(pSymbol);
9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab
9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
91422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule,
91537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                    FileOutputBuffer& pOutput) {
91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
91787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!file_format->hasSymTab())
91887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
9195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getSymTab();
9215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getStrTab();
9225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
92337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MemoryRegion symtab_region =
92437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pOutput.request(symtab_sect.offset(), symtab_sect.size());
92537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MemoryRegion strtab_region =
92637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pOutput.request(strtab_sect.offset(), strtab_sect.size());
9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
9295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
9305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
931d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
93287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin();
933d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
93487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin();
935d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
936d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
937d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
938d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
939d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
9405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
94137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  char* strtab = reinterpret_cast<char*>(strtab_region.begin());
9425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit the first ELF symbol
9446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits())
9456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0);
9466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
9476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0);
9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
94922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool sym_exist = false;
95022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  HashTableType::entry_type* entry = NULL;
95122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry = m_pSymIndexMap->insert(LDSymbol::Null(), sym_exist);
95322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(0);
95422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
95522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symIdx = 1;
9575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
9586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const Module::SymbolTable& symbols = pModule.getSymbolTable();
9606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd;
9616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
9626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symEnd = symbols.end();
9636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = symbols.begin(); symbol != symEnd; ++symbol) {
96422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LinkerConfig::Object == config().codeGenType()) {
96522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      entry = m_pSymIndexMap->insert(*symbol, sym_exist);
9666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      entry->setValue(symIdx);
9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
968d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
9696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx);
97022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
9716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx);
9726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symIdx;
973f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (hasEntryInStrTab(**symbol))
97422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
9775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
97822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
9795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
9805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
9815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
98237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::emitDynNamePools(Module& pModule,
98337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                    FileOutputBuffer& pOutput) {
98422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
98537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (!file_format->hasDynSymTab() || !file_format->hasDynStrTab() ||
98622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      !file_format->hasDynamic())
98722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
9885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
9905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
9915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
9935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
99437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  LDSection& dyn_sect = file_format->getDynamic();
99537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
99637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MemoryRegion symtab_region =
99737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pOutput.request(symtab_sect.offset(), symtab_sect.size());
99837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MemoryRegion strtab_region =
99937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pOutput.request(strtab_sect.offset(), strtab_sect.size());
100037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MemoryRegion dyn_region = pOutput.request(dyn_sect.offset(), dyn_sect.size());
10015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
1004d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().targets().is32Bits())
100587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin();
1006d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (config().targets().is64Bits())
100787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin();
1008d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
1009d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    fatal(diag::unsupported_bitclass) << config().targets().triple().str()
1010d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      << config().targets().bitclass();
1011d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
101437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  char* strtab = reinterpret_cast<char*>(strtab_region.begin());
10155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit the first ELF symbol
10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits())
10186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0);
10196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0);
10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symIdx = 1;
10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .gnu.hash
10272bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar  if (config().options().hasGNUHash())
10286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitGNUHashTab(symbols, pOutput);
1029f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
10306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .hash
10312bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar  if (config().options().hasSysVHash())
10326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitELFHashTab(symbols, pOutput);
10336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category)
10356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = symbols.dynamicEnd();
10366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) {
1037d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (config().targets().is32Bits())
10386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx);
103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
10406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx);
10415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // maintain output's symbol and index map
10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
10436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry->setValue(symIdx);
104422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // sum up counters
10456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++symIdx;
1046f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (hasEntryInStrTab(**symbol))
104722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      strtabsize += (*symbol)->nameSize() + 1;
10485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
10515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
10525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
105322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::const_lib_iterator lib, libEnd = pModule.lib_end();
105422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) {
105637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ::memcpy((strtab + strtabsize),
105737b74a387bb3993387029859c2d9d051c41c724eStephen Hines               (*lib)->name().c_str(),
105837b74a387bb3993387029859c2d9d051c41c724eStephen Hines               (*lib)->name().size());
10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
10606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtabsize += (*lib)->name().size() + 1;
10616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++dt_need;
10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().options().getRpathList().empty()) {
10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (!config().options().hasNewDTags())
10676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_RPATH, strtabsize);
10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (*dt_need)->setValue(llvm::ELF::DT_RUNPATH, strtabsize);
10706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++dt_need;
10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    GeneralOptions::const_rpath_iterator rpath,
107337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        rpathEnd = config().options().rpath_end();
10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (rpath = config().options().rpath_begin(); rpath != rpathEnd; ++rpath) {
10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      memcpy((strtab + strtabsize), (*rpath).data(), (*rpath).size());
10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtabsize += (*rpath).size();
10776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      strtab[strtabsize++] = (rpath + 1 == rpathEnd ? '\0' : ':');
10785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
107922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
10805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
108222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
108322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // set pointer to SONAME entry in dynamic string table.
1084affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
108522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1086d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  dynamic().applyEntries(*file_format);
108787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  dynamic().emit(dyn_sect, dyn_region);
10885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
108922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // emit soname
109022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType()) {
109137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ::memcpy((strtab + strtabsize),
109237b74a387bb3993387029859c2d9d051c41c724eStephen Hines             config().options().soname().c_str(),
109337b74a387bb3993387029859c2d9d051c41c724eStephen Hines             config().options().soname().size());
109487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    strtabsize += config().options().soname().size() + 1;
109522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
10975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitELFHashTab - emit .hash
10996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitELFHashTab(const Module::SymbolTable& pSymtab,
110037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  FileOutputBuffer& pOutput) {
11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
11026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!file_format->hasHashTab())
11036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
11046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSection& hash_sect = file_format->getHashTab();
110537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MemoryRegion hash_region =
110637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pOutput.request(hash_sect.offset(), hash_sect.size());
11075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
11085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
110937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t* word_array = reinterpret_cast<uint32_t*>(hash_region.begin());
11105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
111137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t& nchain = word_array[1];
11125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t dynsymSize = 1 + pSymtab.numOfLocalDyns() + pSymtab.numOfDynamics();
11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  nbucket = getHashBucketCount(dynsymSize, false);
111537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  nchain = dynsymSize;
11165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
111837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t* chain = (bucket + nbucket);
11195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
112137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  memset(reinterpret_cast<void*>(bucket), 0, nbucket);
11225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  hash::StringHash<hash::ELF> hash_func;
11245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t idx = 1;
11266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd();
11276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.localDynBegin(); symbol != symEnd; ++symbol) {
11286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    llvm::StringRef name((*symbol)->name());
11296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    size_t bucket_pos = hash_func(name) % nbucket;
11306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    chain[idx] = bucket[bucket_pos];
11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bucket[bucket_pos] = idx;
11326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++idx;
11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
11346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
11356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitGNUHashTab - emit .gnu.hash
11376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitGNUHashTab(Module::SymbolTable& pSymtab,
113837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  FileOutputBuffer& pOutput) {
11396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFFileFormat* file_format = getOutputFormat();
11406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!file_format->hasGNUHashTab())
11416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
11426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
114387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MemoryRegion gnuhash_region =
114437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pOutput.request(file_format->getGNUHashTab().offset(),
114537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                      file_format->getGNUHashTab().size());
11466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
114737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t* word_array = reinterpret_cast<uint32_t*>(gnuhash_region.begin());
11486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // fixed-length fields
114937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t& nbucket = word_array[0];
115037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t& symidx = word_array[1];
11516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t& maskwords = word_array[2];
115237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t& shift2 = word_array[3];
11536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // variable-length fields
115437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint8_t* bitmask = reinterpret_cast<uint8_t*>(word_array + 4);
115537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t* bucket = NULL;
115637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t* chain = NULL;
11576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // count the number of dynsym to hash
11596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t unhashed_sym_cnt = pSymtab.numOfLocalDyns();
116037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t hashed_sym_cnt = pSymtab.numOfDynamics();
11616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd();
11626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.dynamicBegin(); symbol != symEnd; ++symbol) {
11636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (DynsymCompare().needGNUHash(**symbol))
11646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
116537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ++unhashed_sym_cnt;
116637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    --hashed_sym_cnt;
11676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
11686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // special case for the empty hash table
11706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (hashed_sym_cnt == 0) {
117137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    nbucket = 1;                    // one empty bucket
117237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    symidx = 1 + unhashed_sym_cnt;  // symidx above unhashed symbols
117337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    maskwords = 1;                  // bitmask length
117437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    shift2 = 0;                     // bloom filter
11756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (config().targets().is32Bits()) {
117737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      uint32_t* maskval = reinterpret_cast<uint32_t*>(bitmask);
117837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      *maskval = 0;  // no valid hashes
11796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    } else {
11806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // must be 64
118137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      uint64_t* maskval = reinterpret_cast<uint64_t*>(bitmask);
118237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      *maskval = 0;  // no valid hashes
11835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
118437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    bucket = reinterpret_cast<uint32_t*>(bitmask +
118537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         config().targets().bitclass() / 8);
118637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    *bucket = 0;  // no hash in the only bucket
11876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
11885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
11896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbitslog2 = getGNUHashMaskbitslog2(hashed_sym_cnt);
11916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbits = 1u << maskbitslog2;
11926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t shift1 = config().targets().is32Bits() ? 5 : 6;
11936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t mask = (1u << shift1) - 1;
11946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
119537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  nbucket = getHashBucketCount(hashed_sym_cnt, true);
119637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  symidx = 1 + unhashed_sym_cnt;
11976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  maskwords = 1 << (maskbitslog2 - shift1);
119837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  shift2 = maskbitslog2;
11996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // setup bucket and chain
120137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bucket = reinterpret_cast<uint32_t*>(bitmask + maskbits / 8);
120237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  chain = (bucket + nbucket);
12036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // build the gnu style hash table
120537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef std::multimap<uint32_t, std::pair<LDSymbol*, uint32_t> > SymMapType;
12066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  SymMapType symmap;
12076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  symEnd = pSymtab.dynamicEnd();
12086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (symbol = pSymtab.localDynBegin() + symidx - 1; symbol != symEnd;
120937b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++symbol) {
1210f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    hash::StringHash<hash::DJB> hasher;
12116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t djbhash = hasher((*symbol)->name());
12126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    uint32_t hash = djbhash % nbucket;
12136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    symmap.insert(std::make_pair(hash, std::make_pair(*symbol, djbhash)));
12146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
12156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // compute bucket, chain, and bitmask
12176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  std::vector<uint64_t> bitmasks(maskwords);
12186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t hashedidx = symidx;
12196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (size_t idx = 0; idx < nbucket; ++idx) {
12206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    size_t count = 0;
12216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    std::pair<SymMapType::iterator, SymMapType::iterator> ret;
12226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ret = symmap.equal_range(idx);
122337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    for (SymMapType::iterator it = ret.first; it != ret.second;) {
12246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // rearrange the hashed symbol ordering
12256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *(pSymtab.localDynBegin() + hashedidx - 1) = it->second.first;
12266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t djbhash = it->second.second;
12276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      uint32_t val = ((djbhash >> shift1) & ((maskbits >> shift1) - 1));
12286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bitmasks[val] |= 1u << (djbhash & mask);
12296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bitmasks[val] |= 1u << ((djbhash >> shift2) & mask);
12306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      val = djbhash & ~1u;
12316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // advance the iterator and check if we're dealing w/ the last elment
12326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (++it == ret.second) {
12336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // last element terminates the chain
12346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        val |= 1;
12356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
12366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      chain[hashedidx - symidx] = val;
12376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++hashedidx;
12396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      ++count;
12405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (count == 0)
12436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bucket[idx] = 0;
12446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
12456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      bucket[idx] = hashedidx - count;
12466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
12476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
12486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // write the bitmasks
12496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().is32Bits()) {
125037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    uint32_t* maskval = reinterpret_cast<uint32_t*>(bitmask);
12516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (size_t i = 0; i < maskwords; ++i)
12526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      std::memcpy(maskval + i, &bitmasks[i], 4);
12536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else {
12546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // must be 64
125537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    uint64_t* maskval = reinterpret_cast<uint64_t*>(bitmask);
12566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (size_t i = 0; i < maskwords; ++i)
12576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      std::memcpy(maskval + i, &bitmasks[i], 8);
12585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section
126237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sizeInterp() {
1263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const char* dyld_name;
126422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasDyld())
126522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dyld_name = config().options().dyld().c_str();
1266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
12676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dyld_name = m_pInfo->dyld();
1268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
126922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& interp = getOutputFormat()->getInterp();
1270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  interp.setSize(std::strlen(dyld_name) + 1);
1271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp
127437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::emitInterp(FileOutputBuffer& pOutput) {
127522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasInterp()) {
127622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const LDSection& interp = getOutputFormat()->getInterp();
127787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    MemoryRegion region = pOutput.request(interp.offset(), interp.size());
127822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    const char* dyld_name;
127922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasDyld())
128022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      dyld_name = config().options().dyld().c_str();
128122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else
12826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      dyld_name = m_pInfo->dyld();
1283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
128487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    std::memcpy(region.begin(), dyld_name, interp.size());
128522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
128837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const {
1289f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ResolveInfo::Section != pSym.type();
1290f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
1291f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
129237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::orderSymbolTable(Module& pModule) {
1293f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  Module::SymbolTable& symbols = pModule.getSymbolTable();
1294f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
12952bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar  if (config().options().hasGNUHash()) {
1296f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // Currently we may add output symbols after sizeNamePools(), and a
1297f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // non-stable sort is used in SymbolCategory::arrange(), so we just
1298f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // sort .dynsym right before emitting .gnu.hash
129937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    std::stable_sort(
130037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        symbols.dynamicBegin(), symbols.dynamicEnd(), DynsymCompare());
13012bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar  }
1302f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
1303f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
13045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder
130537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const {
130622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* file_format = getOutputFormat();
130722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // NULL section should be the "1st" section
13095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (LDFileFormat::Null == pSectHdr.kind())
131087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return SHO_NULL;
13115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
131222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (&pSectHdr == &file_format->getStrTab())
131322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return SHO_STRTAB;
131422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the section is not ALLOC, lay it out until the last possible moment
13165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC))
13175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_UNDEFINED;
13185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0;
13205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0;
13215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: need to take care other possible output sections
13225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pSectHdr.kind()) {
13230dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    case LDFileFormat::TEXT:
13240dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    case LDFileFormat::DATA:
13255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (is_exec) {
13265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getInit())
13275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_INIT;
13285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getFini())
13295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_FINI;
13305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_TEXT;
13315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else if (!is_write) {
13325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RO;
13335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else {
133422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (config().options().hasRelro()) {
133522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (&pSectHdr == &file_format->getPreInitArray() ||
133622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getInitArray() ||
133722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              &pSectHdr == &file_format->getFiniArray() ||
1338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getCtors() ||
1339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getDtors() ||
1340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getJCR() ||
1341d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao              &pSectHdr == &file_format->getDataRelRo())
1342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO;
134337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1344d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          if (&pSectHdr == &file_format->getDataRelRoLocal())
1345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO_LOCAL;
134637b74a387bb3993387029859c2d9d051c41c724eStephen Hines
134737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          // Make special sections that end with .rel.ro suffix as RELRO.
134837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          llvm::StringRef name(pSectHdr.name());
134937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          if (name.endswith(".rel.ro")) {
135037b74a387bb3993387029859c2d9d051c41c724eStephen Hines            return SHO_RELRO;
135137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }
1352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
135322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) {
135422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return SHO_TLS_DATA;
135522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
13565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_DATA;
13575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
13585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::BSS:
136022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0)
136122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        return SHO_TLS_BSS;
13625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_BSS;
13635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
136422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    case LDFileFormat::NamePool: {
13655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getDynamic())
13665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RELRO;
13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_NAMEPOOL;
136822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Relocation:
13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getRelPlt() ||
13715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          &pSectHdr == &file_format->getRelaPlt())
13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_REL_PLT;
13735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_RELOCATION;
13745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // get the order from target for target specific sections
13765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Target:
137722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return getTargetSectionOrder(pSectHdr);
13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // handle .interp and .note.* sections
13805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Note:
13816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (file_format->hasInterp() && (&pSectHdr == &file_format->getInterp()))
13826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_INTERP;
13836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      else if (is_write)
13846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_RW_NOTE;
13856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      else
13866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        return SHO_RO_NOTE;
13875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrame:
1389f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      // set writable .eh_frame as relro
1390f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (is_write)
1391f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        return SHO_RELRO;
1392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrameHdr:
1393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::GCCExceptTable:
1394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_EXCEPTION;
13955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::MetaData:
13975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Debug:
139837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case LDFileFormat::DebugString:
13995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
14005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_UNDEFINED;
14015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize
140537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const {
14065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // undefined and dynamic symbols should have zero size.
14075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined)
14085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
14095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.resolveInfo()->size();
14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo
141337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const {
14145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set binding
14155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t bind = 0x0;
14165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isLocal())
14175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isGlobal())
14195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isWeak())
14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_WEAK;
14225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isAbsolute()) {
14235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // (Luba) Is a absolute but not global (weak or local) symbol meaningful?
14245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
14255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1427d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (config().codeGenType() != LinkerConfig::Object &&
1428d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
142937b74a387bb3993387029859c2d9d051c41c724eStephen Hines       pSymbol.visibility() == llvm::ELF::STV_HIDDEN))
14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
14315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t type = pSymbol.resolveInfo()->type();
1433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change
1434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // its type to Function
1435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn())
1436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    type = ResolveInfo::Function;
1437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (type | (bind << 4));
14385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout()
144137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const {
14425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn())
14435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
14445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.value();
14465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout()
144937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const {
14505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isAbsolute())
14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_ABS;
14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isCommon())
14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_COMMON;
14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn())
14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_UNDEF;
14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
145722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef())
145822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return llvm::ELF::SHN_ABS;
145922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
146037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(pSymbol.hasFragRef() &&
146137b74a387bb3993387029859c2d9d051c41c724eStephen Hines         "symbols must have fragment reference to get its index");
146222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pSymbol.fragRef()->frag()->getParent()->getSection().index();
14635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index
146637b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t GNULDBackend::getSymbolIdx(const LDSymbol* pSymbol) const {
146737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  HashTableType::iterator entry =
146837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pSymIndexMap->find(const_cast<LDSymbol*>(pSymbol));
146937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(entry != m_pSymIndexMap->end() &&
147037b74a387bb3993387029859c2d9d051c41c724eStephen Hines         "symbol not found in the symbol table");
147137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return entry.getEntry()->value();
14725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
14735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isTemporary - Whether pSymbol is a local label.
147537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isTemporary(const LDSymbol& pSymbol) const {
14766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (ResolveInfo::Local != pSymbol.binding())
14776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
14786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
14796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSymbol.nameSize() < 2)
14806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
14816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
14826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const char* name = pSymbol.name();
14836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if ('.' == name[0] && 'L' == name[1])
14846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
14856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
14866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // UnixWare 2.1 cc generate DWARF debugging symbols with `..' prefix.
14876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (name[0] == '.' && name[1] == '.')
14886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
14896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
14906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Work arround for gcc's bug
14916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // gcc sometimes generate symbols with '_.L_' prefix.
14926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSymbol.nameSize() < 4)
14936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
14946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
14956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
14966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return true;
14976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
14986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return false;
14996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
15006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding
150222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage.
150337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::allocateCommonSymbols(Module& pModule) {
150422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SymbolCategory& symbol_list = pModule.getSymbolTable();
1505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (symbol_list.emptyCommons() && symbol_list.emptyFiles() &&
15076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      symbol_list.emptyLocals() && symbol_list.emptyLocalDyns())
1508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
1511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: If the order of common symbols is defined, then sort common symbols
1513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // std::sort(com_sym, com_end, some kind of order);
1514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
151522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // get corresponding BSS LDSection
151622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat* file_format = getOutputFormat();
151722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& bss_sect = file_format->getBSS();
151822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection& tbss_sect = file_format->getTBSS();
1519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1520cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
152122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* bss_sect_data = NULL;
152222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (bss_sect.hasSectionData())
152322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = bss_sect.getSectionData();
152422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
152522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
152622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
152722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* tbss_sect_data = NULL;
152822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (tbss_sect.hasSectionData())
152922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = tbss_sect.getSectionData();
153022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
153122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
1532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
153437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint64_t bss_offset = bss_sect.size();
153522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t tbss_offset = tbss_sect.size();
1536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all local common symbols
1538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.localEnd();
1539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
1541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::Common == (*com_sym)->desc()) {
1542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // We have to reset the description of the symbol here. When doing
1543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // incremental linking, the output relocatable object may have common
1544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // symbols. Therefore, we can not treat common symbols as normal symbols
1545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // when emitting the regular name pools. We must change the symbols'
1546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // description here.
1547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1548cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
1549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
155237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        tbss_offset += ObjectBuilder::AppendFragment(
155337b74a387bb3993387029859c2d9d051c41c724eStephen Hines            *frag, *tbss_sect_data, (*com_sym)->value());
1554551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines        ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
155587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
155637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      } else {
155737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        bss_offset += ObjectBuilder::AppendFragment(
155837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            *frag, *bss_sect_data, (*com_sym)->value());
1559551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines        ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
156087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
15645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all global common symbols
1566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.commonEnd();
1567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
1568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // We have to reset the description of the symbol here. When doing
1569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // incremental linking, the output relocatable object may have common
1570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // symbols. Therefore, we can not treat common symbols as normal symbols
1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // when emitting the regular name pools. We must change the symbols'
1572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // description here.
1573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1574cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
1575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
157837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      tbss_offset += ObjectBuilder::AppendFragment(
157937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          *frag, *tbss_sect_data, (*com_sym)->value());
1580551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
158187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
158237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
158337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      bss_offset += ObjectBuilder::AppendFragment(
158437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          *frag, *bss_sect_data, (*com_sym)->value());
1585551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
158687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
1587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
159022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bss_sect.setSize(bss_offset);
159122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  tbss_sect.setSize(tbss_offset);
1592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  symbol_list.changeCommonsToGlobal();
1593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
15945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// updateSectionFlags - update pTo's flags when merging pFrom
15976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// update the output section flags based on input section flags.
159837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::updateSectionFlags(LDSection& pTo, const LDSection& pFrom) {
15996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // union the flags from input
16006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t flags = pTo.flag();
160137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  flags |= (pFrom.flag() & (llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC |
160237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                            llvm::ELF::SHF_EXECINSTR));
16036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // if there is an input section is not SHF_MERGE, clean this flag
16056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (0 == (pFrom.flag() & llvm::ELF::SHF_MERGE))
16066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    flags &= ~llvm::ELF::SHF_MERGE;
16076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // if there is an input section is not SHF_STRINGS, clean this flag
16096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (0 == (pFrom.flag() & llvm::ELF::SHF_STRINGS))
16106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    flags &= ~llvm::ELF::SHF_STRINGS;
16116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  pTo.setFlag(flags);
16136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
16146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
161687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rel entry
161787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel,
161887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type& pType,
161987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t& pSymIdx,
162037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  uint32_t& pOffset) const {
162187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t r_info = 0x0;
162287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
162387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
162437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = pRel.r_info;
162537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
162687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap32(pRel.r_offset);
162737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = mcld::bswap32(pRel.r_info);
162887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
162987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
163087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<unsigned char>(r_info);
163187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 8);
163287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
163387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
163487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
163587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rela entry
163687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel,
163787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type& pType,
163887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t& pSymIdx,
163987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t& pOffset,
164037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  int32_t& pAddend) const {
164137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint32_t r_info = 0x0;
164287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
164387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
164437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = pRel.r_info;
164587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = pRel.r_addend;
164637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
164787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap32(pRel.r_offset);
164837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = mcld::bswap32(pRel.r_info);
164987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = mcld::bswap32(pRel.r_addend);
165087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
165187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
165287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<unsigned char>(r_info);
165387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 8);
165487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
165587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
165687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
165787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF64_Rel entry
165887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel,
165937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  Relocation::Type& pType,
166037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  uint32_t& pSymIdx,
166137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  uint64_t& pOffset) const {
166287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t r_info = 0x0;
166387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
166487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
166537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = pRel.r_info;
166637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
166787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap64(pRel.r_offset);
166837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = mcld::bswap64(pRel.r_info);
166987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
167087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
167187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<uint32_t>(r_info);
167287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 32);
167387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
167487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
167587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
167687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRel - read ELF64_Rela entry
167787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel,
167837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  Relocation::Type& pType,
167937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  uint32_t& pSymIdx,
168037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  uint64_t& pOffset,
168137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  int64_t& pAddend) const {
168287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t r_info = 0x0;
168387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (llvm::sys::IsLittleEndianHost) {
168487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = pRel.r_offset;
168537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = pRel.r_info;
168687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = pRel.r_addend;
168737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
168887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pOffset = mcld::bswap64(pRel.r_offset);
168937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    r_info = mcld::bswap64(pRel.r_info);
169087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pAddend = mcld::bswap64(pRel.r_addend);
169187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
169287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
169387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pType = static_cast<uint32_t>(r_info);
169487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pSymIdx = (r_info >> 32);
169587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return true;
169687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
169787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
169887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rel entry
169987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel,
170087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
170187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
170237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  uint32_t pOffset) const {
170387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
170487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
170587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
170687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
170787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rela entry
170887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel,
170987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
171087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
171187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pOffset,
171237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  int32_t pAddend) const {
171387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
171487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_addend = pAddend;
171587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
171687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
171787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
171887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rel entry
171987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel,
172087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
172187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
172237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  uint64_t pOffset) const {
172387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
172487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
172587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
172687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
172787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rela entry
172887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel,
172987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  Relocation::Type pType,
173087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint32_t pSymIdx,
173187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                                  uint64_t pOffset,
173237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  int64_t pAddend) const {
173387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_offset = pOffset;
173487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.r_addend = pAddend;
173587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pRel.setSymbolAndType(pSymIdx, pType);
173687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
173787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
17385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers
173937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::createProgramHdrs(Module& pModule) {
174037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ELFFileFormat* file_format = getOutputFormat();
1741affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
17425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_INTERP
1743affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInterp()) {
174487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // make PT_PHDR
174587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    elfSegmentTable().produce(llvm::ELF::PT_PHDR);
174687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
174787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* interp_seg = elfSegmentTable().produce(llvm::ELF::PT_INTERP);
174887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    interp_seg->append(&file_format->getInterp());
1749affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
175187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t cur_flag, prev_flag = 0x0;
17525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegment* load_seg = NULL;
17535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make possible PT_LOAD segments
175487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& ldscript = pModule.getScript();
175537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  LinkerScript::AddressMap::iterator addrEnd = ldscript.addressMap().end();
175687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::iterator out, prev, outBegin, outEnd;
175787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outBegin = ldscript.sectionMap().begin();
175887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outEnd = ldscript.sectionMap().end();
175987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin, prev = outEnd; out != outEnd; prev = out, ++out) {
176087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    LDSection* sect = (*out)->getSection();
176187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
176287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (0 == (sect->flag() & llvm::ELF::SHF_ALLOC) &&
176387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        LDFileFormat::Null != sect->kind())
176487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
1765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
176687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // bypass empty sections
176787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (!(*out)->hasContent() &&
176887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() != LDFileFormat::Null)
17695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
17705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
177187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur_flag = getSegmentFlag(sect->flag());
177222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bool createPT_LOAD = false;
177387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (LDFileFormat::Null == sect->kind()) {
177422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 1. create text segment
177522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
177637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else if (!config().options().omagic() &&
177737b74a387bb3993387029859c2d9d051c41c724eStephen Hines               (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) {
177822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 2. create data segment if w/o omagic set
177922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
178037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else if (sect->kind() == LDFileFormat::BSS && load_seg->isDataSegment() &&
178137b74a387bb3993387029859c2d9d051c41c724eStephen Hines               addrEnd != ldscript.addressMap().find(".bss")) {
178222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // 3. create bss segment if w/ -Tbss and there is a data segment
178322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      createPT_LOAD = true;
178437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else if ((sect != &(file_format->getText())) &&
178537b74a387bb3993387029859c2d9d051c41c724eStephen Hines               (sect != &(file_format->getData())) &&
178637b74a387bb3993387029859c2d9d051c41c724eStephen Hines               (sect != &(file_format->getBSS())) &&
178737b74a387bb3993387029859c2d9d051c41c724eStephen Hines               (addrEnd != ldscript.addressMap().find(sect->name()))) {
178887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 4. create PT_LOAD for sections in address map except for text, data,
178987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // and bss
179087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      createPT_LOAD = true;
179137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else if (LDFileFormat::Null == (*prev)->getSection()->kind() &&
179237b74a387bb3993387029859c2d9d051c41c724eStephen Hines               !config().options().getScriptList().empty()) {
179387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // 5. create PT_LOAD to hold NULL section if there is a default ldscript
179487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      createPT_LOAD = true;
179522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
179722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (createPT_LOAD) {
179822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // create new PT_LOAD segment
179987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      load_seg = elfSegmentTable().produce(llvm::ELF::PT_LOAD, cur_flag);
18006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (!config().options().nmagic() && !config().options().omagic())
18016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        load_seg->setAlign(abiPageSize());
18025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
18035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
180437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    assert(load_seg != NULL);
180587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    load_seg->append(sect);
180622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (cur_flag != prev_flag)
180722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      load_seg->updateFlag(cur_flag);
18085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
180922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    prev_flag = cur_flag;
18105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
18115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_DYNAMIC
1813affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasDynamic()) {
181437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ELFSegment* dyn_seg = elfSegmentTable().produce(
181537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        llvm::ELF::PT_DYNAMIC, llvm::ELF::PF_R | llvm::ELF::PF_W);
181687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    dyn_seg->append(&file_format->getDynamic());
1817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1818affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
181922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasRelro()) {
1820affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // make PT_GNU_RELRO
182187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* relro_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_RELRO);
182222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
182337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                     segEnd = elfSegmentTable().end();
182437b74a387bb3993387029859c2d9d051c41c724eStephen Hines         seg != segEnd;
182537b74a387bb3993387029859c2d9d051c41c724eStephen Hines         ++seg) {
182687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (llvm::ELF::PT_LOAD != (*seg)->type())
182722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
182822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
182937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      for (ELFSegment::iterator sect = (*seg)->begin(), sectEnd = (*seg)->end();
183037b74a387bb3993387029859c2d9d051c41c724eStephen Hines           sect != sectEnd;
183137b74a387bb3993387029859c2d9d051c41c724eStephen Hines           ++sect) {
183222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        unsigned int order = getSectionOrder(**sect);
183337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (SHO_RELRO_LOCAL == order || SHO_RELRO == order ||
183422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            SHO_RELRO_LAST == order) {
183587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          relro_seg->append(*sect);
183622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
1837affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1838affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
18395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
18405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1841affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // make PT_GNU_EH_FRAME
1842affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasEhFrameHdr()) {
184387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* eh_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_EH_FRAME);
184487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    eh_seg->append(&file_format->getEhFrameHdr());
1845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
184622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
184722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_TLS
184822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasTData() || file_format->hasTBSS()) {
184987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment* tls_seg = elfSegmentTable().produce(llvm::ELF::PT_TLS);
185022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTData())
185187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      tls_seg->append(&file_format->getTData());
185222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (file_format->hasTBSS())
185387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      tls_seg->append(&file_format->getTBSS());
185422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
185522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
185622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // make PT_GNU_STACK
185722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (file_format->hasStackNote()) {
185837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    uint32_t flag = getSegmentFlag(file_format->getStackNote().flag());
185987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    elfSegmentTable().produce(llvm::ELF::PT_GNU_STACK,
186037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                              llvm::ELF::PF_R | llvm::ELF::PF_W | flag);
186122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
186222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // make PT_NOTE
186437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ELFSegment* note_seg = NULL;
186587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  prev_flag = 0x0;
186687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Module::iterator sect, sectBegin, sectEnd;
186787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sectBegin = pModule.begin();
186887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sectEnd = pModule.end();
186987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (sect = sectBegin; sect != sectEnd; ++sect) {
187087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*sect)->type() != llvm::ELF::SHT_NOTE ||
18716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        ((*sect)->flag() & llvm::ELF::SHF_ALLOC) == 0)
18726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      continue;
18736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
18746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    cur_flag = getSegmentFlag((*sect)->flag());
18756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // we have different section orders for read-only and writable notes, so
18766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create 2 segments if needed.
18776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (note_seg == NULL ||
18786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        (cur_flag & llvm::ELF::PF_W) != (prev_flag & llvm::ELF::PF_W))
187987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      note_seg = elfSegmentTable().produce(llvm::ELF::PT_NOTE, cur_flag);
18806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
188187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    note_seg->append(*sect);
18826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    prev_flag = cur_flag;
18836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
18846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
188522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // create target dependent segments
18866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  doCreateProgramHdrs(pModule);
1887affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1888affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1889affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments
189037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setupProgramHdrs(const LinkerScript& pScript) {
18915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update segment info
189287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(),
189337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                   segEnd = elfSegmentTable().end();
189437b74a387bb3993387029859c2d9d051c41c724eStephen Hines       seg != segEnd;
189537b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++seg) {
189687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // bypass if there is no section in this segment (e.g., PT_GNU_STACK)
189787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*seg)->size() == 0)
189887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
189987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
190087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // bypass the PT_LOAD that only has NULL section now
190187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*seg)->type() == llvm::ELF::PT_LOAD &&
190237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        (*seg)->front()->kind() == LDFileFormat::Null && (*seg)->size() == 1)
190337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      continue;
190487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
190587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*seg)->setOffset((*seg)->front()->offset());
190687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*seg)->type() == llvm::ELF::PT_LOAD &&
190787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->front()->kind() == LDFileFormat::Null) {
190887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      const LDSection* second = *((*seg)->begin() + 1);
190987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      assert(second != NULL);
191087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*seg)->setVaddr(second->addr() - second->offset());
191187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
191287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*seg)->setVaddr((*seg)->front()->addr());
191387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
191487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*seg)->setPaddr((*seg)->vaddr());
191587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
191687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegment::reverse_iterator sect, sectREnd = (*seg)->rend();
191787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (sect = (*seg)->rbegin(); sect != sectREnd; ++sect) {
191887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*sect)->kind() != LDFileFormat::BSS)
191987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        break;
192087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
192187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (sect != sectREnd) {
192237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      (*seg)->setFilesz((*sect)->offset() + (*sect)->size() - (*seg)->offset());
192387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
192487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*seg)->setFilesz(0x0);
192587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
192687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
192737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    (*seg)->setMemsz((*seg)->back()->addr() + (*seg)->back()->size() -
192887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                     (*seg)->vaddr());
192937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of for
193087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
193187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // handle the case if text segment only has NULL section
193287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* null_sect = &getOutputFormat()->getNULLSection();
193387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator null_seg =
193437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect);
193587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
193687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((*null_seg)->size() == 1) {
193787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // find 2nd PT_LOAD
193887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end();
193987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (seg = null_seg + 1; seg != segEnd; ++seg) {
194087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*seg)->type() == llvm::ELF::PT_LOAD)
194187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        break;
194287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
194387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (seg != segEnd) {
194487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t addr = (*seg)->front()->addr() - (*seg)->front()->offset();
194587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t size = sectionStartOffset();
194687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (addr + size == (*seg)->front()->addr()) {
194787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // if there is no space between the 2 segments, we can merge them.
194887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->setOffset(0x0);
194987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->setVaddr(addr);
195087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->setPaddr(addr);
195187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
195287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        ELFSegment::iterator sect, sectEnd = (*seg)->end();
195387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        for (sect = (*seg)->begin(); sect != sectEnd; ++sect) {
195487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if ((*sect)->kind() == LDFileFormat::BSS) {
195587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            --sect;
195687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            break;
195787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          }
195887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
195987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (sect == sectEnd) {
196037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          (*seg)->setFilesz((*seg)->back()->offset() + (*seg)->back()->size() -
196187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*seg)->offset());
196287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        } else if (*sect != (*seg)->front()) {
196387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          --sect;
196437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          (*seg)->setFilesz((*sect)->offset() + (*sect)->size() -
196587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                            (*seg)->offset());
196687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        } else {
196787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*seg)->setFilesz(0x0);
196887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
196987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
197037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        (*seg)->setMemsz((*seg)->back()->addr() + (*seg)->back()->size() -
197187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (*seg)->vaddr());
197287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
197387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*seg)->insert((*seg)->begin(), null_sect);
197487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        elfSegmentTable().erase(null_seg);
197587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
197687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else if (addr + size < (*seg)->vaddr()) {
197787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setOffset(0x0);
197887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setVaddr(addr);
197987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setPaddr(addr);
198087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setFilesz(size);
198187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*null_seg)->setMemsz(size);
198287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
198387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // erase the non valid segment contains NULL.
198487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        elfSegmentTable().erase(null_seg);
198587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
198687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
198787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
198887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
198987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // set up PT_PHDR
199087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator phdr =
199137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      elfSegmentTable().find(llvm::ELF::PT_PHDR, llvm::ELF::PF_R, 0x0);
199287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
199387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (phdr != elfSegmentTable().end()) {
199487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    ELFSegmentFactory::iterator null_seg =
199537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect);
199687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (null_seg != elfSegmentTable().end()) {
199787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      uint64_t offset = 0x0, phdr_size = 0x0;
1998d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (config().targets().is32Bits()) {
19995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf32_Ehdr);
20005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
200187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
20025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf64_Ehdr);
20035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf64_Phdr);
20045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
200587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setOffset(offset);
200687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setVaddr((*null_seg)->vaddr() + offset);
200787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setPaddr((*phdr)->vaddr());
200887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setFilesz(elfSegmentTable().size() * phdr_size);
200987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setMemsz(elfSegmentTable().size() * phdr_size);
201087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*phdr)->setAlign(config().targets().bitclass() / 8);
201187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
201287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      elfSegmentTable().erase(phdr);
20135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
20145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
20155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
20165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
201787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// getSegmentFlag - give a section flag and return the corresponding segment
201887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// flag
201937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint32_t GNULDBackend::getSegmentFlag(const uint32_t pSectionFlag) {
202087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t flag = 0x0;
202187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((pSectionFlag & llvm::ELF::SHF_ALLOC) != 0x0)
202287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    flag |= llvm::ELF::PF_R;
202387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((pSectionFlag & llvm::ELF::SHF_WRITE) != 0x0)
202487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    flag |= llvm::ELF::PF_W;
202587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if ((pSectionFlag & llvm::ELF::SHF_EXECINSTR) != 0x0)
202687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    flag |= llvm::ELF::PF_X;
202787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return flag;
202887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
202987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
203022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
203137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setupGNUStackInfo(Module& pModule) {
2032affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t flag = 0x0;
203322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasStackSet()) {
2034affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 1. check the command line option (-z execstack or -z noexecstack)
203522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (config().options().hasExecStack())
2036affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      flag = llvm::ELF::SHF_EXECINSTR;
203737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
2038affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2. check the stack info from the input objects
203922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // FIXME: since we alway emit .note.GNU-stack in output now, we may be able
204022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // to check this from the output .note.GNU-stack directly after section
204122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // merging is done
2042affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    size_t object_count = 0, stack_note_count = 0;
204322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::const_obj_iterator obj, objEnd = pModule.obj_end();
204422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (obj = pModule.obj_begin(); obj != objEnd; ++obj) {
204522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      ++object_count;
204622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack");
204737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (sect != NULL) {
204822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ++stack_note_count;
204922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // 2.1 found a stack note that is set as executable
205022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) {
205122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          flag = llvm::ELF::SHF_EXECINSTR;
205222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          break;
2053affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
2054affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
2055affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
20565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2057affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.2 there are no stack note sections in all input objects
2058affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (0 == stack_note_count)
2059affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
20605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2061affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.3 a special case. Use the target default to decide if the stack should
2062affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //     be executable
2063affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count)
20646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (m_pInfo->isDefaultExecStack())
2065affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        flag = llvm::ELF::SHF_EXECINSTR;
20665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
20675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
206822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (getOutputFormat()->hasStackNote()) {
206922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    getOutputFormat()->getStackNote().setFlag(flag);
207022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
207122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
207222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
207387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionOffset - helper function to set output sections' offset.
207437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setOutputSectionOffset(Module& pModule) {
207587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& script = pModule.getScript();
207687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t offset = 0x0;
207787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* cur = NULL;
207887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* prev = NULL;
207987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::iterator out, outBegin, outEnd;
208087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outBegin = script.sectionMap().begin();
208187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outEnd = script.sectionMap().end();
208287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out, prev = cur) {
208387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur = (*out)->getSection();
208487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (cur->kind() == LDFileFormat::Null) {
208587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      cur->setOffset(0x0);
208687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      continue;
208787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
208822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
208987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    switch (prev->kind()) {
209037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Null:
209137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        offset = sectionStartOffset();
209237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
209337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::BSS:
209437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        offset = prev->offset();
209537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
209637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default:
209737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        offset = prev->offset() + prev->size();
209837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
209922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
210087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    alignAddress(offset, cur->align());
210187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur->setOffset(offset);
210287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
210387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
210487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
210587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionAddress - helper function to set output sections' address.
210637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setOutputSectionAddress(Module& pModule) {
210787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  RpnEvaluator evaluator(pModule, *this);
210887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript& script = pModule.getScript();
210987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t vma = 0x0, offset = 0x0;
211087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* cur = NULL;
211187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSection* prev = NULL;
211287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LinkerScript::AddressMap::iterator addr, addrEnd = script.addressMap().end();
211387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end();
211487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::Output::dot_iterator dot;
211587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap::iterator out, outBegin, outEnd;
211687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outBegin = script.sectionMap().begin();
211787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  outEnd = script.sectionMap().end();
211887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; prev = cur, ++out) {
211987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur = (*out)->getSection();
212087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
212187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (cur->kind() == LDFileFormat::Null) {
212287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      cur->setOffset(0x0);
212322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
212487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
212522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
212687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // process dot assignments between 2 output sections
212787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (SectionMap::Output::dot_iterator it = (*out)->dot_begin(),
212837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          ie = (*out)->dot_end();
212937b74a387bb3993387029859c2d9d051c41c724eStephen Hines         it != ie;
213037b74a387bb3993387029859c2d9d051c41c724eStephen Hines         ++it) {
213187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*it).assign(evaluator);
213287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
213387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
213487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    seg = elfSegmentTable().find(llvm::ELF::PT_LOAD, cur);
213587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (seg != segEnd && cur == (*seg)->front()) {
213687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*seg)->isBssSegment())
213787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        addr = script.addressMap().find(".bss");
213887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      else if ((*seg)->isDataSegment())
213987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        addr = script.addressMap().find(".data");
214087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      else
214187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        addr = script.addressMap().find(cur->name());
214287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else
214387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      addr = addrEnd;
214422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
214587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (addr != addrEnd) {
21466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // use address mapping in script options
214787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      vma = addr.getEntry()->value();
214887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else if ((*out)->prolog().hasVMA()) {
214987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // use address from output section description
215087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      evaluator.eval((*out)->prolog().vma(), vma);
215187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else if ((dot = (*out)->find_last_explicit_dot()) != (*out)->dot_end()) {
215287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // assign address based on `.' symbol in ldscript
215387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      vma = (*dot).symbol().value();
215487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      alignAddress(vma, cur->align());
215587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
215687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*out)->prolog().type() == OutputSectDesc::NOLOAD) {
215787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        vma = prev->addr() + prev->size();
215887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0) {
215987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (prev->kind() == LDFileFormat::Null) {
216087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          // Let SECTIONS starts at 0 if we have a default ldscript but don't
216187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          // have any initial value (VMA or `.').
216287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (!config().options().getScriptList().empty())
216387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = 0x0;
216487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          else
216587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = getSegmentStartAddr(script) + sectionStartOffset();
216687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        } else {
216787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if ((prev->kind() == LDFileFormat::BSS))
216887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = prev->addr();
216987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          else
217087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            vma = prev->addr() + prev->size();
217187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
217287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        alignAddress(vma, cur->align());
217387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (config().options().getScriptList().empty()) {
217487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (seg != segEnd && cur == (*seg)->front()) {
217587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            // Try to align p_vaddr at page boundary if not in script options.
217687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            // To do so will add more padding in file, but can save one page
217787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            // at runtime.
2178b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines            // Avoid doing this optimization if -z relro is given, because there
2179b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines            // seems to be too many padding.
2180b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines            if (!config().options().hasRelro()) {
2181b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines              alignAddress(vma, (*seg)->align());
2182b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines            } else {
2183b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines              vma += abiPageSize();
2184b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines            }
218587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          }
218687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
218787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
218887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        vma = 0x0;
218922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
21906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
219122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
219287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (config().options().hasRelro()) {
219387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // if -z relro is given, we need to adjust sections' offset again, and
219487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // let PT_GNU_RELRO end on a abi page boundary
219587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
219687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      // check if current is the first non-relro section
219787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      SectionMap::iterator relro_last = out - 1;
219837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (relro_last != outEnd && (*relro_last)->order() <= SHO_RELRO_LAST &&
219987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*out)->order() > SHO_RELRO_LAST) {
220087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // align the first non-relro section to page boundary
220187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        alignAddress(vma, abiPageSize());
220287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
220387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // It seems that compiler think .got and .got.plt are continuous (w/o
220487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // any padding between). If .got is the last section in PT_RELRO and
220587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // it's not continuous to its next section (i.e. .got.plt), we need to
220687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // add padding in front of .got instead.
220787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // FIXME: Maybe we can handle this in a more general way.
220887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        LDSection& got = getOutputFormat()->getGOT();
220987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((getSectionOrder(got) == SHO_RELRO_LAST) &&
221087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            (got.addr() + got.size() < vma)) {
221187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          uint64_t diff = vma - got.addr() - got.size();
221287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          got.setAddr(vma - got.size());
221387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          got.setOffset(got.offset() + diff);
221487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
221587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
221637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }  // end of if - for relro processing
221787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
221887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur->setAddr(vma);
221987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
222087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    switch (prev->kind()) {
222137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Null:
222237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        offset = sectionStartOffset();
222337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
222437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::BSS:
222537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        offset = prev->offset();
222637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
222737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default:
222837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        offset = prev->offset() + prev->size();
222937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
223087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
223187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    alignAddress(offset, cur->align());
22326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf
22336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // p_align: As "Program Loading" describes in this chapter of the
22346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // processor supplement, loadable process segments must have congruent
22356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // values for p_vaddr and p_offset, modulo the page size.
223687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // FIXME: Now make all sh_addr and sh_offset are congruent, modulo the page
223787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // size. Otherwise, old objcopy (e.g., binutils 2.17) may fail with our
223887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // output!
223987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0 &&
224087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (vma & (abiPageSize() - 1)) != (offset & (abiPageSize() - 1))) {
224137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      uint64_t padding = abiPageSize() + (vma & (abiPageSize() - 1)) -
224287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         (offset & (abiPageSize() - 1));
224387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset += padding;
224422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
224522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
224687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    cur->setOffset(offset);
224722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
224887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // process dot assignments in the output section
224987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool changed = false;
225087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    Fragment* invalid = NULL;
225187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (SectionMap::Output::iterator in = (*out)->begin(),
225237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      inEnd = (*out)->end();
225337b74a387bb3993387029859c2d9d051c41c724eStephen Hines         in != inEnd;
225437b74a387bb3993387029859c2d9d051c41c724eStephen Hines         ++in) {
225587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (invalid != NULL && !(*in)->dotAssignments().empty()) {
225687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        while (invalid != (*in)->dotAssignments().front().first) {
225787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          Fragment* prev = invalid->getPrevNode();
225887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          invalid->setOffset(prev->getOffset() + prev->size());
225987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          invalid = invalid->getNextNode();
226087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
226187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        invalid = NULL;
226287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
226322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
226487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (SectionMap::Input::dot_iterator it = (*in)->dot_begin(),
226537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                           ie = (*in)->dot_end();
226637b74a387bb3993387029859c2d9d051c41c724eStephen Hines           it != ie;
226737b74a387bb3993387029859c2d9d051c41c724eStephen Hines           ++it) {
226887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*it).second.assign(evaluator);
226987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((*it).first != NULL) {
227087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          uint64_t new_offset = (*it).second.symbol().value() - vma;
227187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (new_offset != (*it).first->getOffset()) {
227287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            (*it).first->setOffset(new_offset);
227387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            invalid = (*it).first->getNextNode();
227487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            changed = true;
227587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          }
227687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
227737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      }  // for each dot assignment
227837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }    // for each input description
227987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
228087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (changed) {
228187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      while (invalid != NULL) {
228287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        Fragment* prev = invalid->getPrevNode();
228387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        invalid->setOffset(prev->getOffset() + prev->size());
228487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        invalid = invalid->getNextNode();
228587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
228687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
228787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      cur->setSize(cur->getSectionData()->back().getOffset() +
228887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                   cur->getSectionData()->back().size());
228922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
229037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // for each output section description
22915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
22925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
229387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// placeOutputSections - place output sections based on SectionMap
229437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::placeOutputSections(Module& pModule) {
229587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef std::vector<LDSection*> Orphans;
229687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Orphans orphans;
229787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap& sectionMap = pModule.getScript().sectionMap();
229887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2299d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie;
230037b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++it) {
230187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool wanted = false;
230287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2303d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    switch ((*it)->kind()) {
230437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // take NULL and StackNote directly
230537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Null:
230637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::StackNote:
230787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        wanted = true;
230837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
230937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // ignore if section size is 0
231037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::EhFrame:
231137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (((*it)->size() != 0) ||
231237b74a387bb3993387029859c2d9d051c41c724eStephen Hines            ((*it)->hasEhFrame() &&
231337b74a387bb3993387029859c2d9d051c41c724eStephen Hines             config().codeGenType() == LinkerConfig::Object))
231437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          wanted = true;
231537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
231637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Relocation:
231737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (((*it)->size() != 0) ||
231837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            ((*it)->hasRelocData() &&
231937b74a387bb3993387029859c2d9d051c41c724eStephen Hines             config().codeGenType() == LinkerConfig::Object))
232037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          wanted = true;
232137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
232237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::TEXT:
232337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::DATA:
232437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Target:
232537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::MetaData:
232637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::BSS:
232737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Debug:
232837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::DebugString:
232937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::GCCExceptTable:
233037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Note:
233137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::NamePool:
233237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::EhFrameHdr:
233337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (((*it)->size() != 0) ||
233437b74a387bb3993387029859c2d9d051c41c724eStephen Hines            ((*it)->hasSectionData() &&
233537b74a387bb3993387029859c2d9d051c41c724eStephen Hines             config().codeGenType() == LinkerConfig::Object))
233637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          wanted = true;
233737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
233837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Group:
233937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (LinkerConfig::Object == config().codeGenType()) {
234037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          // TODO: support incremental linking
234137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }
234237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
234337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Version:
234437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if ((*it)->size() != 0) {
234537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          wanted = true;
234637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name();
234737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }
234837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
234937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default:
235037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if ((*it)->size() != 0) {
235137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          error(diag::err_unsupported_section) << (*it)->name()
235237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                               << (*it)->kind();
235337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }
235437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
235537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }  // end of switch
235687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
235787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (wanted) {
235887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      SectionMap::iterator out, outBegin, outEnd;
235987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      outBegin = sectionMap.begin();
236087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      outEnd = sectionMap.end();
236187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (out = outBegin; out != outEnd; ++out) {
236287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        bool matched = false;
236387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((*it)->name().compare((*out)->name()) == 0) {
236487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          switch ((*out)->prolog().constraint()) {
236537b74a387bb3993387029859c2d9d051c41c724eStephen Hines            case OutputSectDesc::NO_CONSTRAINT:
236637b74a387bb3993387029859c2d9d051c41c724eStephen Hines              matched = true;
236737b74a387bb3993387029859c2d9d051c41c724eStephen Hines              break;
236837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            case OutputSectDesc::ONLY_IF_RO:
236937b74a387bb3993387029859c2d9d051c41c724eStephen Hines              matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) == 0;
237037b74a387bb3993387029859c2d9d051c41c724eStephen Hines              break;
237137b74a387bb3993387029859c2d9d051c41c724eStephen Hines            case OutputSectDesc::ONLY_IF_RW:
237237b74a387bb3993387029859c2d9d051c41c724eStephen Hines              matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) != 0;
237337b74a387bb3993387029859c2d9d051c41c724eStephen Hines              break;
237437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }  // end of switch
237587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
237687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if (matched)
237787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            break;
237887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
237937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      }  // for each output section description
238087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
238187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (out != outEnd) {
238287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // set up the section
238387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->setSection(*it);
238487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->setOrder(getSectionOrder(**it));
238587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      } else {
238687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        orphans.push_back(*it);
238787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
2388d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
238937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // for each section in Module
239087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
239187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // set up sections in SectionMap but do not exist at all.
239287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t flag = 0x0;
239387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  unsigned int order = SHO_UNDEFINED;
239487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  OutputSectDesc::Type type = OutputSectDesc::LOAD;
239587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (SectionMap::reverse_iterator out = sectionMap.rbegin(),
239637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                    outEnd = sectionMap.rend();
239737b74a387bb3993387029859c2d9d051c41c724eStephen Hines       out != outEnd;
239837b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++out) {
239987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->hasContent() ||
240087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::Null ||
240187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::StackNote) {
240287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      flag = (*out)->getSection()->flag();
240387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      order = (*out)->order();
240487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      type = (*out)->prolog().type();
240587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
240687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->getSection()->setFlag(flag);
240787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->setOrder(order);
240887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->prolog().setType(type);
240987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
241037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // for each output section description
241187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
241287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // place orphan sections
241387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (Orphans::iterator it = orphans.begin(), ie = orphans.end(); it != ie;
241437b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++it) {
241587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    size_t order = getSectionOrder(**it);
241687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SectionMap::iterator out, outBegin, outEnd;
241787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    outBegin = sectionMap.begin();
241887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    outEnd = sectionMap.end();
241987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
242087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*it)->kind() == LDFileFormat::Null)
242187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      out = sectionMap.insert(outBegin, *it);
242287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    else {
242387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (out = outBegin; out != outEnd; ++out) {
242487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((*out)->order() > order)
242587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          break;
242687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
242787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      out = sectionMap.insert(out, *it);
242887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
242987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    (*out)->setOrder(order);
243037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // for each orphan section
243187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
243287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // sort output section orders if there is no default ldscript
243387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (config().options().getScriptList().empty()) {
243437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    std::stable_sort(
243537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        sectionMap.begin(), sectionMap.end(), SectionMap::SHOCompare());
243687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
2437d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
243887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // when section ordering is fixed, now we can make sure dot assignments are
243987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // all set appropriately
244087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sectionMap.fixupDotSymbols();
244187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
244287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
244387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// layout - layout method
244437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::layout(Module& pModule) {
244587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 1. place output sections based on SectionMap from SECTIONS command
244687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  placeOutputSections(pModule);
2447d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
244887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 2. update output sections in Module
244987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionMap& sectionMap = pModule.getScript().sectionMap();
2450d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pModule.getSectionTable().clear();
245187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (SectionMap::iterator out = sectionMap.begin(), outEnd = sectionMap.end();
245237b74a387bb3993387029859c2d9d051c41c724eStephen Hines       out != outEnd;
245337b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++out) {
245487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->hasContent() ||
245587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::Null ||
245687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->getSection()->kind() == LDFileFormat::StackNote ||
245787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        config().codeGenType() == LinkerConfig::Object) {
245887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->getSection()->setIndex(pModule.size());
245987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      pModule.getSectionTable().push_back((*out)->getSection());
246087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
246137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // for each output section description
246287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
246387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 3. update the size of .shstrtab
246487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sizeShstrtab(pModule);
2465d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2466d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 4. create program headers
2467d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
24686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    createProgramHdrs(pModule);
2469d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
2470d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
247187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 5. set output section address/offset
247287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (LinkerConfig::Object != config().codeGenType())
247387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    setOutputSectionAddress(pModule);
247487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else
247587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    setOutputSectionOffset(pModule);
2476d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
2477d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
247837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::createAndSizeEhFrameHdr(Module& pModule) {
24796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType() &&
24806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // init EhFrameHdr and size the output section
248222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ELFFileFormat* format = getOutputFormat();
248337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_pEhFrameHdr =
248437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        new EhFrameHdr(format->getEhFrameHdr(), format->getEhFrame());
2485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr->sizeOutput();
2486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
248787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
248887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24890dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
24900dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// function pointer access
249137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::mayHaveUnsafeFunctionPointerAccess(
249237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const LDSection& pSection) const {
24930dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  llvm::StringRef name(pSection.name());
24940dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  return !name.startswith(".rodata._ZTV") &&
24950dea6bc96bb52346737966839ac68644f7939f58Stephen Hines         !name.startswith(".data.rel.ro._ZTV") &&
24960dea6bc96bb52346737966839ac68644f7939f58Stephen Hines         !name.startswith(".rodata._ZTC") &&
249737b74a387bb3993387029859c2d9d051c41c724eStephen Hines         !name.startswith(".data.rel.ro._ZTC") && !name.startswith(".eh_frame");
24980dea6bc96bb52346737966839ac68644f7939f58Stephen Hines}
24990dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
250087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// preLayout - Backend can do any needed modification before layout
250137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::preLayout(Module& pModule, IRBuilder& pBuilder) {
250287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // prelayout target first
250387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  doPreLayout(pBuilder);
250422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // change .tbss and .tdata section symbol from Local to LocalDyn category
250637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pTDATA != NULL)
2507f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pModule.getSymbolTable().changeToDynamic(*f_pTDATA);
250822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
250937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (f_pTBSS != NULL)
2510f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pModule.getSymbolTable().changeToDynamic(*f_pTBSS);
251122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
251222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // To merge input's relocation sections into output's relocation sections.
251322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //
251422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are generating relocatables (-r), move input relocation sections
251522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // to corresponding output relocation sections.
251622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object == config().codeGenType()) {
251722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Module::obj_iterator input, inEnd = pModule.obj_end();
251822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    for (input = pModule.obj_begin(); input != inEnd; ++input) {
251922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
252022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
252122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the output relocation LDSection with identical name.
252222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_sect = pModule.getSection((*rs)->name());
252337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (output_sect == NULL) {
252437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          output_sect = LDSection::Create(
252537b74a387bb3993387029859c2d9d051c41c724eStephen Hines              (*rs)->name(), (*rs)->kind(), (*rs)->type(), (*rs)->flag());
252622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
252722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setAlign((*rs)->align());
252822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          pModule.getSectionTable().push_back(output_sect);
252922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
253022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
253122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // set output relocation section link
253222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        const LDSection* input_link = (*rs)->getLink();
253337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assert(input_link != NULL && "Illegal input relocation section.");
253422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
253522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get the linked output section
253622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* output_link = pModule.getSection(input_link->name());
253737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assert(output_link != NULL);
253822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
253922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        output_sect->setLink(output_link);
254022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
254122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // get output relcoationData, create one if not exist
254222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!output_sect->hasRelocData())
254322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          IRBuilder::CreateRelocData(*output_sect);
254422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
254522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        RelocData* out_reloc_data = output_sect->getRelocData();
254622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
254722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // move relocations from input's to output's RelcoationData
2548d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& out_list =
254937b74a387bb3993387029859c2d9d051c41c724eStephen Hines            out_reloc_data->getRelocationList();
2550d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        RelocData::RelocationListType& in_list =
255137b74a387bb3993387029859c2d9d051c41c724eStephen Hines            (*rs)->getRelocData()->getRelocationList();
255222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        out_list.splice(out_list.end(), in_list);
255322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
255422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // size output
255522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (llvm::ELF::SHT_REL == output_sect->type())
255622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelEntrySize());
255722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else if (llvm::ELF::SHT_RELA == output_sect->type())
255822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          output_sect->setSize(out_reloc_data->size() * getRelaEntrySize());
255922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else {
256022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          fatal(diag::unknown_reloc_section_type) << output_sect->type()
256122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  << output_sect->name();
256222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
256337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      }  // end of for each relocation section
256437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }    // end of for each input
256537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }      // end of if
256622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
256722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // set up the section flag of .note.GNU-stack section
25686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  setupGNUStackInfo(pModule);
25695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
25705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2571cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout
257237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::postLayout(Module& pModule, IRBuilder& pBuilder) {
257322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::Object != config().codeGenType()) {
257487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // do relaxation
25756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relax(pModule, pBuilder);
257687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // set up the attributes of program headers
2577f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    setupProgramHdrs(pModule.getScript());
2578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
25806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  doPostLayout(pModule, pBuilder);
25815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
25825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
258337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::postProcessing(FileOutputBuffer& pOutput) {
25846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != config().codeGenType() &&
25856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) {
2586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // emit eh_frame_hdr
2587f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_pEhFrameHdr->emitOutput<32>(pOutput);
2588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
25915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count.
25925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols,
259337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          bool pIsGNUStyle) {
259437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static const unsigned int buckets[] = {
259537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, 16411,
259637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      32771, 65537, 131101, 262147
25975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
25985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const unsigned buckets_count = sizeof buckets / sizeof buckets[0];
25995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int result = 1;
26015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (unsigned i = 0; i < buckets_count; ++i) {
26025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pNumOfSymbols < buckets[i])
26035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
26045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = buckets[i];
26055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
26065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pIsGNUStyle && result < 2)
26085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = 2;
26095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
26115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
26125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
261437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned GNULDBackend::getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const {
26156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint32_t maskbitslog2 = 1;
261637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  for (uint32_t x = pNumOfSymbols >> 1; x != 0; x >>= 1)
26176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ++maskbitslog2;
26186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
26196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (maskbitslog2 < 3)
26206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 = 5;
26216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (((1U << (maskbitslog2 - 2)) & pNumOfSymbols) != 0)
26226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 += 3;
26236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
26246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 += 2;
26256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
26266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().targets().bitclass() == 64 && maskbitslog2 == 5)
26276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    maskbitslog2 = 6;
26286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
26296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return maskbitslog2;
26306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
26316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
26325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol
263337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol) const {
26345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
26355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // symbol. We should not add it
26365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.binding() == ResolveInfo::Local)
26375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
26385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If we are building shared object, and the visibility is external, we
26405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // need to add it.
264122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
264237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      LinkerConfig::Exec == config().codeGenType() ||
2643d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
26445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default ||
26456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected)
26465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return true;
264722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
264822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
264922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
265022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
265122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol
265237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo) const {
265322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
265422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // symbol. We should not add it
265522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pResolveInfo.binding() == ResolveInfo::Local)
265622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
265722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
265822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // If we are building shared object, and the visibility is external, we
265922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // need to add it.
266022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj == config().codeGenType() ||
266137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      LinkerConfig::Exec == config().codeGenType() ||
2662d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LinkerConfig::Binary == config().codeGenType()) {
266322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (pResolveInfo.visibility() == ResolveInfo::Default ||
26646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        pResolveInfo.visibility() == ResolveInfo::Protected)
266522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return true;
266622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
2667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
2668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2669affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
267087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table
267137b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFSegmentFactory& GNULDBackend::elfSegmentTable() {
267287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!");
267387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return *m_pELFSegmentTable;
267487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
267587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
267687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table
267737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ELFSegmentFactory& GNULDBackend::elfSegmentTable() const {
267887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!");
267987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return *m_pELFSegmentTable;
268087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
268187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine.
268337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::commonPageSize() const {
268422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().commPageSize() > 0)
268522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return std::min(config().options().commPageSize(), abiPageSize());
2686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
26876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return std::min(m_pInfo->commonPageSize(), abiPageSize());
2688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine.
269137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::abiPageSize() const {
269222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().maxPageSize() > 0)
269322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return config().options().maxPageSize();
2694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
26956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return m_pInfo->abiPageSize();
2696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other
2699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit
270037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const {
2701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.other() != ResolveInfo::Default)
2702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
270422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This is because the codeGenType of pie is DynObj. And gold linker check
270522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // the "shared" option instead.
270622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
270722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
270822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
270922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (LinkerConfig::DynObj != config().codeGenType())
271022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
271122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
271222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().Bsymbolic())
2713affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2714affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
271522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // A local defined symbol should be non-preemptible.
271622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32
271722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relocation refers to a local defined symbol, and we should generate a
271822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // relative dynamic relocation when applying the relocation.
271922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local)
2720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2721affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2722affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
2723affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2724affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
272522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
27266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsDynRel(const ResolveInfo& pSym,
272722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                     bool pSymHasPLT,
272837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                     bool isAbsReloc) const {
272922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // an undefined reference in the executables should be statically
273022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // resolved to 0 and no need a dynamic relocation
273137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pSym.isUndef() && !pSym.isDyn() &&
273237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      (LinkerConfig::Exec == config().codeGenType() ||
2733d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary == config().codeGenType()))
273422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
273522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // An absolute symbol can be resolved directly if it is either local
27376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // or we are linking statically. Otherwise it can still be overridden
27386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // at runtime.
27396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSym.isAbsolute() &&
27406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (pSym.binding() == ResolveInfo::Local || config().isCodeStatic()))
274122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
27426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() && isAbsReloc)
274322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
274422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSymHasPLT && ResolveInfo::Function == pSym.type())
274522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
27466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!config().isCodeIndep() && pSymHasPLT)
274722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
274837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pSym.isDyn() || pSym.isUndef() || isSymbolPreemptible(pSym))
274922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
275022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
275122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
275222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
275322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2754affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry
275537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::symbolNeedsPLT(const ResolveInfo& pSym) const {
275637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pSym.isUndef() && !pSym.isDyn() &&
275722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      LinkerConfig::DynObj != config().codeGenType())
2758affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2759affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2760affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry
2761affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() == ResolveInfo::IndirectFunc)
2762affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2763affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2764affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() != ResolveInfo::Function)
2765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2766affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
27676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeStatic())
276822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
276922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
277022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().isPIE())
2771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2772affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
277337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return (pSym.isDyn() || pSym.isUndef() || isSymbolPreemptible(pSym));
2774affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2775affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
277622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at
277722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time
277837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::symbolFinalValueIsKnown(const ResolveInfo& pSym) const {
277922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the output is pic code or if not executables, symbols' value may change
278022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // at runtime
27816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: CodeIndep() || LinkerConfig::Relocatable == CodeGenType
27826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (config().isCodeIndep() ||
2783d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::Exec != config().codeGenType() &&
2784d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao       LinkerConfig::Binary != config().codeGenType()))
2785affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
278622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
278722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is from dynamic object, then its value is unknown
278822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pSym.isDyn())
2789affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
279022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
279122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is not in dynamic object and is not undefined, then its value
279222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // is known
279322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pSym.isUndef())
2794affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
2795affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
279622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the symbol is undefined and not in dynamic objects, for example, a weak
279722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // undefined symbol, then whether the symbol's final value can be known
279822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // depends on whrther we're doing static link
27996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return config().isCodeStatic();
2800affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
2801affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2802affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
28036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsCopyReloc(const Relocation& pReloc,
280437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        const ResolveInfo& pSym) const {
2805affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // only the reference from dynamic executable to non-function symbol in
2806affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // the dynamic objects may need copy relocation
280737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (config().isCodeIndep() || !pSym.isDyn() ||
280837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pSym.type() == ResolveInfo::Function || pSym.size() == 0)
2809affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2810affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2811affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // check if the option -z nocopyreloc is given
281222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (config().options().hasNoCopyReloc())
2813affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
2814affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // TODO: Is this check necessary?
2816affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if relocation target place is readonly, a copy relocation is needed
281722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag();
281822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE))
2819affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
28205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
28215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
28225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2823affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
282437b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol& GNULDBackend::getTDATASymbol() {
282537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(f_pTDATA != NULL);
282622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
282722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
282822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
282937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst LDSymbol& GNULDBackend::getTDATASymbol() const {
283037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(f_pTDATA != NULL);
283122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTDATA;
283222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
283322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
283437b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol& GNULDBackend::getTBSSSymbol() {
283537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(f_pTBSS != NULL);
283622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
283722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
283822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
283937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst LDSymbol& GNULDBackend::getTBSSSymbol() const {
284037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(f_pTBSS != NULL);
284122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return *f_pTBSS;
284222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
284322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
284437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef GNULDBackend::getEntry(const Module& pModule) const {
284587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pModule.getScript().hasEntry())
284687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return pModule.getScript().entry();
284787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  else
284887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return getInfo().entry();
284987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
285087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
285137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection) {
285222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_bHasTextRel)
285322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
285422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
285522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // if the target section of the dynamic relocation is ALLOCATE but is not
285622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // writable, than we should set DF_TEXTREL
285722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const uint32_t flag = pSection.flag();
285822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC))
285922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_bHasTextRel = true;
286022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
286122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return;
286222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
286322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
286487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sortRelocation - sort the dynamic relocations to let dynamic linker
286587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// process relocations more efficiently
286637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sortRelocation(LDSection& pSection) {
286787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!config().options().hasCombReloc())
286887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return;
286987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
287087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  assert(pSection.kind() == LDFileFormat::Relocation);
287187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
287287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  switch (config().codeGenType()) {
287337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case LinkerConfig::DynObj:
287437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case LinkerConfig::Exec:
287537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (&pSection == &getOutputFormat()->getRelDyn() ||
287637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          &pSection == &getOutputFormat()->getRelaDyn()) {
287737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (pSection.hasRelocData())
287837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          pSection.getRelocData()->sort(RelocCompare(*this));
287937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      }
288037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
288137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return;
288287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
288387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
288487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2885b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesunsigned GNULDBackend::stubGroupSize() const {
2886b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  const unsigned group_size = config().targets().getStubGroupSize();
2887b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  if (group_size == 0) {
2888b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    return m_pInfo->stubGroupSize();
2889b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  } else {
2890b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    return group_size;
2891b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  }
2892b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines}
2893b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
289422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation
289537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initBRIslandFactory() {
289637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_pBRIslandFactory == NULL) {
2897b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    m_pBRIslandFactory = new BranchIslandFactory(maxFwdBranchOffset(),
2898b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                                 maxBwdBranchOffset(),
2899b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                                 stubGroupSize());
290022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
290122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
290222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
290322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
290422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation
290537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initStubFactory() {
290637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_pStubFactory == NULL) {
290722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pStubFactory = new StubFactory();
290822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
290922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
291022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
291122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
291237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) {
291322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!mayRelax())
291422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
291522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
291687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  getBRIslandFactory()->group(pModule);
291787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
291822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool finished = true;
291922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  do {
29206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (doRelax(pModule, pBuilder, finished)) {
292187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      setOutputSectionAddress(pModule);
292222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
292322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } while (!finished);
292422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
292522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
292622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
292722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
292837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::DynsymCompare::needGNUHash(const LDSymbol& X) const {
29296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: in bfd and gold linker, an undefined symbol might be hashed
29306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // when the ouput is not PIC, if the symbol is referred by a non pc-relative
29316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // reloc, and its value is set to the addr of the plt entry.
29326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return !X.resolveInfo()->isUndef() && !X.isDyn();
29336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
29346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
29356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::operator()(const LDSymbol* X,
293637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                             const LDSymbol* Y) const {
29376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return !needGNUHash(*X) && needGNUHash(*Y);
29386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
29396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2940a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesbool GNULDBackend::RelocCompare::operator()(const Relocation& X,
2941a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines                                            const Relocation& Y) const {
294287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 1. compare if relocation is relative
2943a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (X.symInfo() == NULL) {
2944a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines    if (Y.symInfo() != NULL)
294587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return true;
2946a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  } else if (Y.symInfo() == NULL) {
294787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
294887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } else {
294987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // 2. compare the symbol index
2950a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines    size_t symIdxX = m_Backend.getSymbolIdx(X.symInfo()->outSymbol());
2951a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines    size_t symIdxY = m_Backend.getSymbolIdx(Y.symInfo()->outSymbol());
295287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (symIdxX < symIdxY)
295387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return true;
295487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (symIdxX > symIdxY)
295587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return false;
295687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
295787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
295887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 3. compare the relocation address
2959a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (X.place() < Y.place())
296087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return true;
2961a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (X.place() > Y.place())
296287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
296387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
296487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 4. compare the relocation type
2965a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (X.type() < Y.type())
296687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return true;
2967a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (X.type() > Y.type())
296887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
296987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
297087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // 5. compare the addend
2971a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (X.addend() < Y.addend())
297287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return true;
2973a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  if (X.addend() > Y.addend())
297487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
297587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
297687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return false;
297787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
297837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
297937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
2980