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