GNULDBackend.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- GNULDBackend.cpp ---------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <string> 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring> 13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cassert> 14d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <vector> 15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <algorithm> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h> 21d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Config/Config.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h> 23cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/LDSymbol.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h> 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrameHdr.h> 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h> 29d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h> 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h> 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryArea.h> 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 34affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 35cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/MemoryAreaFactory.h> 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIslandFactory.h> 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/StubFactory.h> 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===--------------------------------------------------------------------===// 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatic bool isCIdentifier(const std::string& pName) 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao std::string ident = "0123456789" 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao "ABCDEFGHIJKLMNOPWRSTUVWXYZ" 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao "abcdefghijklmnopqrstuvwxyz" 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao "_"; 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return (pName.find_first_not_of(ident) > pName.length()); 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend 58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : TargetLDBackend(pConfig), 61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pObjectReader(NULL), 62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pDynObjFileFormat(NULL), 63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pExecFileFormat(NULL), 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectFileFormat(NULL), 65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pInfo(pInfo), 66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_ELFSegmentTable(9), // magic number 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pBRIslandFactory(NULL), 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pStubFactory(NULL), 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEhFrame(NULL), 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pEhFrameHdr(NULL), 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasTextRel(false), 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasStaticTLS(false), 73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart(NULL), 74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd(NULL), 75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart(NULL), 76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd(NULL), 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart(NULL), 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd(NULL), 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack(NULL), 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic(NULL), 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTDATA(NULL), 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTBSS(NULL), 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart(NULL), 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText(NULL), 85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText(NULL), 86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText(NULL), 87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData(NULL), 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData(NULL), 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart(NULL), 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd(NULL), 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End(NULL) { 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymIndexMap = new HashTableType(1024); 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::~GNULDBackend() 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 97d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pInfo; 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynObjFileFormat; 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pExecFileFormat; 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pSymIndexMap; 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pEhFrame; 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pEhFrameHdr; 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != m_pBRIslandFactory) 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pBRIslandFactory; 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != m_pStubFactory) 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pStubFactory; 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::sectionStartOffset() const 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 112d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Binary == config().codeGenType()) 113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0x0; 114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch (config().targets().bitclass()) { 116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 32u: 117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf32_Ehdr) + 118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao numOfSegments() * sizeof(llvm::ELF::Elf32_Phdr); 119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 64u: 120d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf64_Ehdr) + 121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao numOfSegments() * sizeof(llvm::ELF::Elf64_Phdr); 122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao default: 123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0; 126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::segmentStartAddr(const FragmentLinker& pLinker) const 130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ScriptOptions::AddressMap::const_iterator mapping = 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao config().scripts().addressMap().find(".text"); 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (mapping != config().scripts().addressMap().end()) 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return mapping.getEntry()->value(); 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (pLinker.isOutputPIC()) 136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return 0x0; 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return defaultTextSegmentAddr(); 139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader* 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::createArchiveReader(Module& pModule) 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectReader); 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return new GNUArchiveReader(pModule, *m_pObjectReader); 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder) 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectReader = new ELFObjectReader(*this, pBuilder, config()); 15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectReader; 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 154d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder) 155d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFDynObjReader(*this, pBuilder, config()); 157d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 158d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder) 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 161d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFBinaryReader(*this, pBuilder, config()); 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 164d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectWriter* GNULDBackend::createObjectWriter() 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 166d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFObjectWriter(*this, config()); 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 169d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjWriter* GNULDBackend::createDynObjWriter() 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 171d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFDynObjWriter(*this, config()); 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 174d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFExecWriter* GNULDBackend::createExecWriter() 175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 176d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFExecWriter(*this, config()); 177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryWriter* GNULDBackend::createBinaryWriter() 180d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 181d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFBinaryWriter(*this, config()); 182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStdSections(ObjectBuilder& pBuilder) 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pDynObjFileFormat) 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pDynObjFileFormat = new ELFDynObjFileFormat(); 190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pDynObjFileFormat->initStdSections(pBuilder, 191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pExecFileFormat) 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pExecFileFormat = new ELFExecFileFormat(); 198d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pExecFileFormat->initStdSections(pBuilder, 199d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pObjectFileFormat) 20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectFileFormat = new ELFObjectFileFormat(); 205d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectFileFormat->initStdSections(pBuilder, 206d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols. 21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations. 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStandardSymbols(FragmentLinker& pLinker, 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule) 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // GNU extension: define __start and __stop symbols for the sections whose 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // name can be presented as C symbol 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ref: GNU gold, Layout::define_section_symbols 22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator iter, iterEnd = pModule.end(); 22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iter = pModule.begin(); iter != iterEnd; ++iter) { 22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* section = *iter; 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (section->kind()) { 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasEhFrame()) 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasSectionData()) 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of switch 24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isCIdentifier(section->name())) { 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::StringRef start_name = llvm::StringRef("__start_" + section->name()); 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* start_fragref = FragmentRef::Create( 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->getSectionData()->front(), 0x0); 24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>(start_name, 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao false, // isDyn 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::NoType, 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Global, 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_fragref, // FragRef 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Default); 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::StringRef stop_name = llvm::StringRef("__stop_" + section->name()); 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* stop_fragref = FragmentRef::Create( 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->getSectionData()->front(), section->size()); 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>(stop_name, 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao false, // isDyn 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::NoType, 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Global, 26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stop_fragref, // FragRef 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Default); 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .preinit_array 278cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* preinit_array = NULL; 279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasPreInitArray()) { 28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Create( 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getPreInitArray().getSectionData()->front(), 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Null(); 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart = 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__preinit_array_start", 290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang preinit_array, // FragRef 297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd = 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__preinit_array_end", 301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .init_array 311cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* init_array = NULL; 312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInitArray()) { 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Create( 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getInitArray().getSectionData()->front(), 315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Null(); 31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart = 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__init_array_start", 324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang init_array, // FragRef 331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd = 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__init_array_end", 335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 337affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang init_array, // FragRef 342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .fini_array 345cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* fini_array = NULL; 346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasFiniArray()) { 34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Create( 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getFiniArray().getSectionData()->front(), 349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Null(); 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart = 35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__fini_array_start", 358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fini_array, // FragRef 365affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd = 36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__fini_array_end", 369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fini_array, // FragRef 376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .stack 379cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* stack = NULL; 380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasStack()) { 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Create( 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getStack().getSectionData()->front(), 383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 384affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Null(); 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack = 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__stack", 392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang stack, // FragRef 399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 400affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // _DYNAMIC 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: add SectionData for .dynamic section, and then we can get the correct 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol section index for _DYNAMIC. Now it will be ABS. 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic = 40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("_DYNAMIC", 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao false, // isDyn 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Object, 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Local, 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Hidden); 41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart = 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__executable_start", 420affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 425affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText = 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("etext", 431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText = 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("_etext", 442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText = 45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__etext", 453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData = 46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("edata", 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd = 47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("end", 476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _edata is defined forcefully. 486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 186 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData = 48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::Force, 48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("_edata", 490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // __bss_start is defined forcefully. 500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 214 501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart = 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::Force, 50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("__bss_start", 504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _end is defined forcefully. 514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 228 515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End = 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::Force, 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("_end", 518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, // isDyn 519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 530affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool 53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::finalizeStandardSymbols(FragmentLinker& pLinker) 532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pPreInitArrayStart) { 540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pPreInitArrayStart->hasFragRef()) { 541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->setValue(0x0); 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pPreInitArrayEnd) { 547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pPreInitArrayEnd->hasFragRef()) { 548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() + 549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getPreInitArray().size()); 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(0x0); 554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pInitArrayStart) { 558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pInitArrayStart->hasFragRef()) { 559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->setValue(0x0); 561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pInitArrayEnd) { 565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pInitArrayEnd->hasFragRef()) { 566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() + 567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getInitArray().size()); 568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(0x0); 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pFiniArrayStart) { 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pFiniArrayStart->hasFragRef()) { 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->setValue(0x0); 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pFiniArrayEnd) { 583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pFiniArrayEnd->hasFragRef()) { 584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() + 585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getFiniArray().size()); 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(0x0); 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pStack) { 594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pStack->hasFragRef()) { 595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute); 596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->setValue(0x0); 597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 60022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pDynamic) { 60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local); 60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setValue(file_format->getDynamic().addr()); 60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setSize(file_format->getDynamic().size()); 60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 60522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pExecutableStart) { 608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* exec_start = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 0x0, 0x0); 609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != exec_start) { 610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) { 611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(f_pExecutableStart->value() + 612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang exec_start->vaddr()); 613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(0x0); 617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText || NULL != f_p_EText || NULL !=f_p__EText) { 620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* etext = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_X, 622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_W); 623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != etext) { 624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText && ResolveInfo::ThreadLocal != f_pEText->type()) { 625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText->setValue(f_pEText->value() + 626affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->vaddr() + 627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->memsz()); 628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EText && ResolveInfo::ThreadLocal != f_p_EText->type()) { 630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText->setValue(f_p_EText->value() + 631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->vaddr() + 632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->memsz()); 633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p__EText && ResolveInfo::ThreadLocal != f_p__EText->type()) { 635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText->setValue(f_p__EText->value() + 636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->vaddr() + 637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->memsz()); 638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText) 642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText->setValue(0x0); 643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EText) 644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText->setValue(0x0); 645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p__EText) 646affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText->setValue(0x0); 647affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData || NULL != f_p_EData || NULL != f_pBSSStart || 651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang NULL != f_pEnd || NULL != f_p_End) { 652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* edata = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_W, 654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != edata) { 656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) { 657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData->setValue(f_pEData->value() + 658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->filesz()); 660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) { 662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData->setValue(f_p_EData->value() + 663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->filesz()); 665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pBSSStart && ResolveInfo::ThreadLocal != f_pBSSStart->type()) { 667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart->setValue(f_pBSSStart->value() + 668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 669affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->filesz()); 670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) { 673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd->setValue(f_pEnd->value() + 674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 675affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->memsz()); 676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) { 678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End->setValue(f_p_End->value() + 679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 680affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->memsz()); 681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData) 685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData->setValue(0x0); 686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EData) 687affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData->setValue(0x0); 688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pBSSStart) 689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart->setValue(0x0); 690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEnd) 692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd->setValue(0x0); 693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_End) 694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End->setValue(0x0); 695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 70122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol) 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 70322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ignore if symbol has no fragRef 70422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSymbol.hasFragRef()) 70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 706affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 70722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the value of a TLS symbol is the offset to the TLS segment 70822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFSegment* tls_seg = m_ELFSegmentTable.find(llvm::ELF::PT_TLS, 70922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_R, 0x0); 71022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t value = pSymbol.fragRef()->getOutputOffset(); 71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t addr = pSymbol.fragRef()->frag()->getParent()->getSection().addr(); 71222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSymbol.setValue(value + addr - tls_seg->vaddr()); 71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 714affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 715affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFFileFormat* GNULDBackend::getOutputFormat() 717affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 71822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 71922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 72022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pDynObjFileFormat); 72122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 72222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 723d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pExecFileFormat); 72522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectFileFormat); 72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 729affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 731affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 734affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst ELFFileFormat* GNULDBackend::getOutputFormat() const 736affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 73922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pDynObjFileFormat); 74022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 74122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 742d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 74322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pExecFileFormat); 74422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 74522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 74622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectFileFormat); 74722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 748affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 74922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 751affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 752affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 753affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 75422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::partialScanRelocation(Relocation& pReloc, 75522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker, 75622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule, 75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& pSection) 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 75922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if we meet a section symbol 76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pReloc.symInfo()->type() == ResolveInfo::Section) { 76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* input_sym = pReloc.symInfo()->outSymbol(); 76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 76322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. update the relocation target offset 76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(input_sym->hasFragRef()); 76522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t offset = input_sym->fragRef()->getOutputOffset(); 76622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pReloc.target() += offset; 76722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. get output section symbol 76922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the output LDSection which the symbol defined in 77022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& out_sect = 77122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao input_sym->fragRef()->frag()->getParent()->getSection(); 77222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo* sym_info = pModule.getSectionSymbolSet().get(out_sect)->resolveInfo(); 77322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set relocation target symbol to the output section symbol's resolveInfo 77422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pReloc.setSymInfo(sym_info); 77522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools 7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab, 78022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab. 7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid 78222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::sizeNamePools(const Module& pModule, bool pIsStaticLink) 7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // number of entries in symbol tables starts from 1 to hold the special entry 7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21. 78622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t symtab = 1; 78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t dynsym = pIsStaticLink ? 0 : 1; 78822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size of string tables starts from 1 to hold the null character in their 79022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // first byte 7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtab = 1; 79222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t dynstr = pIsStaticLink ? 0 : 1; 79322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t shstrtab = 1; 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t hash = 0; 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 796d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // number of local symbol in the .dynsym 797d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao size_t dynsym_local_cnt = 0; 798d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// compute the size of .symtab, .dynsym and .strtab 80022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 80122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symbol; 80222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const Module::SymbolTable& symbols = pModule.getSymbolTable(); 80322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t str_size = 0; 80422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute the size of symbols in Local and File category 80522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symEnd = symbols.localEnd(); 80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) { 80722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao str_size = (*symbol)->nameSize() + 1; 80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink && isDynamicSymbol(**symbol)) { 80922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dynsym; 81022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 81122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += str_size; 81222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 81322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtab; 81422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 81522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab += str_size; 81622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 81722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute the size of symbols in TLS category 81822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = symbols.tlsEnd(); 81922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) { 82022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao str_size = (*symbol)->nameSize() + 1; 82122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink) { 8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++dynsym; 82322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 82422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += str_size; 8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtab; 82722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 82822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab += str_size; 82922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 830d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynsym_local_cnt = dynsym; 83122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute the size of the reset of symbols 83222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = pModule.sym_end(); 83322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) { 83422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao str_size = (*symbol)->nameSize() + 1; 83522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink && isDynamicSymbol(**symbol)) { 83622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dynsym; 83722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 83822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += str_size; 83922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 84022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtab; 84122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 84222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab += str_size; 8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 84522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 84722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch(config().codeGenType()) { 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // compute size of .dynstr and .hash 84922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 85022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // soname 85122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink) 85222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += pModule.name().size() + 1; 85322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 85422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /** fall through **/ 855d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 856d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr and .dynamic 8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Rules: 8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. ignore --no-add-needed 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. force count in --no-as-needed 8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 3. judge --as-needed 86222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink) { 86322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 86422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --add-needed 86622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*lib)->attribute()->isAddNeeded()) { 8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --no-as-needed 86822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!(*lib)->attribute()->isAsNeeded()) { 86922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += (*lib)->name().size() + 1; 8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().reserveNeedEntry(); 8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --as-needed 87322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*lib)->isNeeded()) { 87422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += (*lib)->name().size() + 1; 8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().reserveNeedEntry(); 8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 88022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute .hash 88122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Both Elf32_Word and Elf64_Word are 4 bytes 88222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hash = (2 + getHashBucketCount(dynsym, false) + dynsym) * 88322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sizeof(llvm::ELF::Elf32_Word); 88422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set size 887d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym)); 8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym)); 8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getDynStrTab().setSize(dynstr); 8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getHashTab().setSize(hash); 8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 894d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // set .dynsym sh_info to one greater than the symbol table 895d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // index of the last local symbol 896d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getDynSymTab().setInfo(dynsym_local_cnt); 8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /* fall through */ 89922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 900d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym)); 9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym)); 9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getStrTab().setSize(strtab); 905d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 906d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // set .symtab sh_info to one greater than the symbol table 907d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // index of the last local symbol 908d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getSymTab().setInfo(symbols.numOfLocals() + 1); 9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 91122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 91222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::fatal_illegal_codegen_type) << pModule.name(); 91322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end of switch 91522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @} 9165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 91722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// reserve fixed entries in the .dynamic section. 91822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 91922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 920d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Exec == config().codeGenType() || 921d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 9225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Because some entries in .dynamic section need information of .dynsym, 9235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED 9245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entries until we get the size of the sections mentioned above 92522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink) 926d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynamic().reserveEntries(*file_format); 9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getDynamic().setSize(dynamic().numOfBytes()); 9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @} 93022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 93122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// compute the size of .shstrtab section. 93222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 93322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_iterator sect, sectEnd = pModule.end(); 93422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sect = pModule.begin(); sect != sectEnd; ++sect) { 93522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // StackNote sections will always be in output! 93622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 != (*sect)->size() || LDFileFormat::StackNote == (*sect)->kind()) { 93722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shstrtab += ((*sect)->name().size() + 1); 93822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 93922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 94022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shstrtab += (strlen(".shstrtab") + 1); 94122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getShStrTab().setSize(shstrtab); 94222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @} 94322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 94422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 94522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol 94622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym, 94722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 94822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 94922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 95022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx) 95122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 95222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check the endian between host and target 95322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out symbol 95422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != pSymbol.type()) { 95522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = pStrtabsize; 95622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((pStrtab + pStrtabsize), pSymbol.name()); 95722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 95822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 95922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = 0; 96022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 96122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_value = pSymbol.value(); 96222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_size = getSymbolSize(pSymbol); 96322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_info = getSymbolInfo(pSymbol); 96422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_other = pSymbol.visibility(); 96522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_shndx = getSymbolShndx(pSymbol); 96622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 96722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 96822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol 96922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym, 97022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 97122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 97222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 97322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx) 97422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 97522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check the endian between host and target 97622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out symbol 97722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = pStrtabsize; 97822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_value = pSymbol.value(); 97922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_size = getSymbolSize(pSymbol); 98022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_info = getSymbolInfo(pSymbol); 98122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_other = pSymbol.visibility(); 98222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_shndx = getSymbolShndx(pSymbol); 98322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out string 98422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((pStrtab + pStrtabsize), pSymbol.name()); 9855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab 9885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 9895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 9905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 99122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule, 99222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryArea& pOutput) 9935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 99422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 9955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getSymTab(); 9975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getStrTab(); 9985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 99922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(), 100022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtab_sect.size()); 100122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(), 100222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab_sect.size()); 10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 1007d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 10085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 1009d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start(); 1011d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 1012d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 1013d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 1014d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 1015d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 10165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 10175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab[0] = '\0'; 10195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize the first ELF symbol 1021d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) { 10225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_name = 0; 10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_value = 0; 10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_size = 0; 10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_info = 0; 10265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_other = 0; 10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_shndx = 0; 10285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { // must 64 10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_name = 0; 10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_value = 0; 10325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_size = 0; 10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_info = 0; 10345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_other = 0; 10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_shndx = 0; 10365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 103822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool sym_exist = false; 103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao HashTableType::entry_type* entry = NULL; 104022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 104122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(NULL, sym_exist); 104222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(0); 104322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 104422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx = 1; 10465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 10475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // compute size of .symtab, .dynsym and .strtab 104822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symbol; 104922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symEnd = pModule.sym_end(); 105022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = pModule.sym_begin(); symbol != symEnd; ++symbol) { 105122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // maintain output's symbol and index map if building .o file 105222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 105322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 10545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(symtabIdx); 10555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1057d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 105822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 105922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 106022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 106122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize, 106222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 10635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 10655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 106622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 106722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 10685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 107122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 10725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 10735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 10745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 107522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitDynNamePools(const Module& pModule, 107622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryArea& pOutput) 10775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 107822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 107922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!file_format->hasDynSymTab() || 108022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynStrTab() || 108122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasHashTab() || 108222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynamic()) 108322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 10845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 10865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 10875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 10895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 10905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& hash_sect = file_format->getHashTab(); 10915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& dyn_sect = file_format->getDynamic(); 10925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 109322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(), 109422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtab_sect.size()); 109522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(), 109622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab_sect.size()); 109722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* hash_region = pOutput.request(hash_sect.offset(), 109822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hash_sect.size()); 109922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* dyn_region = pOutput.request(dyn_sect.offset(), 110022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyn_sect.size()); 11015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 11025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 11035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 1104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 11055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 1106d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 11075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start(); 1108d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 1109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 1110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 1111d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 11125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize the first ELF symbol 1114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) { 11155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_name = 0; 11165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_value = 0; 11175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_size = 0; 11185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_info = 0; 11195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_other = 0; 11205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_shndx = 0; 11215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 11225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { // must 64 11235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_name = 0; 11245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_value = 0; 11255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_size = 0; 11265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_info = 0; 11275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_other = 0; 11285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64[0].st_shndx = 0; 11295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 11305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 11315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 11325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab[0] = '\0'; 11335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add the first symbol into m_pSymIndexMap 11355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(NULL, sym_exist); 11365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(0); 11375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx = 1; 11395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 11405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit of .dynsym, and .dynstr 114222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symbol; 114322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const Module::SymbolTable& symbols = pModule.getSymbolTable(); 114422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit symbol in File and Local category if it's dynamic symbol 114522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symEnd = symbols.localEnd(); 114622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) { 114722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isDynamicSymbol(**symbol)) 11485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 11495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 115122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 115222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 115322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 115422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize, 115522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 115622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // maintain output's symbol and index map 11585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 11595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(symtabIdx); 116022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sum up counters 116122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtabIdx; 116222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 116322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 116422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 116622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit symbols in TLS category, all symbols in TLS category shold be emitited 116722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = symbols.tlsEnd(); 116822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) { 1169d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 117022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 117122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 117222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 117322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize, 117422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 117522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 117622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // maintain output's symbol and index map 117722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 117822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(symtabIdx); 117922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sum up counters 118022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtabIdx; 118122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 118222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 118322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 118422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 118522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit the reset of the symbols if the symbol is dynamic symbol 118622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = pModule.sym_end(); 118722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) { 118822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isDynamicSymbol(**symbol)) 118922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 119022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 119222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 119322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 119422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 119522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol64(symtab64[symtabIdx], **symbol, strtab, strtabsize, 119622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 11975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 119822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // maintain output's symbol and index map 119922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 120022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(symtabIdx); 12015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 12025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 120322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 120422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 12055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 12085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 12095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Rules: 12105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. ignore --no-add-needed 12115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. force count in --no-as-needed 12125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 3. judge --as-needed 12135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 121422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 121522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 121622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --add-needed 121722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*lib)->attribute()->isAddNeeded()) { 121822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --no-as-needed 121922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!(*lib)->attribute()->isAsNeeded()) { 122022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((strtab + strtabsize), (*lib)->name().c_str()); 122122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 122222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*lib)->name().size() + 1; 122322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dt_need; 122422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 122522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --as-needed 122622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*lib)->isNeeded()) { 122722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((strtab + strtabsize), (*lib)->name().c_str()); 122822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 122922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*lib)->name().size() + 1; 123022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dt_need; 12315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 123322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 123622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 123722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set pointer to SONAME entry in dynamic string table. 1238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dynamic().applySoname(strtabsize); 123922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1240d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynamic().applyEntries(*file_format); 12415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().emit(dyn_sect, *dyn_region); 12425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 124322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit soname 124422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 124522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((strtab + strtabsize), pModule.name().c_str()); 124622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += pModule.name().size() + 1; 124722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit hash table 12495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: this verion only emit SVR4 hash section. 12505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Please add GNU new hash section 12515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 12535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 12545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* word_array = (uint32_t*)hash_region->start(); 12555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 12565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nchain = word_array[1]; 12575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nbucket = getHashBucketCount(symtabIdx, false); 12595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nchain = symtabIdx; 12605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 12625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* chain = (bucket + nbucket); 12635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 12655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bzero((void*)bucket, nbucket); 12665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao StringHash<ELF> hash_func; 12685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1269d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) { 12705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) { 12715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef name(strtab + symtab32[sym_idx].st_name); 12725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t bucket_pos = hash_func(name) % nbucket; 12735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao chain[sym_idx] = bucket[bucket_pos]; 12745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bucket[bucket_pos] = sym_idx; 12755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1277d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) { 12785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) { 12795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef name(strtab + symtab64[sym_idx].st_name); 12805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t bucket_pos = hash_func(name) % nbucket; 12815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao chain[sym_idx] = bucket[bucket_pos]; 12825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bucket[bucket_pos] = sym_idx; 12835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 12865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section 128822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::sizeInterp() 1289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 1290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const char* dyld_name; 129122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 129222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 1293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 1294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dyld_name = dyld(); 1295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 129622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& interp = getOutputFormat()->getInterp(); 1297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang interp.setSize(std::strlen(dyld_name) + 1); 1298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp 130122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitInterp(MemoryArea& pOutput) 1302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 130322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasInterp()) { 130422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& interp = getOutputFormat()->getInterp(); 130522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion *region = pOutput.request(interp.offset(), interp.size()); 130622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* dyld_name; 130722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 130822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 130922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 131022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = dyld(); 1311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 131222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao std::memcpy(region->start(), dyld_name, interp.size()); 131322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 13165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder 131722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaounsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const 13185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 131922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 132022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // NULL section should be the "1st" section 13225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (LDFileFormat::Null == pSectHdr.kind()) 13235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 13245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 132522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getStrTab()) 132622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_STRTAB; 132722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if the section is not ALLOC, lay it out until the last possible moment 13295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC)) 13305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 13315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0; 13335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0; 13345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: need to take care other possible output sections 13355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pSectHdr.kind()) { 13365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Regular: 13375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (is_exec) { 13385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getInit()) 13395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_INIT; 13405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getFini()) 13415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_FINI; 13425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_TEXT; 13435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else if (!is_write) { 13445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RO; 13455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 134622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 134722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getPreInitArray() || 134822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getInitArray() || 134922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getFiniArray() || 1350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getCtors() || 1351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getDtors() || 1352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getJCR() || 1353d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao &pSectHdr == &file_format->getDataRelRo()) 1354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 1355d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (&pSectHdr == &file_format->getDataRelRoLocal()) 1356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO_LOCAL; 1357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 135822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) { 135922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_DATA; 136022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 13625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 13635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::BSS: 136522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) 136622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_BSS; 13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_BSS; 13685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 136922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::NamePool: { 13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getDynamic()) 13715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO; 13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NAMEPOOL; 137322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Relocation: 13755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getRelPlt() || 13765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &pSectHdr == &file_format->getRelaPlt()) 13775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_REL_PLT; 13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELOCATION; 13795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get the order from target for target specific sections 13815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Target: 138222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return getTargetSectionOrder(pSectHdr); 13835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // handle .interp 13855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Note: 13865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_INTERP; 13875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrame: 1389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrameHdr: 1390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::GCCExceptTable: 1391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_EXCEPTION; 13925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::MetaData: 13945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Debug: 13955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 13965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 13975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 13985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 13995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize 14015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const 14025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // @ref Google gold linker: symtab.cc: 2780 14045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // undefined and dynamic symbols should have zero size. 14055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined) 14065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 14075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.resolveInfo()->size(); 14085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo 14115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const 14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set binding 14145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t bind = 0x0; 14155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isLocal()) 14165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isGlobal()) 14185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isWeak()) 14205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_WEAK; 14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isAbsolute()) { 14225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // (Luba) Is a absolute but not global (weak or local) symbol meaningful? 14235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1426d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().codeGenType() != LinkerConfig::Object && 1427d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (pSymbol.visibility() == llvm::ELF::STV_INTERNAL || 1428d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pSymbol.visibility() == llvm::ELF::STV_HIDDEN)) 14295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t type = pSymbol.resolveInfo()->type(); 1432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change 1433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // its type to Function 1434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn()) 1435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang type = ResolveInfo::Function; 1436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (type | (bind << 4)); 14375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout() 14405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const 14415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn()) 14435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 14445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.value(); 14465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout() 14495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t 145022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const 14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isAbsolute()) 14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_ABS; 14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isCommon()) 14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_COMMON; 14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn()) 14575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_UNDEF; 14585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isLocal()) { 14605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pSymbol.type()) { 14615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case ResolveInfo::NoType: 14625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case ResolveInfo::File: 14635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_ABS; 14645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 146722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef()) 146822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return llvm::ELF::SHN_ABS; 146922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pSymbol.hasFragRef() && "symbols must have fragment reference to get its index"); 147122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return pSymbol.fragRef()->frag()->getParent()->getSection().index(); 14725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index 14755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::getSymbolIdx(LDSymbol* pSymbol) const 14765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::iterator entry = m_pSymIndexMap->find(pSymbol); 14785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return entry.getEntry()->value(); 14795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding 148222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage. 1483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @refer Google gold linker: common.cc: 214 1484affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool 148522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::allocateCommonSymbols(Module& pModule) 14865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 148722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymbolCategory& symbol_list = pModule.getSymbolTable(); 1488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 1490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 1491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 1493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: If the order of common symbols is defined, then sort common symbols 1495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // std::sort(com_sym, com_end, some kind of order); 1496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 149722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get corresponding BSS LDSection 149822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 149922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& bss_sect = file_format->getBSS(); 150022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& tbss_sect = file_format->getTBSS(); 1501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1502cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 150322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_sect_data = NULL; 150422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect.hasSectionData()) 150522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = bss_sect.getSectionData(); 150622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 150722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 150822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 150922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* tbss_sect_data = NULL; 151022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (tbss_sect.hasSectionData()) 151122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = tbss_sect.getSectionData(); 151222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 151322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 1514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 151622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t bss_offset = bss_sect.size(); 151722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tbss_offset = tbss_sect.size(); 1518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all local common symbols 1520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.localEnd(); 1521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 1523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::Common == (*com_sym)->desc()) { 1524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1530cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 153122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 153522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 153622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 153722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 154022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 154122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 154222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 15465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all global common symbols 1548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.commonEnd(); 1549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 1550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1556cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 155722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 156122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 156222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 156322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 156622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 156722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 156822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 157222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect.setSize(bss_offset); 157322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect.setSize(tbss_offset); 1574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang symbol_list.changeCommonsToGlobal(); 1575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 15765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 15775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers 158022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::createProgramHdrs(Module& pModule, 158122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const FragmentLinker& pLinker) 15825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 158322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat *file_format = getOutputFormat(); 1584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_PHDR 15865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_ELFSegmentTable.produce(llvm::ELF::PT_PHDR); 15875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_INTERP 1589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInterp()) { 15905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment* interp_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_INTERP); 1591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang interp_seg->addSection(&file_format->getInterp()); 1592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 159422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t cur_flag, prev_flag = getSegmentFlag(0); 15955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment* load_seg = NULL; 15965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make possible PT_LOAD segments 159722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator sect, sect_end = pModule.end(); 159822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sect = pModule.begin(); sect != sect_end; ++sect) { 1599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == ((*sect)->flag() & llvm::ELF::SHF_ALLOC) && 16015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::Null != (*sect)->kind()) 16025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 16035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 160422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_flag = getSegmentFlag((*sect)->flag()); 160522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool createPT_LOAD = false; 160622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Null == (*sect)->kind()) { 160722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. create text segment 160822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 160922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 161022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (!config().options().omagic() && 161122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) { 161222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. create data segment if w/o omagic set 161322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 161422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 161522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*sect)->kind() == LDFileFormat::BSS && 161622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->isDataSegment() && 161722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao config().scripts().addressMap().find(".bss") != 161822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (config().scripts().addressMap().end())) { 161922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. create bss segment if w/ -Tbss and there is a data segment 162022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 162122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 162222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 162322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*sect != &(file_format->getText())) && 162422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect != &(file_format->getData())) && 162522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect != &(file_format->getBSS())) && 162622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (config().scripts().addressMap().find((*sect)->name()) != 162722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao config().scripts().addressMap().end())) 162822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 4. create PT_LOAD for sections in address map except for text, data, 162922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // and bss 163022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 163122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 16325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 163322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (createPT_LOAD) { 163422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create new PT_LOAD segment 163522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_LOAD, cur_flag); 163622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->setAlign(abiPageSize()); 16375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 16385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != load_seg); 1640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang load_seg->addSection((*sect)); 164122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cur_flag != prev_flag) 164222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->updateFlag(cur_flag); 16435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 164422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao prev_flag = cur_flag; 16455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 16465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_DYNAMIC 1648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasDynamic()) { 1649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* dyn_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_DYNAMIC, 1650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_R | 1651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_W); 1652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dyn_seg->addSection(&file_format->getDynamic()); 1653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 165522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 1656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_RELRO 1657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* relro_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_RELRO); 165822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 165922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) { 166022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::PT_LOAD != (*seg).type()) 166122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 166222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 166322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegment::sect_iterator sect = (*seg).begin(), 166422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sectEnd = (*seg).end(); sect != sectEnd; ++sect) { 166522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao unsigned int order = getSectionOrder(**sect); 166622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (SHO_RELRO_LOCAL == order || 166722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SHO_RELRO == order || 166822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SHO_RELRO_LAST == order) { 166922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relro_seg->addSection(*sect); 167022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 16735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 16745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1675affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_EH_FRAME 1676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasEhFrameHdr()) { 1677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* eh_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_EH_FRAME); 1678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang eh_seg->addSection(&file_format->getEhFrameHdr()); 1679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 168022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 168122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_TLS 168222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData() || file_format->hasTBSS()) { 168322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFSegment* tls_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_TLS); 168422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData()) 168522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tls_seg->addSection(&file_format->getTData()); 168622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTBSS()) 168722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tls_seg->addSection(&file_format->getTBSS()); 168822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 168922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 169022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_GNU_STACK 169122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasStackNote()) { 169222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_STACK, 169322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_R | 169422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_W | 169522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getSegmentFlag(file_format->getStackNote().flag())); 169622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 169722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 169822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create target dependent segments 169922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao doCreateProgramHdrs(pModule, pLinker); 1700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments 170322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupProgramHdrs(const FragmentLinker& pLinker) 1704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 17055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // update segment info 17065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegmentFactory::iterator seg, seg_end = m_ELFSegmentTable.end(); 17075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (seg = m_ELFSegmentTable.begin(); seg != seg_end; ++seg) { 17085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment& segment = *seg; 17095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // update PT_PHDR 17115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::PT_PHDR == segment.type()) { 17125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t offset, phdr_size; 1713d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) { 17145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf32_Ehdr); 17155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf32_Phdr); 17165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 17185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf64_Ehdr); 17195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf64_Phdr); 17205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setOffset(offset); 172222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segment.setVaddr(segmentStartAddr(pLinker) + offset); 17235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setPaddr(segment.vaddr()); 17245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setFilesz(numOfSegments() * phdr_size); 17255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setMemsz(numOfSegments() * phdr_size); 1726d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao segment.setAlign(config().targets().bitclass() / 8); 17275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 17285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1730affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // bypass if there is no section in this segment (e.g., PT_GNU_STACK) 1731affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (segment.numOfSections() == 0) 1732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang continue; 1733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 173422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segment.setOffset(segment.front()->offset()); 1735affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (llvm::ELF::PT_LOAD == segment.type() && 173622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Null == segment.front()->kind()) 173722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segment.setVaddr(segmentStartAddr(pLinker)); 1738affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 173922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segment.setVaddr(segment.front()->addr()); 17405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setPaddr(segment.vaddr()); 17415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 174222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* last_sect = segment.back(); 17435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != last_sect); 1744affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t file_size = last_sect->offset() - segment.offset(); 17455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (LDFileFormat::BSS != last_sect->kind()) 17465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_size += last_sect->size(); 17475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setFilesz(file_size); 17485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setMemsz(last_sect->addr() - segment.vaddr() + last_sect->size()); 17505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 17525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output 1754affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: layout.cc:2608 175522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupGNUStackInfo(Module& pModule, FragmentLinker& pLinker) 17565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1757affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t flag = 0x0; 175822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasStackSet()) { 1759affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 1. check the command line option (-z execstack or -z noexecstack) 176022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasExecStack()) 1761affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 176222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 176322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 1764affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. check the stack info from the input objects 176522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: since we alway emit .note.GNU-stack in output now, we may be able 176622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to check this from the output .note.GNU-stack directly after section 176722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // merging is done 1768affc150dc44fab1911775a49636d0ce85333b634Zonr Chang size_t object_count = 0, stack_note_count = 0; 176922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_obj_iterator obj, objEnd = pModule.obj_end(); 177022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (obj = pModule.obj_begin(); obj != objEnd; ++obj) { 177122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++object_count; 177222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack"); 177322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != sect) { 177422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++stack_note_count; 177522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2.1 found a stack note that is set as executable 177622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) { 177722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao flag = llvm::ELF::SHF_EXECINSTR; 177822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 1779affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1780affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1781affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 17825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1783affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.2 there are no stack note sections in all input objects 1784affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == stack_note_count) 1785affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 17865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1787affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.3 a special case. Use the target default to decide if the stack should 1788affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // be executable 1789affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count) 1790affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isDefaultExecStack()) 1791affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 17925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 179422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasStackNote()) { 179522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getOutputFormat()->getStackNote().setFlag(flag); 179622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 179722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 179822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 179922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupRelro - setup the offset constraint of PT_RELRO 180022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupRelro(Module& pModule) 180122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 180222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(config().options().hasRelro()); 180322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if -z relro is given, we need to adjust sections' offset again, and let 180422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // PT_GNU_RELRO end on a common page boundary 180522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 180622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator sect = pModule.begin(); 180722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (Module::iterator sect_end = pModule.end(); sect != sect_end; ++sect) { 180822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // find the first non-relro section 180922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getSectionOrder(**sect) > SHO_RELRO_LAST) 181022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 181122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 181222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 181322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // align the first non-relro section to page boundary 181422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t offset = (*sect)->offset(); 181522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao alignAddress(offset, commonPageSize()); 181622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect)->setOffset(offset); 181722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 181822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // It seems that compiler think .got and .got.plt are continuous (w/o any 181922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // padding between). If .got is the last section in PT_RELRO and it's not 182022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // continuous to its next section (i.e. .got.plt), we need to add padding 182122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // in front of .got instead. 182222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: Maybe we can handle this in a more general way. 182322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = getOutputFormat()->getGOT(); 182422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((getSectionOrder(got) == SHO_RELRO_LAST) && 182522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (got.offset() + got.size() != offset)) { 182622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao got.setOffset(offset - got.size()); 182722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 182822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 182922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up remaining section's offset 183022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setOutputSectionOffset(pModule, ++sect, pModule.end()); 183122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 183222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 183322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set a group of output sections' 183422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// offset, and set pSectBegin to pStartOffset if pStartOffset is not -1U. 183522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setOutputSectionOffset(Module& pModule, 183622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectBegin, 183722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectEnd, 183822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t pStartOffset) 183922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 184022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSectBegin == pModule.end()) 184122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 184222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 184322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pSectEnd == pModule.end() || 184422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (pSectEnd != pModule.end() && 184522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*pSectBegin)->index() <= (*pSectEnd)->index())); 184622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 184722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pStartOffset != -1U) { 184822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*pSectBegin)->setOffset(pStartOffset); 184922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++pSectBegin; 185022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 185122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 185222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up the "cur" and "prev" iterator 185322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator cur = pSectBegin; 185422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator prev = pSectBegin; 185522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cur != pModule.begin()) 185622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao --prev; 1857affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 185822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++cur; 185922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 186022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (; cur != pSectEnd; ++cur, ++prev) { 186122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t offset = 0x0; 186222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch ((*prev)->kind()) { 186322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Null: 186422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset = sectionStartOffset(); 186522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 186622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::BSS: 186722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset = (*prev)->offset(); 186822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 186922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 187022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset = (*prev)->offset() + (*prev)->size(); 187122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 187222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 187322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 187422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao alignAddress(offset, (*cur)->align()); 187522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*cur)->setOffset(offset); 187622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 187722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 187822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 187922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set output sections' address 188022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setOutputSectionAddress(FragmentLinker& pLinker, 188122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule, 188222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectBegin, 188322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectEnd) 188422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 188522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSectBegin == pModule.end()) 188622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 188722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 188822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pSectEnd == pModule.end() || 188922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (pSectEnd != pModule.end() && 189022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*pSectBegin)->index() <= (*pSectEnd)->index())); 189122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 189222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 189322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segEnd = elfSegmentTable().end(), prev = elfSegmentTable().end(); 189422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao seg != segEnd; prev = seg, ++seg) { 189522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::PT_LOAD != (*seg).type()) 189622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 189722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 189822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t start_addr = 0x0; 189922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ScriptOptions::AddressMap::const_iterator mapping; 190022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*seg).front()->kind() == LDFileFormat::Null) 190122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mapping = config().scripts().addressMap().find(".text"); 190222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*seg).isDataSegment()) 190322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mapping = config().scripts().addressMap().find(".data"); 190422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*seg).isBssSegment()) 190522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mapping = config().scripts().addressMap().find(".bss"); 190622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 190722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mapping = config().scripts().addressMap().find((*seg).front()->name()); 190822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 190922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (mapping != config().scripts().addressMap().end()) { 191022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // check address mapping 191122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_addr = mapping.getEntry()->value(); 1912d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if ((*seg).front()->kind() != LDFileFormat::Null) { 1913d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const uint64_t remainder = start_addr % abiPageSize(); 1914d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (remainder != (*seg).front()->offset() % abiPageSize()) { 1915d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao uint64_t padding = abiPageSize() + remainder - 1916d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*seg).front()->offset() % abiPageSize(); 1917d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao setOutputSectionOffset(pModule, 1918d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.begin() + (*seg).front()->index(), 1919d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.end(), 1920d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*seg).front()->offset() + padding); 1921d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().options().hasRelro()) 1922d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao setupRelro(pModule); 1923d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 192422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 192522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 192622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 192722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*seg).front()->kind() == LDFileFormat::Null) { 192822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1st PT_LOAD 192922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_addr = segmentStartAddr(pLinker); 193022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 193122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*prev).front()->kind() == LDFileFormat::Null) { 193222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // prev segment is 1st PT_LOAD 193322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_addr = segmentStartAddr(pLinker) + (*seg).front()->offset(); 193422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 193522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 193622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Others 193722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_addr = (*prev).front()->addr() + (*seg).front()->offset(); 193822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 193922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 194022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // padding 194122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (((*seg).front()->offset() & (abiPageSize() - 1)) != 0) 194222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_addr += abiPageSize(); 194322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 194422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 194522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegment::sect_iterator sect = (*seg).begin(), 194622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sectEnd = (*seg).end(); sect != sectEnd; ++sect) { 194722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*sect)->index() < (*pSectBegin)->index()) 194822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 194922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 195022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Null == (*sect)->kind()) 195122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 195222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 195322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sect == pSectEnd) 195422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 195522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 195622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sect != (*seg).begin()) 195722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect)->setAddr(start_addr + (*sect)->offset() - 195822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*seg).front()->offset()); 195922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 196022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect)->setAddr(start_addr); 196122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 196222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 19635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 19645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1965d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// layout - layout method 1966d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid GNULDBackend::layout(Module& pModule, FragmentLinker& pLinker) 1967d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 1968d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::vector<SHOEntry> output_list; 1969d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1. determine what sections will go into final output, and push the needed 1970d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // sections into output_list for later processing 1971d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie; 1972d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ++it) { 1973d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch ((*it)->kind()) { 1974d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // take NULL and StackNote directly 1975d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Null: 1976d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::StackNote: 1977d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 1978d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao break; 1979d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // ignore if section size is 0 1980d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Regular: 1981d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Target: 1982d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::MetaData: 1983d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::BSS: 1984d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Debug: 1985d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::EhFrame: 1986d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::GCCExceptTable: 1987d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::NamePool: 1988d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Relocation: 1989d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Note: 1990d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::EhFrameHdr: 1991d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (0 != (*it)->size()) { 1992d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 1993d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 1994d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao break; 1995d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Group: 1996d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 1997d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao //TODO: support incremental linking 1998d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ; 1999d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2000d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao break; 2001d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Version: 2002d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (0 != (*it)->size()) { 2003d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 2004d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name(); 2005d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2006d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao break; 2007d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao default: 2008d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (0 != (*it)->size()) { 2009d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao error(diag::err_unsupported_section) << (*it)->name() << (*it)->kind(); 2010d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2011d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao break; 2012d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2013d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } // end of for 2014d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2015d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 2. sort output section orders 2016d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::stable_sort(output_list.begin(), output_list.end(), SHOCompare()); 2017d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2018d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 3. update output sections in Module 2019d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.getSectionTable().clear(); 2020d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao for(size_t index = 0; index < output_list.size(); ++index) { 2021d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (output_list[index].first)->setIndex(index); 2022d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.getSectionTable().push_back(output_list[index].first); 2023d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2024d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2025d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 4. create program headers 2026d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 2027d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao createProgramHdrs(pModule, pLinker); 2028d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2029d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2030d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 5. set output section offset 2031d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao setOutputSectionOffset(pModule, pModule.begin(), pModule.end(), 0x0); 2032d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 2033d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 20345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// preLayout - Backend can do any needed modification before layout 203522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::preLayout(Module& pModule, FragmentLinker& pLinker) 20365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 20375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // prelayout target first 203822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao doPreLayout(pLinker); 2039affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 204022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2041affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // init EhFrameHdr and size the output section 204222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* format = getOutputFormat(); 204322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEhFrameHdr = new EhFrameHdr(format->getEhFrameHdr(), 204422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao format->getEhFrame()); 2045affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pEhFrameHdr->sizeOutput(); 2046affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 204722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 204822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // change .tbss and .tdata section symbol from Local to TLS category 204922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pTDATA) 205022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule.getSymbolTable().changeLocalToTLS(*f_pTDATA); 205122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 205222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pTBSS) 205322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule.getSymbolTable().changeLocalToTLS(*f_pTBSS); 205422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 205522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // To merge input's relocation sections into output's relocation sections. 205622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 205722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are generating relocatables (-r), move input relocation sections 205822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to corresponding output relocation sections. 205922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 206022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = pModule.obj_end(); 206122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = pModule.obj_begin(); input != inEnd; ++input) { 206222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 206322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 206422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 206522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the output relocation LDSection with identical name. 206622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_sect = pModule.getSection((*rs)->name()); 206722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == output_sect) { 206822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect = LDSection::Create((*rs)->name(), 206922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->kind(), 207022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->type(), 207122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->flag()); 207222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 207322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setAlign((*rs)->align()); 207422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule.getSectionTable().push_back(output_sect); 207522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 207622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 207722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set output relocation section link 207822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* input_link = (*rs)->getLink(); 207922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != input_link && "Illegal input relocation section."); 208022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 208122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the linked output section 208222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_link = pModule.getSection(input_link->name()); 208322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != output_link); 208422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 208522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setLink(output_link); 208622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 208722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get output relcoationData, create one if not exist 208822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!output_sect->hasRelocData()) 208922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao IRBuilder::CreateRelocData(*output_sect); 209022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 209122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData* out_reloc_data = output_sect->getRelocData(); 209222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 209322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // move relocations from input's to output's RelcoationData 2094d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& out_list = 2095d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao out_reloc_data->getRelocationList(); 2096d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& in_list = 2097d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*rs)->getRelocData()->getRelocationList(); 209822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao out_list.splice(out_list.end(), in_list); 209922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 210022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size output 210122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::SHT_REL == output_sect->type()) 210222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelEntrySize()); 210322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (llvm::ELF::SHT_RELA == output_sect->type()) 210422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelaEntrySize()); 210522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 210622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unknown_reloc_section_type) << output_sect->type() 210722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << output_sect->name(); 210822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 210922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for each relocation section 211022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for each input 211122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of if 211222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 211322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up the section flag of .note.GNU-stack section 211422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setupGNUStackInfo(pModule, pLinker); 21155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 21165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2117cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout 211822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::postLayout(Module& pModule, 211922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker) 21205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1. set up section address and segment attributes 212222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 212322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 2124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.1 set up the offset constraint of PT_RELRO 212522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setupRelro(pModule); 212622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 212722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2128d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.2 set up the output sections' address 212922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setOutputSectionAddress(pLinker, pModule, pModule.begin(), pModule.end()); 213022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.3 do relaxation 213222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relax(pModule, pLinker); 2133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.4 set up the attributes of program headers 213522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setupProgramHdrs(pLinker); 2136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. target specific post layout 213922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao doPostLayout(pModule, pLinker); 21405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 21415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 214222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::postProcessing(FragmentLinker& pLinker, MemoryArea& pOutput) 2143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 214422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // emit eh_frame_hdr 2146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 214722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEhFrameHdr->emitOutput<32>(pOutput); 2148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 21515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count. 21525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker, dynobj.cc:791 21535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols, 21545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool pIsGNUStyle) 21555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 21565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // @ref Google gold, dynobj.cc:loc 791 21575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static const unsigned int buckets[] = 21585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 21595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, 21605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16411, 32771, 65537, 131101, 262147 21615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao }; 21625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const unsigned buckets_count = sizeof buckets / sizeof buckets[0]; 21635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int result = 1; 21655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (unsigned i = 0; i < buckets_count; ++i) { 21665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pNumOfSymbols < buckets[i]) 21675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 21685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = buckets[i]; 21695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 21705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pIsGNUStyle && result < 2) 21725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = 2; 21735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 21755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 21765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol 21785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker: symtab.cc:311 217922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol) 21805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 21815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 21825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol. We should not add it 21835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.binding() == ResolveInfo::Local) 21845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 21855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we are building shared object, and the visibility is external, we 21875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // need to add it. 218822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 2189d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Exec == config().codeGenType() || 2190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 21915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default || 2192d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected || 2193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pSymbol.resolveInfo()->type() == ResolveInfo::ThreadLocal) { 21945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 219522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 219622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 219722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 219822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 219922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 220022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol 220122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker: symtab.cc:311 220222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo) 220322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 220422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 220522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol. We should not add it 220622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.binding() == ResolveInfo::Local) 220722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 220822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 220922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are building shared object, and the visibility is external, we 221022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // need to add it. 221122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 2212d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Exec == config().codeGenType() || 2213d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 221422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.visibility() == ResolveInfo::Default || 2215d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pResolveInfo.visibility() == ResolveInfo::Protected || 2216d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pResolveInfo.type() == ResolveInfo::ThreadLocal) { 221722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 221822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 221922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine. 2224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:135 222522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::commonPageSize() const 2226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 222722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().commPageSize() > 0) 222822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return std::min(config().options().commPageSize(), abiPageSize()); 2229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 223022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return std::min(static_cast<uint64_t>(0x1000), abiPageSize()); 2231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine. 2234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:125 223522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::abiPageSize() const 2236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 223722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().maxPageSize() > 0) 223822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return config().options().maxPageSize(); 2239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 2240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return static_cast<uint64_t>(0x1000); 2241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other 2244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit 2245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:551 224622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const 2247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 2248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.other() != ResolveInfo::Default) 2249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 225122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This is because the codeGenType of pie is DynObj. And gold linker check 225222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the "shared" option instead. 225322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 225422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 225522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 225622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj != config().codeGenType()) 225722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 225822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 225922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().Bsymbolic()) 2260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 226222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // A local defined symbol should be non-preemptible. 226322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32 226422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relocation refers to a local defined symbol, and we should generate a 226522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relative dynamic relocation when applying the relocation. 226622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local) 2267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 227222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation 227322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, symtab.h:645 227422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolNeedsDynRel(const FragmentLinker& pLinker, 227522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo& pSym, 227622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool pSymHasPLT, 227722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isAbsReloc) const 227822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 227922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // an undefined reference in the executables should be statically 228022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // resolved to 0 and no need a dynamic relocation 228122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isUndef() && 228222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !pSym.isDyn() && 2283d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::Exec == config().codeGenType() || 2284d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType())) 228522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 228622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 228722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isAbsolute()) 228822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 228922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pLinker.isOutputPIC() && isAbsReloc) 229022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 229122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymHasPLT && ResolveInfo::Function == pSym.type()) 229222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 229322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pLinker.isOutputPIC() && pSymHasPLT) 229422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 229522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDyn() || pSym.isUndef() || 229622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isSymbolPreemptible(pSym)) 229722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 229822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 229922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 230022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 230122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry 2303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:596 230422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolNeedsPLT(const FragmentLinker& pLinker, 230522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo& pSym) const 2306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 230722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isUndef() && 230822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !pSym.isDyn() && 230922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkerConfig::DynObj != config().codeGenType()) 2310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry 2313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() == ResolveInfo::IndirectFunc) 2314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() != ResolveInfo::Function) 2317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 231922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pLinker.isStaticLink() && !pLinker.isOutputPIC()) 232022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 232122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 232222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 2323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (pSym.isDyn() || 2326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.isUndef() || 232722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isSymbolPreemptible(pSym)); 2328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 233022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at 233122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time 233222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, Symbol::final_value_is_known 233322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolFinalValueIsKnown(const FragmentLinker& pLinker, 233422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo& pSym) const 2335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 233622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the output is pic code or if not executables, symbols' value may change 233722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // at runtime 2338d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pLinker.isOutputPIC() || 2339d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::Exec != config().codeGenType() && 2340d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary != config().codeGenType())) 2341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 234222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 234322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is from dynamic object, then its value is unknown 234422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDyn()) 2345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 234622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 234722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is not in dynamic object and is not undefined, then its value 234822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is known 234922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSym.isUndef()) 2350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 235222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is undefined and not in dynamic objects, for example, a weak 235322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // undefined symbol, then whether the symbol's final value can be known 235422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // depends on whrther we're doing static link 235522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return pLinker.isStaticLink(); 2356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation 235922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::symbolNeedsCopyReloc(const FragmentLinker& pLinker, 2360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Relocation& pReloc, 236122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo& pSym) const 2362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 2363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // only the reference from dynamic executable to non-function symbol in 2364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // the dynamic objects may need copy relocation 236522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pLinker.isOutputPIC() || 2366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang !pSym.isDyn() || 2367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.type() == ResolveInfo::Function || 2368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.size() == 0) 2369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // check if the option -z nocopyreloc is given 237222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNoCopyReloc()) 2373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // TODO: Is this check necessary? 2376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if relocation target place is readonly, a copy relocation is needed 237722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag(); 237822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE)) 2379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 23805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 23825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 238422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTDATASymbol() 238522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 238622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTDATA); 238722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 238822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 238922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 239022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTDATASymbol() const 239122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 239222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTDATA); 239322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 239422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 239522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 239622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTBSSSymbol() 239722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 239822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTBSS); 239922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 240022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 240122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 240222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTBSSSymbol() const 240322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 240422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTBSS); 240522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 240622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 240722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 240822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection) 240922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 241022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_bHasTextRel) 241122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 241222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 241322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the target section of the dynamic relocation is ALLOCATE but is not 241422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // writable, than we should set DF_TEXTREL 241522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const uint32_t flag = pSection.flag(); 241622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC)) 241722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasTextRel = true; 241822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 241922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 242022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 242122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 242222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation 242322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initBRIslandFactory() 242422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 242522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pBRIslandFactory) { 242622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pBRIslandFactory = new BranchIslandFactory(maxBranchOffset()); 242722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 242822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 242922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 243022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 243122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation 243222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStubFactory() 243322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 243422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pStubFactory) { 243522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pStubFactory = new StubFactory(); 243622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 243722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 243822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 243922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 244022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::relax(Module& pModule, FragmentLinker& pLinker) 244122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 244222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!mayRelax()) 244322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 244422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 244522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool finished = true; 244622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao do { 244722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (doRelax(pModule, pLinker, finished)) { 244822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the sections (e.g., .text) are relaxed, the layout is also changed 244922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // We need to do the following: 245022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 245122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. set up the offset 245222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setOutputSectionOffset(pModule, pModule.begin(), pModule.end()); 245322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 245422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. set up the offset constraint of PT_RELRO 245522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) 245622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setupRelro(pModule); 245722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 245822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. set up the output sections' address 245922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setOutputSectionAddress(pLinker, pModule, pModule.begin(), pModule.end()); 246022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 246122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } while (!finished); 246222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 246322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 246422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 246522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2466