15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- GNULDBackend.cpp ---------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Target/GNULDBackend.h>
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <string>
13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring>
14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cassert>
15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h>
19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/LDSymbol.h>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/Layout.h>
21cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDOutput.h>
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/InputTree.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/SymbolCategory.h>
26cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/MC/MCLinker.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryArea.h>
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
30cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/MemoryAreaFactory.h>
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend
36cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::GNULDBackend()
38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  : m_pArchiveReader(NULL),
39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pObjectReader(NULL),
40affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pDynObjReader(NULL),
41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pObjectWriter(NULL),
42affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pDynObjWriter(NULL),
43affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pExecWriter(NULL),
44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pDynObjFileFormat(NULL),
45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pExecFileFormat(NULL),
46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_ELFSegmentTable(9), // magic number
47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr(NULL),
48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayStart(NULL),
49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pPreInitArrayEnd(NULL),
50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayStart(NULL),
51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pInitArrayEnd(NULL),
52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayStart(NULL),
53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pFiniArrayEnd(NULL),
54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pStack(NULL),
55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pExecutableStart(NULL),
56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEText(NULL),
57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EText(NULL),
58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p__EText(NULL),
59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEData(NULL),
60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_EData(NULL),
61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pBSSStart(NULL),
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_pEnd(NULL),
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    f_p_End(NULL) {
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pSymIndexMap = new HashTableType(1024);
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::~GNULDBackend()
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pArchiveReader)
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pArchiveReader;
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pObjectReader)
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pObjectReader;
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pDynObjReader)
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynObjReader;
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pObjectWriter)
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pObjectWriter;
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pDynObjWriter)
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynObjWriter;
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pExecWriter)
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    delete m_pExecWriter;
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pDynObjFileFormat)
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pDynObjFileFormat;
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pExecFileFormat)
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pExecFileFormat;
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pSymIndexMap)
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pSymIndexMap;
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pEhFrameHdr)
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    delete m_pEhFrameHdr;
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::sectionStartOffset() const
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: use fixed offset, we need 10 segments by default
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return sizeof(llvm::ELF::Elf64_Ehdr)+10*sizeof(llvm::ELF::Elf64_Phdr);
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
97affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t GNULDBackend::segmentStartAddr(const Output& pOutput,
98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const MCLDInfo& pInfo) const
99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // TODO: handle the user option: -TText=
101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (isOutputPIC(pOutput, pInfo))
102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return 0x0;
103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return defaultTextSegmentAddr();
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNULDBackend::initArchiveReader(MCLinker& pLinker,
108cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                     MCLDInfo& pInfo,
109cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                     MemoryAreaFactory& pMemAreaFactory)
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
111cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (NULL == m_pArchiveReader) {
112cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    assert(NULL != m_pObjectReader);
113cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    m_pArchiveReader = new GNUArchiveReader(pInfo,
114cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                            pMemAreaFactory,
115cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                            *m_pObjectReader);
116cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool GNULDBackend::initObjectReader(MCLinker& pLinker)
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == m_pObjectReader)
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pObjectReader = new ELFObjectReader(*this, pLinker);
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool GNULDBackend::initDynObjReader(MCLinker& pLinker)
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == m_pDynObjReader)
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynObjReader = new ELFDynObjReader(*this, pLinker);
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool GNULDBackend::initObjectWriter(MCLinker&)
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool GNULDBackend::initDynObjWriter(MCLinker& pLinker)
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == m_pDynObjWriter)
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynObjWriter = new ELFDynObjWriter(*this, pLinker);
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
147affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::initExecWriter(MCLinker& pLinker)
148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == m_pExecWriter)
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pExecWriter = new ELFExecWriter(*this, pLinker);
151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool GNULDBackend::initExecSections(MCLinker& pMCLinker)
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
15667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == m_pExecFileFormat)
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pExecFileFormat = new ELFExecFileFormat(*this);
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize standard sections
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pExecFileFormat->initStdSections(pMCLinker);
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool GNULDBackend::initDynObjSections(MCLinker& pMCLinker)
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
16667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == m_pDynObjFileFormat)
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pDynObjFileFormat = new ELFDynObjFileFormat(*this);
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize standard sections
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pDynObjFileFormat->initStdSections(pMCLinker);
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
174affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::initStandardSymbols(MCLinker& pLinker, const Output& pOutput)
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = getOutputFormat(pOutput);
177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .preinit_array
180cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* preinit_array = NULL;
181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasPreInitArray()) {
182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    preinit_array = pLinker.getLayout().getFragmentRef(
183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                   *(file_format->getPreInitArray().getSectionData()->begin()),
184affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                   0x0);
185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayStart =
187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__preinit_array_start",
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             preinit_array, // FragRef
196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pPreInitArrayEnd =
198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__preinit_array_end",
200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .init_array
210cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* init_array = NULL;
211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInitArray()) {
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    init_array = pLinker.getLayout().getFragmentRef(
213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      *(file_format->getInitArray().getSectionData()->begin()),
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      0x0);
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayStart =
218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__init_array_start",
220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pInitArrayEnd =
229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__init_array_end",
231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
235affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             init_array, // FragRef
238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .fini_array
241cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* fini_array = NULL;
242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasFiniArray()) {
243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fini_array = pLinker.getLayout().getFragmentRef(
244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     *(file_format->getFiniArray().getSectionData()->begin()),
245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     0x0);
246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayStart =
249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__fini_array_start",
251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
259affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pFiniArrayEnd =
260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__fini_array_end",
262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             fini_array, // FragRef
269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // .stack
272cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  FragmentRef* stack = NULL;
273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasStack()) {
274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    stack = pLinker.getLayout().getFragmentRef(
275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          *(file_format->getStack().getSectionData()->begin()),
276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          0x0);
277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pStack =
279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__stack",
281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Global,
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             stack, // FragRef
288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Hidden);
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pExecutableStart =
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__executable_start",
294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEText =
303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("etext",
305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_EText =
314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("_etext",
316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p__EText =
325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__etext",
327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
334affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEData =
336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
337affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("edata",
338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pEnd =
348affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::AsRefered,
349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("end",
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _edata is defined forcefully.
360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 186
361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_EData =
362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::Force,
363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("_edata",
364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
365affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // __bss_start is defined forcefully.
374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 214
375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_pBSSStart =
376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::Force,
377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("__bss_start",
378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
382affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
384affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
385affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
387affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // _end is defined forcefully.
388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // @ref Google gold linker: defstd.cc: 228
389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  f_p_End =
390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     pLinker.defineSymbol<MCLinker::Force,
391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          MCLinker::Resolve>("_end",
392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             false, // isDyn
393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::NoType,
394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Define,
395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Absolute,
396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // size
397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             0x0, // value
398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             NULL, // FragRef
399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                             ResolveInfo::Default);
400affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
401affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
402affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
404affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool
405affc150dc44fab1911775a49636d0ce85333b634Zonr ChangGNULDBackend::finalizeStandardSymbols(MCLinker& pLinker, const Output& pOutput)
406affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
407affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = getOutputFormat(pOutput);
408affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
409affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  section symbols  ----- //
410affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayStart) {
411affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pPreInitArrayStart->hasFragRef()) {
412affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayStart->setValue(0x0);
414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
415affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pPreInitArrayEnd) {
418affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pPreInitArrayEnd->hasFragRef()) {
419affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() +
420affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   file_format->getPreInitArray().size());
421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pPreInitArrayEnd->setValue(0x0);
425affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayStart) {
429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pInitArrayStart->hasFragRef()) {
430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayStart->setValue(0x0);
432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pInitArrayEnd) {
436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pInitArrayEnd->hasFragRef()) {
437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() +
438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getInitArray().size());
439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
440affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pInitArrayEnd->setValue(0x0);
443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayStart) {
447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pFiniArrayStart->hasFragRef()) {
448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute);
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayStart->setValue(0x0);
450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pFiniArrayEnd) {
454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (f_pFiniArrayEnd->hasFragRef()) {
455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() +
456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                file_format->getFiniArray().size());
457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute);
460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pFiniArrayEnd->setValue(0x0);
461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pStack) {
465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!f_pStack->hasFragRef()) {
466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute);
467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pStack->setValue(0x0);
468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  segment symbols  ----- //
472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pExecutableStart) {
473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* exec_start = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 0x0, 0x0);
474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != exec_start) {
475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) {
476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pExecutableStart->setValue(f_pExecutableStart->value() +
477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     exec_start->vaddr());
478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      f_pExecutableStart->setValue(0x0);
482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEText || NULL != f_p_EText || NULL !=f_p__EText) {
485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* etext = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD,
486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_X,
487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_W);
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != etext) {
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText && ResolveInfo::ThreadLocal != f_pEText->type()) {
490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(f_pEText->value() +
491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           etext->vaddr() +
492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           etext->memsz());
493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText && ResolveInfo::ThreadLocal != f_p_EText->type()) {
495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(f_p_EText->value() +
496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->vaddr() +
497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->memsz());
498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText && ResolveInfo::ThreadLocal != f_p__EText->type()) {
500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(f_p__EText->value() +
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->vaddr() +
502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            etext->memsz());
503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEText)
507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEText->setValue(0x0);
508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EText)
509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EText->setValue(0x0);
510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p__EText)
511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p__EText->setValue(0x0);
512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != f_pEData || NULL != f_p_EData || NULL != f_pBSSStart ||
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      NULL != f_pEnd || NULL != f_p_End) {
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* edata = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD,
518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               llvm::ELF::PF_W,
519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                               0x0);
520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (NULL != edata) {
521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) {
522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(f_pEData->value() +
523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->vaddr() +
524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->filesz());
525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) {
527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(f_p_EData->value() +
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->vaddr() +
529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            edata->filesz());
530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart && ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(f_pBSSStart->value() +
533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              edata->vaddr() +
534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              edata->filesz());
535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) {
538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(f_pEnd->value() +
539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                         edata->vaddr() +
540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                         edata->memsz());
541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) {
543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(f_p_End->value() +
544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          edata->vaddr() +
545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          edata->memsz());
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEData)
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEData->setValue(0x0);
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_EData)
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_EData->setValue(0x0);
553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pBSSStart)
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pBSSStart->setValue(0x0);
555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_pEnd)
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_pEnd->setValue(0x0);
558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (NULL != f_p_End)
559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        f_p_End->setValue(0x0);
560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNUArchiveReader *GNULDBackend::getArchiveReader()
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
56867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pArchiveReader);
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pArchiveReader;
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
572affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst GNUArchiveReader *GNULDBackend::getArchiveReader() const
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
57467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pArchiveReader);
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pArchiveReader;
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectReader *GNULDBackend::getObjectReader()
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
58067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pObjectReader);
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pObjectReader;
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
584affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFObjectReader *GNULDBackend::getObjectReader() const
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
58667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pObjectReader);
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pObjectReader;
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFDynObjReader *GNULDBackend::getDynObjReader()
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
59267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pDynObjReader);
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pDynObjReader;
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
596affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFDynObjReader *GNULDBackend::getDynObjReader() const
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
59867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pDynObjReader);
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pDynObjReader;
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectWriter *GNULDBackend::getObjectWriter()
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return NULL;
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
608affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFObjectWriter *GNULDBackend::getObjectWriter() const
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return NULL;
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFDynObjWriter *GNULDBackend::getDynObjWriter()
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
61667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pDynObjWriter);
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pDynObjWriter;
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
620affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFDynObjWriter *GNULDBackend::getDynObjWriter() const
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
62267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pDynObjWriter);
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pDynObjWriter;
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
626affc150dc44fab1911775a49636d0ce85333b634Zonr ChangELFExecWriter *GNULDBackend::getExecWriter()
627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pExecWriter);
629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return m_pExecWriter;
630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
632affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFExecWriter *GNULDBackend::getExecWriter() const
633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != m_pExecWriter);
635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return m_pExecWriter;
636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
638affc150dc44fab1911775a49636d0ce85333b634Zonr ChangELFFileFormat* GNULDBackend::getOutputFormat(const Output& pOutput)
639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  switch (pOutput.type()) {
641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::DynObj:
642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return getDynObjFileFormat();
643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::Exec:
644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return getExecFileFormat();
645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // FIXME: We do not support building .o now
646affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::Object:
647affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unrecognized_output_file) << pOutput.type();
649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
653affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFFileFormat* GNULDBackend::getOutputFormat(const Output& pOutput) const
654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  switch (pOutput.type()) {
656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::DynObj:
657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return getDynObjFileFormat();
658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::Exec:
659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return getExecFileFormat();
660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // FIXME: We do not support building .o now
661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case Output::Object:
662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::unrecognized_output_file) << pOutput.type();
664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return NULL;
665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFDynObjFileFormat* GNULDBackend::getDynObjFileFormat()
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
67067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pDynObjFileFormat);
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pDynObjFileFormat;
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
674affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFDynObjFileFormat* GNULDBackend::getDynObjFileFormat() const
6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
67667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pDynObjFileFormat);
6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pDynObjFileFormat;
6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFExecFileFormat* GNULDBackend::getExecFileFormat()
6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
68267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pExecFileFormat);
6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pExecFileFormat;
6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
686affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst ELFExecFileFormat* GNULDBackend::getExecFileFormat() const
6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
68867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(NULL != m_pExecFileFormat);
6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pExecFileFormat;
6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools
6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab,
6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// .dynsym, .dynstr, and .hash
6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid
6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::sizeNamePools(const Output& pOutput,
6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            const SymbolCategory& pSymbols,
6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            const MCLDInfo& pLDInfo)
6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // size of string tables starts from 1 to hold the null character in their
7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // first byte
7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtab = 1;
7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t dynsym = 1;
7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // number of entries in symbol tables starts from 1 to hold the special entry
7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtab = 1;
7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t dynstr = 1;
7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hash   = 0;
7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute size of .symtab, .dynsym and .strtab
7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::const_iterator symbol;
7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::const_iterator symEnd = pSymbols.end();
7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (symbol = pSymbols.begin(); symbol != symEnd; ++symbol) {
7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t str_size = (*symbol)->nameSize() + 1;
7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isDynamicSymbol(**symbol, pOutput)) {
7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      ++dynsym;
7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      dynstr += str_size;
7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtab;
7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strtab += str_size;
7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
723affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = getOutputFormat(pOutput);
7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch(pOutput.type()) {
7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute size of .dynstr and .hash
7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::DynObj:
7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Exec: {
7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // add DT_NEED strings into .dynstr and .dynamic
7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Rules:
7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      //   1. ignore --no-add-needed
7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      //   2. force count in --no-as-needed
7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      //   3. judge --as-needed
7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (Input::DynObj == (*input)->type()) {
7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // --add-needed
7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if ((*input)->attribute()->isAddNeeded()) {
7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            // --no-as-needed
7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            if (!(*input)->attribute()->isAsNeeded()) {
7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              dynstr += (*input)->name().size() + 1;
7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              dynamic().reserveNeedEntry();
7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            }
7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            // --as-needed
7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            else if ((*input)->isNeeded()) {
7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              dynstr += (*input)->name().size() + 1;
7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              dynamic().reserveNeedEntry();
7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            }
7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } // for
7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // compute .hash
7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Both Elf32_Word and Elf64_Word are 4 bytes
7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao             sizeof(llvm::ELF::Elf32_Word);
7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set size
7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      dynstr += pOutput.name().size() + 1;
7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (32 == bitclass())
7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getDynStrTab().setSize(dynstr);
7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getHashTab().setSize(hash);
7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    /* fall through */
7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case Output::Object: {
7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (32 == bitclass())
7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_format->getStrTab().setSize(strtab);
7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of switch
7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // reserve fixed entries in the .dynamic section.
7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (Output::DynObj == pOutput.type() || Output::Exec == pOutput.type()) {
7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // Because some entries in .dynamic section need information of .dynsym,
7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // entries until we get the size of the sections mentioned above
7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    dynamic().reserveEntries(pLDInfo, *file_format);
7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    file_format->getDynamic().setSize(dynamic().numOfBytes());
7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab
7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
7925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid GNULDBackend::emitRegNamePools(Output& pOutput,
7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    SymbolCategory& pSymbols,
7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const Layout& pLayout,
7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const MCLDInfo& pLDInfo)
7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
7985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pOutput.hasMemArea());
8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
804affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = getOutputFormat(pOutput);
805affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pOutput.type() == Output::Object) {
806affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // add first symbol into m_pSymIndexMap
807affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    entry = m_pSymIndexMap->insert(NULL, sym_exist);
808affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    entry->setValue(0);
8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
810affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // TODO: not support yet
811affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return;
8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getSymTab();
8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getStrTab();
8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           symtab_sect.size());
8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           strtab_sect.size());
8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (32 == bitclass())
8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (64 == bitclass())
8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("unsupported bitclass ") +
8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(bitclass()) +
8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(".\n"));
8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize the first ELF symbol
8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (32 == bitclass()) {
8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_name  = 0;
8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_value = 0;
8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_size  = 0;
8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_info  = 0;
8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_other = 0;
8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_shndx = 0;
8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else { // must 64
8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_name  = 0;
8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_value = 0;
8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_size  = 0;
8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_info  = 0;
8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_other = 0;
8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_shndx = 0;
8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute size of .symtab, .dynsym and .strtab
8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::iterator symbol;
8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::iterator symEnd = pSymbols.end();
8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (symbol = pSymbols.begin(); symbol != symEnd; ++symbol) {
8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao     // maintain output's symbol and index map if building .o file
8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (Output::Object == pOutput.type()) {
8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      entry = m_pSymIndexMap->insert(NULL, sym_exist);
8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      entry->setValue(symtabIdx);
8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // FIXME: check the endian between host and target
8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // write out symbol
8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (32 == bitclass()) {
8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_name  = strtabsize;
8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_value = getSymbolValue(**symbol);
8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_size  = getSymbolSize(**symbol);
8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_info  = getSymbolInfo(**symbol);
8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_other = (*symbol)->visibility();
8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else { // must 64
8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_name  = strtabsize;
8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_value = getSymbolValue(**symbol);
8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_size  = getSymbolSize(**symbol);
8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_info  = getSymbolInfo(**symbol);
8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_other = (*symbol)->visibility();
8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // write out string
8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strcpy((strtab + strtabsize), (*symbol)->name());
8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // write out
8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strtabsize += (*symbol)->nameSize() + 1;
8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
8955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout
8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables
9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid GNULDBackend::emitDynNamePools(Output& pOutput,
9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    SymbolCategory& pSymbols,
9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const Layout& pLayout,
9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const MCLDInfo& pLDInfo)
9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
9055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pOutput.hasMemArea());
906affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat* file_format = getOutputFormat(pOutput);
9075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool sym_exist = false;
9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType::entry_type* entry = 0;
9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& symtab_sect = file_format->getDynSymTab();
9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& strtab_sect = file_format->getDynStrTab();
9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& hash_sect   = file_format->getHashTab();
9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection& dyn_sect    = file_format->getDynamic();
9155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
9175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           symtab_sect.size());
9185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
9195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                           strtab_sect.size());
9205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(),
9215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         hash_sect.size());
9225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(),
9235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                        dyn_sect.size());
9245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up symtab_region
9255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf32_Sym* symtab32 = NULL;
9265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::ELF::Elf64_Sym* symtab64 = NULL;
9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (32 == bitclass())
9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
9295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (64 == bitclass())
9305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
9315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
9325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("unsupported bitclass ") +
9335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(bitclass()) +
9345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(".\n"));
9355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize the first ELF symbol
9375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (32 == bitclass()) {
9385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_name  = 0;
9395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_value = 0;
9405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_size  = 0;
9415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_info  = 0;
9425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_other = 0;
9435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab32[0].st_shndx = 0;
9445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else { // must 64
9465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_name  = 0;
9475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_value = 0;
9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_size  = 0;
9495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_info  = 0;
9505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_other = 0;
9515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    symtab64[0].st_shndx = 0;
9525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
9535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up strtab_region
9545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = (char*)strtab_region->start();
9555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtab[0] = '\0';
9565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add the first symbol into m_pSymIndexMap
9585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry = m_pSymIndexMap->insert(NULL, sym_exist);
9595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entry->setValue(0);
9605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symtabIdx = 1;
9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t strtabsize = 1;
9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit of .dynsym, and .dynstr
9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::iterator symbol;
9665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::iterator symEnd = pSymbols.end();
9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (symbol = pSymbols.begin(); symbol != symEnd; ++symbol) {
9685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!isDynamicSymbol(**symbol, pOutput))
9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
9705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // maintain output's symbol and index map
9725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
9735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry->setValue(symtabIdx);
9745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // FIXME: check the endian between host and target
9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // write out symbol
9775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (32 == bitclass()) {
9785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_name  = strtabsize;
9795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_value = (*symbol)->value();
9805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_size  = getSymbolSize(**symbol);
9815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_info  = getSymbolInfo(**symbol);
9825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_other = (*symbol)->visibility();
9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab32[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
9845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
9855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else { // must 64
9865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_name  = strtabsize;
9875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_value = (*symbol)->value();
9885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_size  = getSymbolSize(**symbol);
9895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_info  = getSymbolInfo(**symbol);
9905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_other = (*symbol)->visibility();
9915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      symtab64[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
9935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // write out string
9945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strcpy((strtab + strtabsize), (*symbol)->name());
9955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // sum up counters
9975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++symtabIdx;
9985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strtabsize += (*symbol)->nameSize() + 1;
9995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit DT_NEED
10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // add DT_NEED strings into .dynstr
10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Rules:
10045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   1. ignore --no-add-needed
10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   2. force count in --no-as-needed
10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   3. judge --as-needed
10075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynamic::iterator dt_need = dynamic().needBegin();
10085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
10095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (Input::DynObj == (*input)->type()) {
10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // --add-needed
10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if ((*input)->attribute()->isAddNeeded()) {
10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // --no-as-needed
10145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (!(*input)->attribute()->isAsNeeded()) {
10155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strcpy((strtab + strtabsize), (*input)->name().c_str());
10165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
10175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strtabsize += (*input)->name().size() + 1;
10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ++dt_need;
10195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
10205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // --as-needed
10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        else if ((*input)->isNeeded()) {
10225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strcpy((strtab + strtabsize), (*input)->name().c_str());
10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          strtabsize += (*input)->name().size() + 1;
10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ++dt_need;
10265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
10285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // for
10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit soname
10325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize value of ELF .dynamic section
1033affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Output::DynObj == pOutput.type())
1034affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dynamic().applySoname(strtabsize);
10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().applyEntries(pLDInfo, *file_format);
10365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dynamic().emit(dyn_sect, *dyn_region);
10375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strcpy((strtab + strtabsize), pOutput.name().c_str());
10395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  strtabsize += pOutput.name().size() + 1;
10405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // emit hash table
10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: this verion only emit SVR4 hash section.
10435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //        Please add GNU new hash section
10445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // both 32 and 64 bits hash table use 32-bit entry
10465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up hash_region
10475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* word_array = (uint32_t*)hash_region->start();
10485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nbucket = word_array[0];
10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t& nchain  = word_array[1];
10505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nbucket = getHashBucketCount(symtabIdx, false);
10525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  nchain  = symtabIdx;
10535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* bucket = (word_array + 2);
10555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* chain  = (bucket + nbucket);
10565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // initialize bucket
10585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bzero((void*)bucket, nbucket);
10595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  StringHash<ELF> hash_func;
10615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (32 == bitclass()) {
10635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
10645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
10655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      size_t bucket_pos = hash_func(name) % nbucket;
10665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      chain[sym_idx] = bucket[bucket_pos];
10675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      bucket[bucket_pos] = sym_idx;
10685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
10695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (64 == bitclass()) {
10715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
10725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::StringRef name(strtab + symtab64[sym_idx].st_name);
10735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      size_t bucket_pos = hash_func(name) % nbucket;
10745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      chain[sym_idx] = bucket[bucket_pos];
10755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      bucket[bucket_pos] = sym_idx;
10765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
10775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
10785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
10795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1080affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section
1081affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid GNULDBackend::sizeInterp(const Output& pOutput, const MCLDInfo& pLDInfo)
1082affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1083affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pOutput.type() == Output::Exec);
1084affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1085affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const char* dyld_name;
1086affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pLDInfo.options().hasDyld())
1087affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyld_name = pLDInfo.options().dyld().c_str();
1088affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1089affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyld_name = dyld();
1090affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1091affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection& interp = getExecFileFormat()->getInterp();
1092affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  interp.setSize(std::strlen(dyld_name) + 1);
1093affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1094affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1095affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp
1096affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid GNULDBackend::emitInterp(Output& pOutput, const MCLDInfo& pLDInfo)
1097affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1098affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pOutput.type() == Output::Exec &&
1099affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         getExecFileFormat()->hasInterp() &&
1100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         pOutput.hasMemArea());
1101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const LDSection& interp = getExecFileFormat()->getInterp();
1103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  MemoryRegion *region = pOutput.memArea()->request(
1104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                              interp.offset(), interp.size());
1105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const char* dyld_name;
1106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pLDInfo.options().hasDyld())
1107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyld_name = pLDInfo.options().dyld().c_str();
1108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyld_name = dyld();
1110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  std::memcpy(region->start(), dyld_name, interp.size());
1112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
11145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder
11155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int GNULDBackend::getSectionOrder(const Output& pOutput,
1116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                           const LDSection& pSectHdr,
1117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                           const MCLDInfo& pInfo) const
11185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
11195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // NULL section should be the "1st" section
11205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (LDFileFormat::Null == pSectHdr.kind())
11215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0;
11225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the section is not ALLOC, lay it out until the last possible moment
11245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC))
11255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return SHO_UNDEFINED;
11265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0;
11285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0;
1129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFFileFormat* file_format = getOutputFormat(pOutput);
11305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // TODO: need to take care other possible output sections
11325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (pSectHdr.kind()) {
11335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Regular:
11345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (is_exec) {
11355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getInit())
11365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_INIT;
11375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (&pSectHdr == &file_format->getFini())
11385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          return SHO_FINI;
11395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_TEXT;
11405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else if (!is_write) {
11415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RO;
11425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      } else {
1143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (pInfo.options().hasRelro()) {
1144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (pSectHdr.type() == llvm::ELF::SHT_PREINIT_ARRAY ||
1145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              pSectHdr.type() == llvm::ELF::SHT_INIT_ARRAY ||
1146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              pSectHdr.type() == llvm::ELF::SHT_FINI_ARRAY ||
1147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getCtors() ||
1148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getDtors() ||
1149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              &pSectHdr == &file_format->getJCR() ||
1150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang              0 == pSectHdr.name().compare(".data.rel.ro"))
1151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO;
1152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (0 == pSectHdr.name().compare(".data.rel.ro.local"))
1153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            return SHO_RELRO_LOCAL;
1154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
11555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_DATA;
11565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
11575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::BSS:
11595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_BSS;
11605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::NamePool:
11625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getDynamic())
11635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_RELRO;
11645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_NAMEPOOL;
11655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Relocation:
11675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pSectHdr == &file_format->getRelPlt() ||
11685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          &pSectHdr == &file_format->getRelaPlt())
11695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return SHO_REL_PLT;
11705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_RELOCATION;
11715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // get the order from target for target specific sections
11735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Target:
1174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return getTargetSectionOrder(pOutput, pSectHdr, pInfo);
11755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // handle .interp
11775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Note:
11785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_INTERP;
11795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrame:
1181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::EhFrameHdr:
1182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case LDFileFormat::GCCExceptTable:
1183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return SHO_EXCEPTION;
11845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::MetaData:
11865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    case LDFileFormat::Debug:
11875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    default:
11885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return SHO_UNDEFINED;
11895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
11905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
11915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize
11935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const
11945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
11955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold linker: symtab.cc: 2780
11965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // undefined and dynamic symbols should have zero size.
11975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined)
11985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
11995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.resolveInfo()->size();
12005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo
12035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const
12045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set binding
12065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t bind = 0x0;
12075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isLocal())
12085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
12095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isGlobal())
12105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
12115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isWeak())
12125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_WEAK;
12135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (pSymbol.resolveInfo()->isAbsolute()) {
12145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // (Luba) Is a absolute but not global (weak or local) symbol meaningful?
12155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_GLOBAL;
12165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
12195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pSymbol.visibility() == llvm::ELF::STV_HIDDEN)
12205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bind = llvm::ELF::STB_LOCAL;
12215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t type = pSymbol.resolveInfo()->type();
1223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change
1224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // its type to Function
1225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn())
1226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    type = ResolveInfo::Function;
1227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (type | (bind << 4));
12285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout()
12315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const
12325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.isDyn())
12345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0x0;
12355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pSymbol.value();
12375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout()
12405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t
12415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::getSymbolShndx(const LDSymbol& pSymbol, const Layout& pLayout) const
12425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isAbsolute())
12445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_ABS;
12455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isCommon())
12465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_COMMON;
12475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn())
12485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return llvm::ELF::SHN_UNDEF;
12495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.resolveInfo()->isLocal()) {
12515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch (pSymbol.type()) {
12525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case ResolveInfo::NoType:
12535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case ResolveInfo::File:
12545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return llvm::ELF::SHN_ABS;
12555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
12565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
12575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pSymbol.hasFragRef() && "symbols must have fragment reference to get its index");
12595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pLayout.getOutputLDSection(*pSymbol.fragRef()->frag())->index();
12605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index
12635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::getSymbolIdx(LDSymbol* pSymbol) const
12645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
12655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao   HashTableType::iterator entry = m_pSymIndexMap->find(pSymbol);
12665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao   return entry.getEntry()->value();
12675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
12685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding
1270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sections.
1271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @refer Google gold linker: common.cc: 214
1272affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool
1273affc150dc44fab1911775a49636d0ce85333b634Zonr ChangGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
12745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
1276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
1278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  SymbolCategory::iterator com_sym, com_end;
1281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: If the order of common symbols is defined, then sort common symbols
1283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // std::sort(com_sym, com_end, some kind of order);
1284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get or create corresponding BSS LDSection
1286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* bss_sect = &pLinker.getOrCreateOutputSectHdr(".bss",
1287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
1288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
1289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
1290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* tbss_sect = &pLinker.getOrCreateOutputSectHdr(
1292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   ".tbss",
1293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   LDFileFormat::BSS,
1294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHT_NOBITS,
1295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
1296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(NULL != bss_sect && NULL !=tbss_sect);
1298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1299cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // get or create corresponding BSS SectionData
1300cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect);
1301cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect);
1302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // remember original BSS size
1304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t bss_offset  = bss_sect->size();
1305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t tbss_offset = tbss_sect->size();
1306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all local common symbols
1308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.localEnd();
1309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
1311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::Common == (*com_sym)->desc()) {
1312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // We have to reset the description of the symbol here. When doing
1313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // incremental linking, the output relocatable object may have common
1314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // symbols. Therefore, we can not treat common symbols as normal symbols
1315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // when emitting the regular name pools. We must change the symbols'
1316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // description here.
1317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1318cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
1319cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
1320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // allocate TLS common symbol in tbss section
1323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        tbss_offset += pLinker.getLayout().appendFragment(*frag,
1324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                          tbss_sect_data,
1325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                          (*com_sym)->value());
1326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      else {
1328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        bss_offset += pLinker.getLayout().appendFragment(*frag,
1329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                         bss_sect_data,
1330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                         (*com_sym)->value());
1331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
13345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // allocate all global common symbols
1336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  com_end = symbol_list.commonEnd();
1337affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
1338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // We have to reset the description of the symbol here. When doing
1339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // incremental linking, the output relocatable object may have common
1340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // symbols. Therefore, we can not treat common symbols as normal symbols
1341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // when emitting the regular name pools. We must change the symbols'
1342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // description here.
1343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
1344cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
1345cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
1346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
1348affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // allocate TLS common symbol in tbss section
1349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      tbss_offset += pLinker.getLayout().appendFragment(*frag,
1350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                        tbss_sect_data,
1351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                        (*com_sym)->value());
1352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else {
1354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      bss_offset += pLinker.getLayout().appendFragment(*frag,
1355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                       bss_sect_data,
1356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                       (*com_sym)->value());
1357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bss_sect->setSize(bss_offset);
1361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  tbss_sect->setSize(tbss_offset);
1362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  symbol_list.changeCommonsToGlobal();
1363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
13645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
13655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers
1368affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid GNULDBackend::createProgramHdrs(Output& pOutput, const MCLDInfo& pInfo)
13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(pOutput.hasContext());
1371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFFileFormat *file_format = getOutputFormat(pOutput);
1372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
13735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_PHDR
13745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_ELFSegmentTable.produce(llvm::ELF::PT_PHDR);
13755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_INTERP
1377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasInterp()) {
13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ELFSegment* interp_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_INTERP);
1379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    interp_seg->addSection(&file_format->getInterp());
1380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1382cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // FIXME: Should we consider -z relro here?
1383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pInfo.options().hasRelro()) {
1384affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // if -z relro is given, we need to adjust sections' offset again, and let
1385affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // PT_GNU_RELRO end on a common page boundary
1386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    LDContext::SectionTable& sect_table = pOutput.context()->getSectionTable();
1387cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1388cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    size_t idx;
1389cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    for (idx = 0; idx < pOutput.context()->numOfSections(); ++idx) {
1390cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      // find the first non-relro section
1391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (getSectionOrder(pOutput, *sect_table[idx], pInfo) > SHO_RELRO_LAST) {
1392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
1393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1395cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1396cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // align the first non-relro section to page boundary
1397cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    uint64_t offset = sect_table[idx]->offset();
1398cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    alignAddress(offset, commonPageSize(pInfo));
1399cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    sect_table[idx]->setOffset(offset);
1400cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1401cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // set up remaining section's offset
1402cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    for (++idx; idx < pOutput.context()->numOfSections(); ++idx) {
1403cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      uint64_t offset;
1404cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      size_t prev_idx = idx - 1;
1405cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      if (LDFileFormat::BSS == sect_table[prev_idx]->kind())
1406cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        offset = sect_table[prev_idx]->offset();
1407cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      else
1408cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        offset = sect_table[prev_idx]->offset() + sect_table[prev_idx]->size();
1409cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1410affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      alignAddress(offset, sect_table[idx]->align());
1411affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      sect_table[idx]->setOffset(offset);
1412affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
1413cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  } // relro
14145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t cur_seg_flag, prev_seg_flag = getSegmentFlag(0);
14165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t padding = 0;
14175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegment* load_seg = NULL;
14185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make possible PT_LOAD segments
1419affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDContext::sect_iterator sect, sect_end = pOutput.context()->sectEnd();
1420affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (sect = pOutput.context()->sectBegin(); sect != sect_end; ++sect) {
1421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
14225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0 == ((*sect)->flag() & llvm::ELF::SHF_ALLOC) &&
14235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        LDFileFormat::Null != (*sect)->kind())
14245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
14255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // FIXME: Now only separate writable and non-writable PT_LOAD
14275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    cur_seg_flag = getSegmentFlag((*sect)->flag());
14285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((prev_seg_flag & llvm::ELF::PF_W) ^ (cur_seg_flag & llvm::ELF::PF_W) ||
14295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         LDFileFormat::Null == (*sect)->kind()) {
14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // create new PT_LOAD segment
14315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      load_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_LOAD);
1432cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      load_seg->setAlign(abiPageSize(pInfo));
14335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // check if this segment needs padding
14355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      padding = 0;
1436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (((*sect)->offset() & (abiPageSize(pInfo) - 1)) != 0)
1437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        padding = abiPageSize(pInfo);
14385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
14395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != load_seg);
1441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    load_seg->addSection((*sect));
1442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (cur_seg_flag != prev_seg_flag)
1443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      load_seg->updateFlag(cur_seg_flag);
14445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (LDFileFormat::Null != (*sect)->kind())
1446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      (*sect)->setAddr(segmentStartAddr(pOutput, pInfo) +
1447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                       (*sect)->offset() +
1448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                       padding);
14495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    prev_seg_flag = cur_seg_flag;
14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make PT_DYNAMIC
1454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasDynamic()) {
1455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* dyn_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_DYNAMIC,
1456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_R |
1457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                    llvm::ELF::PF_W);
1458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dyn_seg->addSection(&file_format->getDynamic());
1459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pInfo.options().hasRelro()) {
1462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // make PT_GNU_RELRO
1463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* relro_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_RELRO);
1464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (LDContext::sect_iterator sect = pOutput.context()->sectBegin();
1465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang         sect != pOutput.context()->sectEnd(); ++sect) {
1466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      unsigned int order = getSectionOrder(pOutput, **sect, pInfo);
1467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (SHO_RELRO_LOCAL == order ||
1468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          SHO_RELRO == order ||
1469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          SHO_RELRO_LAST == order) {
1470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        relro_seg->addSection(*sect);
1471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
14735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
14745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // make PT_GNU_EH_FRAME
1476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (file_format->hasEhFrameHdr()) {
1477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFSegment* eh_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_EH_FRAME);
1478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    eh_seg->addSection(&file_format->getEhFrameHdr());
1479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments
1483affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid GNULDBackend:: setupProgramHdrs(const Output& pOutput, const MCLDInfo& pInfo)
1484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
14855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update segment info
14865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegmentFactory::iterator seg, seg_end = m_ELFSegmentTable.end();
14875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (seg = m_ELFSegmentTable.begin(); seg != seg_end; ++seg) {
14885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ELFSegment& segment = *seg;
14895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // update PT_PHDR
14915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (llvm::ELF::PT_PHDR == segment.type()) {
14925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      uint64_t offset, phdr_size;
14935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (32 == bitclass()) {
14945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf32_Ehdr);
14955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
14965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
14975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else {
14985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        offset = sizeof(llvm::ELF::Elf64_Ehdr);
14995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        phdr_size = sizeof(llvm::ELF::Elf64_Phdr);
15005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
15015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setOffset(offset);
1502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      segment.setVaddr(segmentStartAddr(pOutput, pInfo) + offset);
15035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setPaddr(segment.vaddr());
15045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setFilesz(numOfSegments() * phdr_size);
15055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setMemsz(numOfSegments() * phdr_size);
15065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      segment.setAlign(bitclass() / 8);
15075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
15085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
15095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // bypass if there is no section in this segment (e.g., PT_GNU_STACK)
1511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (segment.numOfSections() == 0)
1512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      continue;
1513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setOffset(segment.getFirstSection()->offset());
1515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::PT_LOAD == segment.type() &&
1516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        LDFileFormat::Null == segment.getFirstSection()->kind())
1517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      segment.setVaddr(segmentStartAddr(pOutput, pInfo));
1518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
1519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      segment.setVaddr(segment.getFirstSection()->addr());
15205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setPaddr(segment.vaddr());
15215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    const LDSection* last_sect = segment.getLastSection();
15235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL != last_sect);
1524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    uint64_t file_size = last_sect->offset() - segment.offset();
15255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (LDFileFormat::BSS != last_sect->kind())
15265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      file_size += last_sect->size();
15275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setFilesz(file_size);
15285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    segment.setMemsz(last_sect->addr() - segment.vaddr() + last_sect->size());
15305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
15315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// createGNUStackInfo - create an output GNU stack section or segment if needed
1534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: layout.cc:2608
1535affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid GNULDBackend::createGNUStackInfo(const Output& pOutput,
1536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      const MCLDInfo& pInfo,
1537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      MCLinker& pLinker)
15385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint32_t flag = 0x0;
1540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pInfo.options().hasStackSet()) {
1541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 1. check the command line option (-z execstack or -z noexecstack)
1542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (pInfo.options().hasExecStack())
1543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      flag = llvm::ELF::SHF_EXECINSTR;
1544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  } else {
1545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2. check the stack info from the input objects
1546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    size_t object_count = 0, stack_note_count = 0;
1547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    mcld::InputTree::const_bfs_iterator input, inEnd = pInfo.inputs().bfs_end();
1548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    for (input=pInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
1549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if ((*input)->type() == Input::Object) {
1550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        ++object_count;
1551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        const LDSection* sect = (*input)->context()->getSection(
1552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                             ".note.GNU-stack");
1553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL != sect) {
1554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          ++stack_note_count;
1555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // 2.1 found a stack note that is set as executable
1556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) {
1557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            flag = llvm::ELF::SHF_EXECINSTR;
1558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            break;
1559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          }
1560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
1561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
1562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
15635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.2 there are no stack note sections in all input objects
1565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (0 == stack_note_count)
1566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      return;
15675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 2.3 a special case. Use the target default to decide if the stack should
1569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    //     be executable
1570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count)
1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (isDefaultExecStack())
1572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        flag = llvm::ELF::SHF_EXECINSTR;
15735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
15745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pOutput.type() != Output::Object)
1576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_STACK,
1577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              llvm::ELF::PF_R |
1578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              llvm::ELF::PF_W |
1579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              getSegmentFlag(flag));
1580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    pLinker.getOrCreateOutputSectHdr(".note.GNU-stack",
1582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     LDFileFormat::Note,
1583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     llvm::ELF::SHT_PROGBITS,
1584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     flag);
15855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
15865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// preLayout - Backend can do any needed modification before layout
15885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid GNULDBackend::preLayout(const Output& pOutput,
15895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             const MCLDInfo& pLDInfo,
15905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             MCLinker& pLinker)
15915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
15925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // prelayout target first
15935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  doPreLayout(pOutput, pLDInfo, pLinker);
1594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pLDInfo.options().hasEhFrameHdr()) {
1596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // init EhFrameHdr and size the output section
1597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFFileFormat* format = getOutputFormat(pOutput);
1598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    assert(NULL != getEhFrame());
1599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr = new EhFrameHdr(*getEhFrame(),
1600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   format->getEhFrame(),
1601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   format->getEhFrameHdr());
1602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pEhFrameHdr->sizeOutput();
1603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
16045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
16055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1606cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout
16075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid GNULDBackend::postLayout(const Output& pOutput,
16085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                              const MCLDInfo& pInfo,
16095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                              MCLinker& pLinker)
16105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 1. emit program headers
1612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pOutput.type() != Output::Object) {
1613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 1.1 create program headers
1614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    createProgramHdrs(pLinker.getLDInfo().output(), pInfo);
1615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 1.2 create special GNU Stack note section or segment
1618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  createGNUStackInfo(pOutput, pInfo, pLinker);
1619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pOutput.type() != Output::Object) {
1621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // 1.3 set up the attributes of program headers
1622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    setupProgramHdrs(pOutput, pInfo);
1623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 2. target specific post layout
16265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  doPostLayout(pOutput, pInfo, pLinker);
16275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
16285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1629affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid GNULDBackend::postProcessing(const Output& pOutput,
1630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                  const MCLDInfo& pInfo,
1631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                  MCLinker& pLinker)
1632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pInfo.options().hasEhFrameHdr()) {
1634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // emit eh_frame_hdr
1635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (bitclass() == 32)
1636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_pEhFrameHdr->emitOutput<32>(pLinker.getLDInfo().output(),
1637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                    pLinker);
1638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
1639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
16415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count.
16425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker, dynobj.cc:791
16435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols,
16445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          bool pIsGNUStyle)
16455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
16465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // @ref Google gold, dynobj.cc:loc 791
16475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static const unsigned int buckets[] =
16485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
16495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
16505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    16411, 32771, 65537, 131101, 262147
16515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
16525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const unsigned buckets_count = sizeof buckets / sizeof buckets[0];
16535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int result = 1;
16555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (unsigned i = 0; i < buckets_count; ++i) {
16565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pNumOfSymbols < buckets[i])
16575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
16585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = buckets[i];
16595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
16605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pIsGNUStyle && result < 2)
16625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = 2;
16635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
16655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
16665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol
16685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker: symtab.cc:311
16695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol,
16705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const Output& pOutput)
16715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
16725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If a local symbol is in the LDContext's symbol table, it's a real local
16735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // symbol. We should not add it
16745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSymbol.binding() == ResolveInfo::Local)
16755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
16765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // If we are building shared object, and the visibility is external, we
16785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // need to add it.
1679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Output::DynObj == pOutput.type() || Output::Exec == pOutput.type())
16805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default ||
16815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected)
16825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return true;
1683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
1684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine.
1687affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:135
1688affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t GNULDBackend::commonPageSize(const MCLDInfo& pInfo) const
1689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pInfo.options().commPageSize() > 0)
1691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return std::min(pInfo.options().commPageSize(), abiPageSize(pInfo));
1692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return std::min(static_cast<uint64_t>(0x1000), abiPageSize(pInfo));
1694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine.
1697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:125
1698affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t GNULDBackend::abiPageSize(const MCLDInfo& pInfo) const
1699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pInfo.options().maxPageSize() > 0)
1701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return pInfo.options().maxPageSize();
1702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
1703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return static_cast<uint64_t>(0x1000);
1704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1705affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1706affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isOutputPIC - return whether the output is position-independent
1707affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::isOutputPIC(const Output& pOutput,
1708affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                               const MCLDInfo& pInfo) const
1709affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1710affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Output::DynObj == pOutput.type() || pInfo.options().isPIE())
1711affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1712affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
1713affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1714affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1715affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isStaticLink - return whether we're doing static link
1716affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::isStaticLink(const Output& pOutput,
1717affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                const MCLDInfo& pInfo) const
1718affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1719affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  InputTree::const_iterator it = pInfo.inputs().begin();
1720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!isOutputPIC(pOutput, pInfo) && (*it)->attribute()->isStatic())
1721affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1722affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
1723affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1724affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1725affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other
1726affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit
1727affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:551
1728affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym,
1729affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const MCLDInfo& pLDInfo,
1730affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       const Output& pOutput) const
1731affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.other() != ResolveInfo::Default)
1733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1734affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1735affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Output::DynObj != pOutput.type())
1736affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1737affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1738affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pLDInfo.options().Bsymbolic())
1739affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1740affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1741affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
1742affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1743affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1744affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry
1745affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:596
1746affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::symbolNeedsPLT(const ResolveInfo& pSym,
1747affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                  const MCLDInfo& pLDInfo,
1748affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                  const Output& pOutput) const
1749affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.isUndef() && !pSym.isDyn() && pOutput.type() != Output::DynObj)
1751affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1752affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1753affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry
1754affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() == ResolveInfo::IndirectFunc)
1755affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1756affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1757affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.type() != ResolveInfo::Function)
1758affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1759affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1760affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (isStaticLink(pOutput, pLDInfo) || pLDInfo.options().isPIE())
1761affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1762affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1763affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return (pSym.isDyn() ||
1764affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          pSym.isUndef() ||
1765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          isSymbolPreemptible(pSym, pLDInfo, pOutput));
1766affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1767affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1768affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
1769affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:645
1770affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::symbolNeedsDynRel(const ResolveInfo& pSym,
1771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     bool pSymHasPLT,
1772affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const MCLDInfo& pLDInfo,
1773affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const Output& pOutput,
1774affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     bool isAbsReloc) const
1775affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1776affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // an undefined reference in the executables should be statically
1777affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // resolved to 0 and no need a dynamic relocation
1778affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.isUndef() && !pSym.isDyn() && (Output::Exec == pOutput.type()))
1779affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1780affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.isAbsolute())
1781affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1782affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (isOutputPIC(pOutput, pLDInfo) && isAbsReloc)
1783affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1784affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSymHasPLT && ResolveInfo::Function == pSym.type())
1785affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1786affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!isOutputPIC(pOutput, pLDInfo) && pSymHasPLT)
1787affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1788affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.isDyn() || pSym.isUndef() ||
1789affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      isSymbolPreemptible(pSym, pLDInfo, pOutput))
1790affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
1791affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1792affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return false;
1793affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
1794affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1795affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
1796affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool GNULDBackend::symbolNeedsCopyReloc(const Layout& pLayout,
1797affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const Relocation& pReloc,
1798affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const ResolveInfo& pSym,
1799affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const MCLDInfo& pLDInfo,
1800affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        const Output& pOutput) const
1801affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
1802affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // only the reference from dynamic executable to non-function symbol in
1803affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // the dynamic objects may need copy relocation
1804affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (isOutputPIC(pOutput, pLDInfo) ||
1805affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      !pSym.isDyn() ||
1806affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.type() == ResolveInfo::Function ||
1807affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pSym.size() == 0)
1808affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1809affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1810affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // check if the option -z nocopyreloc is given
1811affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pLDInfo.options().hasNoCopyReloc())
1812affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
1813affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1814affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // TODO: Is this check necessary?
1815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if relocation target place is readonly, a copy relocation is needed
1816affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if ((pLayout.getOutputLDSection(*pReloc.targetRef().frag())->flag() &
1817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      llvm::ELF::SHF_WRITE) == 0)
1818affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
18195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
18215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1822affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1823