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> 166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <map> 17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h> 22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Config/Config.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h> 24cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/LDSymbol.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h> 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h> 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrameHdr.h> 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h> 30d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.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 40f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace { 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===--------------------------------------------------------------------===// 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesstatic const std::string simple_c_identifier_allowed_chars = 46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "0123456789" 47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "ABCDEFGHIJKLMNOPWRSTUVWXYZ" 48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "abcdefghijklmnopqrstuvwxyz" 49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "_"; 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatic bool isCIdentifier(const std::string& pName) 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return (pName.find_first_not_of(simple_c_identifier_allowed_chars) 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines == std::string::npos); 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} // anonymous namespace 59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesusing namespace mcld; 61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend 64cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : TargetLDBackend(pConfig), 67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pObjectReader(NULL), 68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pDynObjFileFormat(NULL), 69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pExecFileFormat(NULL), 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectFileFormat(NULL), 71d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pInfo(pInfo), 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_ELFSegmentTable(9), // magic number 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pBRIslandFactory(NULL), 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pStubFactory(NULL), 75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pEhFrameHdr(NULL), 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasTextRel(false), 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasStaticTLS(false), 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart(NULL), 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd(NULL), 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart(NULL), 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd(NULL), 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart(NULL), 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd(NULL), 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack(NULL), 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic(NULL), 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTDATA(NULL), 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTBSS(NULL), 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart(NULL), 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText(NULL), 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText(NULL), 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText(NULL), 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData(NULL), 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData(NULL), 94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart(NULL), 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd(NULL), 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End(NULL) { 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymIndexMap = new HashTableType(1024); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::~GNULDBackend() 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pInfo; 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynObjFileFormat; 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pExecFileFormat; 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pObjectFileFormat; 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pSymIndexMap; 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pEhFrameHdr; 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pBRIslandFactory; 1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pStubFactory; 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::sectionStartOffset() const 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Binary == config().codeGenType()) 115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0x0; 116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch (config().targets().bitclass()) { 118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 32u: 119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf32_Ehdr) + 120d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao numOfSegments() * sizeof(llvm::ELF::Elf32_Phdr); 121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 64u: 122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf64_Ehdr) + 123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao numOfSegments() * sizeof(llvm::ELF::Elf64_Phdr); 124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao default: 125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 127d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0; 128d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesuint64_t GNULDBackend::getSegmentStartAddr(const LinkerScript& pScript) const 132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::AddressMap::const_iterator mapping = 134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pScript.addressMap().find(".text"); 135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pScript.addressMap().end() != mapping) 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return mapping.getEntry()->value(); 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (config().isCodeIndep()) 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return 0x0; 139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pInfo->defaultTextSegmentAddr(); 141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader* 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::createArchiveReader(Module& pModule) 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectReader); 14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return new GNUArchiveReader(pModule, *m_pObjectReader); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder) 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 152d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectReader = new ELFObjectReader(*this, pBuilder, config()); 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectReader; 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder) 157d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 158d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFDynObjReader(*this, pBuilder, config()); 159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 160d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 161d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder) 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 163d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFBinaryReader(*this, pBuilder, config()); 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter* GNULDBackend::createWriter() 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 168d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFObjectWriter(*this, config()); 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStdSections(ObjectBuilder& pBuilder) 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pDynObjFileFormat) 17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pDynObjFileFormat = new ELFDynObjFileFormat(); 177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pDynObjFileFormat->initStdSections(pBuilder, 178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 181d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 182d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pExecFileFormat) 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pExecFileFormat = new ELFExecFileFormat(); 185d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pExecFileFormat->initStdSections(pBuilder, 186d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pObjectFileFormat) 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectFileFormat = new ELFObjectFileFormat(); 192d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectFileFormat->initStdSections(pBuilder, 193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols. 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations. 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::initStandardSymbols(IRBuilder& pBuilder, 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule) 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // GNU extension: define __start and __stop symbols for the sections whose 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // name can be presented as C symbol 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ref: GNU gold, Layout::define_section_symbols 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator iter, iterEnd = pModule.end(); 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iter = pModule.begin(); iter != iterEnd; ++iter) { 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* section = *iter; 21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (section->kind()) { 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasEhFrame()) 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasSectionData()) 22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of switch 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isCIdentifier(section->name())) { 231f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::string start_name = "__start_" + section->name(); 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* start_fragref = FragmentRef::Create( 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->getSectionData()->front(), 0x0); 2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines start_name, 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::NoType, 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Global, 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_fragref, // FragRef 24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Default); 24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 244f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::string stop_name = "__stop_" + section->name(); 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* stop_fragref = FragmentRef::Create( 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->getSectionData()->front(), section->size()); 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines stop_name, 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::NoType, 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Global, 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stop_fragref, // FragRef 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Default); 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .preinit_array 263cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* preinit_array = NULL; 264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasPreInitArray()) { 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Create( 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getPreInitArray().getSectionData()->front(), 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Null(); 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart = 2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__preinit_array_start", 275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang preinit_array, // FragRef 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd = 2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__preinit_array_end", 285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .init_array 294cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* init_array = NULL; 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInitArray()) { 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Create( 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getInitArray().getSectionData()->front(), 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Null(); 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart = 3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__init_array_start", 307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang init_array, // FragRef 313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd = 3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__init_array_end", 317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang init_array, // FragRef 323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .fini_array 326cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* fini_array = NULL; 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasFiniArray()) { 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Create( 32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getFiniArray().getSectionData()->front(), 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Null(); 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart = 3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__fini_array_start", 339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fini_array, // FragRef 345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd = 3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__fini_array_end", 349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fini_array, // FragRef 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .stack 358cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* stack = NULL; 359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasStack()) { 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Create( 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getStack().getSectionData()->front(), 362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Null(); 36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack = 3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__stack", 371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang stack, // FragRef 377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // _DYNAMIC 38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: add SectionData for .dynamic section, and then we can get the correct 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol section index for _DYNAMIC. Now it will be ABS. 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic = 3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_DYNAMIC", 38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Object, 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Local, 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Hidden); 39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart = 3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__executable_start", 397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 400affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 401affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 404affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText = 4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "etext", 407affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 408affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 409affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 410affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 411affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText = 4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_etext", 417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 418affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 419affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 420affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText = 4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__etext", 427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData = 4356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "edata", 437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 440affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd = 4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "end", 448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _edata is defined forcefully. 457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 186 458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData = 4596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_edata", 461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // __bss_start is defined forcefully. 470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 214 471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart = 4726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 4736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__bss_start", 474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _end is defined forcefully. 483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 228 484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End = 4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 4866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_end", 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::finalizeStandardSymbols() 499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pPreInitArrayStart) { 507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pPreInitArrayStart->hasFragRef()) { 508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->setValue(0x0); 510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pPreInitArrayEnd) { 514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pPreInitArrayEnd->hasFragRef()) { 515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() + 516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getPreInitArray().size()); 517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(0x0); 521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pInitArrayStart) { 525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pInitArrayStart->hasFragRef()) { 526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->setValue(0x0); 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pInitArrayEnd) { 532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pInitArrayEnd->hasFragRef()) { 533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() + 534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getInitArray().size()); 535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(0x0); 539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pFiniArrayStart) { 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pFiniArrayStart->hasFragRef()) { 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->setValue(0x0); 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pFiniArrayEnd) { 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pFiniArrayEnd->hasFragRef()) { 551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() + 552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getFiniArray().size()); 553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(0x0); 557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pStack) { 561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pStack->hasFragRef()) { 562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute); 563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->setValue(0x0); 564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pDynamic) { 56822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local); 56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setValue(file_format->getDynamic().addr()); 57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setSize(file_format->getDynamic().size()); 57122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pExecutableStart) { 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* exec_start = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 0x0, 0x0); 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != exec_start) { 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) { 578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(f_pExecutableStart->value() + 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang exec_start->vaddr()); 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(0x0); 584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText || NULL != f_p_EText || NULL !=f_p__EText) { 587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* etext = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_X, 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_W); 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != etext) { 591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText && ResolveInfo::ThreadLocal != f_pEText->type()) { 592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText->setValue(f_pEText->value() + 593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->vaddr() + 594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->memsz()); 595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EText && ResolveInfo::ThreadLocal != f_p_EText->type()) { 597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText->setValue(f_p_EText->value() + 598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->vaddr() + 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->memsz()); 600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p__EText && ResolveInfo::ThreadLocal != f_p__EText->type()) { 602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText->setValue(f_p__EText->value() + 603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->vaddr() + 604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang etext->memsz()); 605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText) 609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText->setValue(0x0); 610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EText) 611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText->setValue(0x0); 612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p__EText) 613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText->setValue(0x0); 614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData || NULL != f_p_EData || NULL != f_pBSSStart || 618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang NULL != f_pEnd || NULL != f_p_End) { 619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* edata = m_ELFSegmentTable.find(llvm::ELF::PT_LOAD, 620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_W, 621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != edata) { 623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) { 624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData->setValue(f_pEData->value() + 625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 626affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->filesz()); 627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) { 629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData->setValue(f_p_EData->value() + 630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->filesz()); 632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pBSSStart && ResolveInfo::ThreadLocal != f_pBSSStart->type()) { 634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart->setValue(f_pBSSStart->value() + 635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->filesz()); 637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) { 640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd->setValue(f_pEnd->value() + 641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->memsz()); 643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) { 645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End->setValue(f_p_End->value() + 646affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->vaddr() + 647affc150dc44fab1911775a49636d0ce85333b634Zonr Chang edata->memsz()); 648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData) 652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData->setValue(0x0); 653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EData) 654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData->setValue(0x0); 655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pBSSStart) 656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart->setValue(0x0); 657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEnd) 659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd->setValue(0x0); 660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_End) 661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End->setValue(0x0); 662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 66822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol) 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ignore if symbol has no fragRef 67122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSymbol.hasFragRef()) 67222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 67422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the value of a TLS symbol is the offset to the TLS segment 67522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFSegment* tls_seg = m_ELFSegmentTable.find(llvm::ELF::PT_TLS, 67622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_R, 0x0); 67722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t value = pSymbol.fragRef()->getOutputOffset(); 67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t addr = pSymbol.fragRef()->frag()->getParent()->getSection().addr(); 67922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSymbol.setValue(value + addr - tls_seg->vaddr()); 68022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 68322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFFileFormat* GNULDBackend::getOutputFormat() 684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 68522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 68622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 68722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pDynObjFileFormat); 68822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 690d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pExecFileFormat); 69222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 69322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 69422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectFileFormat); 69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 69722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 70222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst ELFFileFormat* GNULDBackend::getOutputFormat() const 703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 70422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 70622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pDynObjFileFormat); 70722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 70822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 709d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 71022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pExecFileFormat); 71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 71222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectFileFormat); 71422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 715affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 717affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 718affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 719affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab, 72322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab. 724f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::sizeNamePools(Module& pModule) 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 726f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(LinkerConfig::Unset != config().codePosition()); 727f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // number of entries in symbol tables starts from 1 to hold the special entry 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21. 73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t symtab = 1; 731f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t dynsym = config().isCodeStatic()? 0 : 1; 73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size of string tables starts from 1 to hold the null character in their 73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // first byte 7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t strtab = 1; 736f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t dynstr = config().isCodeStatic()? 0 : 1; 73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t shstrtab = 1; 7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hash = 0; 7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t gnuhash = 0; 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // number of local symbol in the .symtab and .dynsym 7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symtab_local_cnt = 0; 743d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao size_t dynsym_local_cnt = 0; 744d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd; 7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// Compute the size of .symtab, .strtab, and symtab_local_cnt 74822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.end(); 7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.begin(); symbol != symEnd; ++symbol) { 75122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtab; 752f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 7536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtab += (*symbol)->nameSize() + 1; 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symtab_local_cnt = 1 + symbols.numOfFiles() + symbols.numOfLocals() + 7566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symbols.numOfLocalDyns(); 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 75822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch(config().codeGenType()) { 76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // soname 7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += pModule.name().size() + 1; 76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 76522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /** fall through **/ 766d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 767d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 768f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!config().isCodeStatic()) { 7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// Compute the size of .dynsym, .dynstr, and dynsym_local_cnt 7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.dynamicEnd(); 7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) { 7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dynsym; 773f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*symbol)->nameSize() + 1; 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynsym_local_cnt = 1 + symbols.numOfLocalDyns(); 7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // compute .gnu.hash 7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::GNU == config().options().getHashStyle() || 7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) { 7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // count the number of dynsym to hash 7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashed_sym_cnt = 0; 7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.dynamicEnd(); 7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.dynamicBegin(); symbol != symEnd; ++symbol) { 7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (DynsymCompare().needGNUHash(**symbol)) 7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++hashed_sym_cnt; 7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Special case for empty .dynsym 7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (hashed_sym_cnt == 0) 7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash = 5 * 4 + config().targets().bitclass() / 8; 7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t nbucket = getHashBucketCount(hashed_sym_cnt, true); 7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash = (4 + nbucket + hashed_sym_cnt) * 4; 7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash += (1U << getGNUHashMaskbitslog2(hashed_sym_cnt)) / 8; 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 79822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute .hash 7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::SystemV == config().options().getHashStyle() || 8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) { 8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Both Elf32_Word and Elf64_Word are 4 bytes 8026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hash = (2 + getHashBucketCount(dynsym, false) + dynsym) * 8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf32_Word); 8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // add DT_NEEDED 8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) { 8106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*lib)->name().size() + 1; 8116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveNeedEntry(); 8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // add DT_RPATH 8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().getRpathList().empty()) { 8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveNeedEntry(); 8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::const_rpath_iterator rpath, 8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rpathEnd = config().options().rpath_end(); 8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (rpath = config().options().rpath_begin(); 8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rpath != rpathEnd; ++rpath) 8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*rpath).size() + 1; 8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set size 8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setSize(dynsym * 8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf32_Sym)); 8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setSize(dynsym * 8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf64_Sym)); 8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynStrTab().setSize(dynstr); 8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getHashTab().setSize(hash); 8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getGNUHashTab().setSize(gnuhash); 8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .dynsym sh_info to one greater than the symbol table 8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // index of the last local symbol 8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setInfo(dynsym_local_cnt); 8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Because some entries in .dynamic section need information of .dynsym, 8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED 8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // entries until we get the size of the sections mentioned above 8446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveEntries(*file_format); 8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynamic().setSize(dynamic().numOfBytes()); 8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /* fall through */ 84922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 850d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym)); 8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym)); 8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getStrTab().setSize(strtab); 855d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 856d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // set .symtab sh_info to one greater than the symbol table 857d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // index of the last local symbol 8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getSymTab().setInfo(symtab_local_cnt); 8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // compute the size of .shstrtab section. 8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_iterator sect, sectEnd = pModule.end(); 8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (sect = pModule.begin(); sect != sectEnd; ++sect) { 8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch ((*sect)->kind()) { 8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Null: 8656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // take StackNote directly 8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::StackNote: 8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab += ((*sect)->name().size() + 1); 8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrame: 8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*sect)->size() != 0) || 8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*sect)->hasEhFrame() && 8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab += ((*sect)->name().size() + 1); 8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Relocation: 8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*sect)->size() != 0) || 8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*sect)->hasRelocData() && 8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab += ((*sect)->name().size() + 1); 8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 8826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 8836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*sect)->size() != 0) || 8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*sect)->hasSectionData() && 8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 8866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab += ((*sect)->name().size() + 1); 8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of switch 8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab += (strlen(".shstrtab") + 1); 8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getShStrTab().setSize(shstrtab); 8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 89422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 89522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::fatal_illegal_codegen_type) << pModule.name(); 89622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end of switch 89822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 89922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 90022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol 90122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym, 90222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 90322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 90422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 90522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx) 90622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 90722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check the endian between host and target 90822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out symbol 909f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(pSymbol)) { 91022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = pStrtabsize; 91122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((pStrtab + pStrtabsize), pSymbol.name()); 91222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 91322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 91422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = 0; 91522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_value = pSymbol.value(); 91722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_size = getSymbolSize(pSymbol); 91822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_info = getSymbolInfo(pSymbol); 91922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_other = pSymbol.visibility(); 92022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_shndx = getSymbolShndx(pSymbol); 92122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 92222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 92322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol 92422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym, 92522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 92622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 92722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 92822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx) 92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 93022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check the endian between host and target 93122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out symbol 932f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(pSymbol)) { 9336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSym.st_name = pStrtabsize; 9346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strcpy((pStrtab + pStrtabsize), pSymbol.name()); 9356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSym.st_name = 0; 9386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 93922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_value = pSymbol.value(); 94022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_size = getSymbolSize(pSymbol); 94122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_info = getSymbolInfo(pSymbol); 94222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_other = pSymbol.visibility(); 94322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_shndx = getSymbolShndx(pSymbol); 9445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab 9475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 9495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 95022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule, 95122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryArea& pOutput) 9525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 95322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 9545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getSymTab(); 9565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getStrTab(); 9575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 95822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(), 95922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtab_sect.size()); 96022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(), 96122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab_sect.size()); 9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 966d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 968d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start(); 970d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 971d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 972d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 973d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 974d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 9775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit the first ELF symbol 9796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) 9806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0); 9816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 9826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0); 9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 98422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool sym_exist = false; 98522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao HashTableType::entry_type* entry = NULL; 98622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 9876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry = m_pSymIndexMap->insert(LDSymbol::Null(), sym_exist); 98822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(0); 98922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 99022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symIdx = 1; 9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 9936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Module::SymbolTable& symbols = pModule.getSymbolTable(); 9956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd; 9966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.end(); 9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.begin(); symbol != symEnd; ++symbol) { 99922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 100022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry->setValue(symIdx); 10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1003d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 10046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx); 100522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 10066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx); 10076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symIdx; 1008f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 100922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 101322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 10145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 10155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 10165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitDynNamePools(Module& pModule, MemoryArea& pOutput) 10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 101922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 102022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!file_format->hasDynSymTab() || 102122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynStrTab() || 102222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynamic()) 102322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 10265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& dyn_sect = file_format->getDynamic(); 10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 103222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(), 103322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtab_sect.size()); 103422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(), 103522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab_sect.size()); 103622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* dyn_region = pOutput.request(dyn_sect.offset(), 103722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyn_sect.size()); 10385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 10395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 10405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 1041d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 1043d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 10445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start(); 1045d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 1046d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 1047d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 1048d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 10515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 10525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit the first ELF symbol 10546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) 10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0); 10566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 10576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0); 10585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symIdx = 1; 10605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 10615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .gnu.hash 10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::GNU == config().options().getHashStyle() || 1065f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) 10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitGNUHashTab(symbols, pOutput); 1067f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .hash 10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::SystemV == config().options().getHashStyle() || 10706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) 10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitELFHashTab(symbols, pOutput); 10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category) 10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = symbols.dynamicEnd(); 10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) { 1076d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 10776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx); 107822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 10796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx); 10805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // maintain output's symbol and index map 10815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 10826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry->setValue(symIdx); 108322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sum up counters 10846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symIdx; 1085f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 108622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 10875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 10905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 10915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 109222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 109322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 10946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) { 10956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strcpy((strtab + strtabsize), (*lib)->name().c_str()); 10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 10976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtabsize += (*lib)->name().size() + 1; 10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dt_need; 10996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().getRpathList().empty()) { 11036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().hasNewDTags()) 11046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_RPATH, strtabsize); 11056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 11066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_RUNPATH, strtabsize); 11076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dt_need; 11086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::const_rpath_iterator rpath, 11106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rpathEnd = config().options().rpath_end(); 11116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (rpath = config().options().rpath_begin(); rpath != rpathEnd; ++rpath) { 11126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy((strtab + strtabsize), (*rpath).data(), (*rpath).size()); 11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtabsize += (*rpath).size(); 11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtab[strtabsize++] = (rpath + 1 == rpathEnd ? '\0' : ':'); 11155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 111622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 111922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 112022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set pointer to SONAME entry in dynamic string table. 1121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dynamic().applySoname(strtabsize); 112222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynamic().applyEntries(*file_format); 11245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().emit(dyn_sect, *dyn_region); 11255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 112622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit soname 112722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 112822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((strtab + strtabsize), pModule.name().c_str()); 112922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += pModule.name().size() + 1; 113022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 11325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitELFHashTab - emit .hash 11346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitELFHashTab(const Module::SymbolTable& pSymtab, 11356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryArea& pOutput) 11366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 11376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 11386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!file_format->hasHashTab()) 11396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 11406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& hash_sect = file_format->getHashTab(); 11416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* hash_region = pOutput.request(hash_sect.offset(), 11426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hash_sect.size()); 11435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 11445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 11455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* word_array = (uint32_t*)hash_region->start(); 11465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 11475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nchain = word_array[1]; 11485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t dynsymSize = 1 + pSymtab.numOfLocalDyns() + pSymtab.numOfDynamics(); 11506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nbucket = getHashBucketCount(dynsymSize, false); 11516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nchain = dynsymSize; 11525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 11545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* chain = (bucket + nbucket); 11555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 1157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memset((void*)bucket, 0, nbucket); 11585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines hash::StringHash<hash::ELF> hash_func; 11605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t idx = 1; 11626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd(); 11636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.localDynBegin(); symbol != symEnd; ++symbol) { 11646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::StringRef name((*symbol)->name()); 11656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t bucket_pos = hash_func(name) % nbucket; 11666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain[idx] = bucket[bucket_pos]; 11676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[bucket_pos] = idx; 11686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++idx; 11696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 11716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitGNUHashTab - emit .gnu.hash 11736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitGNUHashTab(Module::SymbolTable& pSymtab, 11746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryArea& pOutput) 11756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 11766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 11776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!file_format->hasGNUHashTab()) 11786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 11796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* gnuhash_region = 11816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pOutput.request(file_format->getGNUHashTab().offset(), 11826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getGNUHashTab().size()); 11836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* word_array = (uint32_t*)gnuhash_region->start(); 11856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // fixed-length fields 11866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& nbucket = word_array[0]; 11876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& symidx = word_array[1]; 11886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& maskwords = word_array[2]; 11896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& shift2 = word_array[3]; 11906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // variable-length fields 11916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t* bitmask = (uint8_t*)(word_array + 4); 11926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* bucket = NULL; 11936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* chain = NULL; 11946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // count the number of dynsym to hash 11966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t unhashed_sym_cnt = pSymtab.numOfLocalDyns(); 11976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashed_sym_cnt = pSymtab.numOfDynamics(); 11986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd(); 11996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.dynamicBegin(); symbol != symEnd; ++symbol) { 12006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (DynsymCompare().needGNUHash(**symbol)) 12016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 12026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++unhashed_sym_cnt; 12036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines --hashed_sym_cnt; 12046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // special case for the empty hash table 12076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (hashed_sym_cnt == 0) { 12086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nbucket = 1; // one empty bucket 12096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symidx = 1 + unhashed_sym_cnt; // symidx above unhashed symbols 12106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskwords = 1; // bitmask length 12116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shift2 = 0; // bloom filter 12126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 12146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* maskval = (uint32_t*)bitmask; 12156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *maskval = 0; // no valid hashes 12166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 12176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be 64 12186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t* maskval = (uint64_t*)bitmask; 12196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *maskval = 0; // no valid hashes 12205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket = (uint32_t*)(bitmask + config().targets().bitclass() / 8); 12226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *bucket = 0; // no hash in the only bucket 12236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 12245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbitslog2 = getGNUHashMaskbitslog2(hashed_sym_cnt); 12276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbits = 1u << maskbitslog2; 12286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shift1 = config().targets().is32Bits() ? 5 : 6; 12296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t mask = (1u << shift1) - 1; 12306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nbucket = getHashBucketCount(hashed_sym_cnt, true); 12326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symidx = 1 + unhashed_sym_cnt; 12336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskwords = 1 << (maskbitslog2 - shift1); 12346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shift2 = maskbitslog2; 12356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // setup bucket and chain 12376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket = (uint32_t*)(bitmask + maskbits / 8); 12386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain = (bucket + nbucket); 12396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // build the gnu style hash table 12416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef std::multimap<uint32_t, 12426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::pair<LDSymbol*, uint32_t> > SymMapType; 12436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines SymMapType symmap; 12446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = pSymtab.dynamicEnd(); 12456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.localDynBegin() + symidx - 1; symbol != symEnd; 12466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symbol) { 1247f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines hash::StringHash<hash::DJB> hasher; 12486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t djbhash = hasher((*symbol)->name()); 12496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t hash = djbhash % nbucket; 12506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symmap.insert(std::make_pair(hash, std::make_pair(*symbol, djbhash))); 12516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // compute bucket, chain, and bitmask 12546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::vector<uint64_t> bitmasks(maskwords); 12556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashedidx = symidx; 12566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < nbucket; ++idx) { 12576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t count = 0; 12586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::pair<SymMapType::iterator, SymMapType::iterator> ret; 12596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ret = symmap.equal_range(idx); 12606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (SymMapType::iterator it = ret.first; it != ret.second; ) { 12616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // rearrange the hashed symbol ordering 12626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *(pSymtab.localDynBegin() + hashedidx - 1) = it->second.first; 12636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t djbhash = it->second.second; 12646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t val = ((djbhash >> shift1) & ((maskbits >> shift1) - 1)); 12656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bitmasks[val] |= 1u << (djbhash & mask); 12666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bitmasks[val] |= 1u << ((djbhash >> shift2) & mask); 12676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines val = djbhash & ~1u; 12686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // advance the iterator and check if we're dealing w/ the last elment 12696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (++it == ret.second) { 12706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // last element terminates the chain 12716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines val |= 1; 12726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain[hashedidx - symidx] = val; 12746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++hashedidx; 12766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++count; 12775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (count == 0) 12806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[idx] = 0; 12816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 12826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[idx] = hashedidx - count; 12836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // write the bitmasks 12866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 12876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* maskval = (uint32_t*)bitmask; 12886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t i = 0; i < maskwords; ++i) 12896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(maskval + i, &bitmasks[i], 4); 12906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 12916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be 64 12926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t* maskval = (uint64_t*)bitmask; 12936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t i = 0; i < maskwords; ++i) 12946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(maskval + i, &bitmasks[i], 8); 12955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 12975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section 129922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::sizeInterp() 1300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 1301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const char* dyld_name; 130222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 130322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 1304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 13056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dyld_name = m_pInfo->dyld(); 1306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 130722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& interp = getOutputFormat()->getInterp(); 1308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang interp.setSize(std::strlen(dyld_name) + 1); 1309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp 131222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitInterp(MemoryArea& pOutput) 1313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 131422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasInterp()) { 131522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& interp = getOutputFormat()->getInterp(); 131622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion *region = pOutput.request(interp.offset(), interp.size()); 131722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* dyld_name; 131822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 131922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 132022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 13216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dyld_name = m_pInfo->dyld(); 1322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 132322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao std::memcpy(region->start(), dyld_name, interp.size()); 132422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1327f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool GNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const 1328f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 1329f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ResolveInfo::Section != pSym.type(); 1330f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 1331f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1332f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::orderSymbolTable(Module& pModule) 1333f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 1334f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 1335f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1336f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (GeneralOptions::GNU == config().options().getHashStyle() || 1337f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) 1338f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Currently we may add output symbols after sizeNamePools(), and a 1339f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // non-stable sort is used in SymbolCategory::arrange(), so we just 1340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort .dynsym right before emitting .gnu.hash 1341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(), 1342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines DynsymCompare()); 1343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 1344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 13455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder 134622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaounsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const 13475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 134822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 134922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // NULL section should be the "1st" section 13515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (LDFileFormat::Null == pSectHdr.kind()) 13525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 13535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 135422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getStrTab()) 135522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_STRTAB; 135622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if the section is not ALLOC, lay it out until the last possible moment 13585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC)) 13595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 13605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0; 13625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0; 13635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: need to take care other possible output sections 13645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pSectHdr.kind()) { 13655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Regular: 13665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (is_exec) { 13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getInit()) 13685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_INIT; 13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getFini()) 13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_FINI; 13715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_TEXT; 13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else if (!is_write) { 13735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RO; 13745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 137522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 137622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getPreInitArray() || 137722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getInitArray() || 137822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getFiniArray() || 1379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getCtors() || 1380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getDtors() || 1381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getJCR() || 1382d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao &pSectHdr == &file_format->getDataRelRo()) 1383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 1384d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (&pSectHdr == &file_format->getDataRelRoLocal()) 1385affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO_LOCAL; 1386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 138722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) { 138822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_DATA; 138922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 13915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 13925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::BSS: 139422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) 139522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_BSS; 13965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_BSS; 13975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 139822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::NamePool: { 13995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getDynamic()) 14005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO; 14015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NAMEPOOL; 140222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Relocation: 14045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getRelPlt() || 14055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &pSectHdr == &file_format->getRelaPlt()) 14065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_REL_PLT; 14075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELOCATION; 14085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get the order from target for target specific sections 14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Target: 141122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return getTargetSectionOrder(pSectHdr); 14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // handle .interp and .note.* sections 14145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Note: 14156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (file_format->hasInterp() && (&pSectHdr == &file_format->getInterp())) 14166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_INTERP; 14176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (is_write) 14186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RW_NOTE; 14196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 14206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RO_NOTE; 14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrame: 1423f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set writable .eh_frame as relro 1424f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (is_write) 1425f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO; 1426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrameHdr: 1427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::GCCExceptTable: 1428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_EXCEPTION; 14295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::MetaData: 14315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Debug: 14325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 14335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 14345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize 14385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const 14395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // @ref Google gold linker: symtab.cc: 2780 14415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // undefined and dynamic symbols should have zero size. 14425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined) 14435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 14445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.resolveInfo()->size(); 14455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo 14485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const 14495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set binding 14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t bind = 0x0; 14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isLocal()) 14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isGlobal()) 14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isWeak()) 14575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_WEAK; 14585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isAbsolute()) { 14595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // (Luba) Is a absolute but not global (weak or local) symbol meaningful? 14605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1463d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().codeGenType() != LinkerConfig::Object && 1464d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (pSymbol.visibility() == llvm::ELF::STV_INTERNAL || 1465d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pSymbol.visibility() == llvm::ELF::STV_HIDDEN)) 14665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t type = pSymbol.resolveInfo()->type(); 1469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change 1470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // its type to Function 1471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn()) 1472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang type = ResolveInfo::Function; 1473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (type | (bind << 4)); 14745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout() 14775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const 14785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn()) 14805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 14815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.value(); 14835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout() 14865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t 148722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const 14885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isAbsolute()) 14905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_ABS; 14915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isCommon()) 14925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_COMMON; 14935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn()) 14945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_UNDEF; 14955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSymbol.resolveInfo()->isLocal() && 14976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkerConfig::Object != config().codeGenType()) { 14985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pSymbol.type()) { 14995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case ResolveInfo::NoType: 15005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case ResolveInfo::File: 15015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_ABS; 15025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 15035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 15045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 150522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef()) 150622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return llvm::ELF::SHN_ABS; 150722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pSymbol.hasFragRef() && "symbols must have fragment reference to get its index"); 150922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return pSymbol.fragRef()->frag()->getParent()->getSection().index(); 15105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 15115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index 15136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinessize_t GNULDBackend::getSymbolIdx(const LDSymbol* pSymbol) const 15145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 15156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HashTableType::iterator entry = m_pSymIndexMap->find(const_cast<LDSymbol *>(pSymbol)); 15166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(entry != m_pSymIndexMap->end() && "symbol not found in the symbol table"); 15175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return entry.getEntry()->value(); 15185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 15195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isTemporary - Whether pSymbol is a local label. 15216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::isTemporary(const LDSymbol& pSymbol) const 15226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 15236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (ResolveInfo::Local != pSymbol.binding()) 15246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSymbol.nameSize() < 2) 15276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* name = pSymbol.name(); 15306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ('.' == name[0] && 'L' == name[1]) 15316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 15326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // UnixWare 2.1 cc generate DWARF debugging symbols with `..' prefix. 15346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name() 15356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (name[0] == '.' && name[1] == '.') 15366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 15376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Work arround for gcc's bug 15396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // gcc sometimes generate symbols with '_.L_' prefix. 15406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name() 15416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSymbol.nameSize() < 4) 15426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_') 15456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 15466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 15496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding 155122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage. 1552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @refer Google gold linker: common.cc: 214 1553affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool 155422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::allocateCommonSymbols(Module& pModule) 15555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 155622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymbolCategory& symbol_list = pModule.getSymbolTable(); 1557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (symbol_list.emptyCommons() && symbol_list.emptyFiles() && 15596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symbol_list.emptyLocals() && symbol_list.emptyLocalDyns()) 1560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 1561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 1563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: If the order of common symbols is defined, then sort common symbols 1565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // std::sort(com_sym, com_end, some kind of order); 1566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 156722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get corresponding BSS LDSection 156822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 156922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& bss_sect = file_format->getBSS(); 157022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& tbss_sect = file_format->getTBSS(); 1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1572cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 157322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_sect_data = NULL; 157422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect.hasSectionData()) 157522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = bss_sect.getSectionData(); 157622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 157722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 157822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 157922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* tbss_sect_data = NULL; 158022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (tbss_sect.hasSectionData()) 158122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = tbss_sect.getSectionData(); 158222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 158322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 1584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 158622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t bss_offset = bss_sect.size(); 158722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tbss_offset = tbss_sect.size(); 1588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all local common symbols 1590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.localEnd(); 1591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 1593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::Common == (*com_sym)->desc()) { 1594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1600cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 160122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 160522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 160622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 160722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 161022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 161122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 161222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 16165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all global common symbols 1618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.commonEnd(); 1619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 1620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1626cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 162722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 163122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 163222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 163322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 163622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 163722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 163822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 164222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect.setSize(bss_offset); 164322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect.setSize(tbss_offset); 1644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang symbol_list.changeCommonsToGlobal(); 1645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 16465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 16475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// updateSectionFlags - update pTo's flags when merging pFrom 16496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// update the output section flags based on input section flags. 16506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref The Google gold linker: 16516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// output.cc: 2809: Output_section::update_flags_for_input_section 16526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::updateSectionFlags(LDSection& pTo, const LDSection& pFrom) 16536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 16546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // union the flags from input 16556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t flags = pTo.flag(); 16566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags |= (pFrom.flag() & 16576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (llvm::ELF::SHF_WRITE | 16586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHF_ALLOC | 16596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHF_EXECINSTR)); 16606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is an input section is not SHF_MERGE, clean this flag 16626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == (pFrom.flag() & llvm::ELF::SHF_MERGE)) 16636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags &= ~llvm::ELF::SHF_MERGE; 16646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is an input section is not SHF_STRINGS, clean this flag 16666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == (pFrom.flag() & llvm::ELF::SHF_STRINGS)) 16676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags &= ~llvm::ELF::SHF_STRINGS; 16686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pTo.setFlag(flags); 16706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 16716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers 16746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::createProgramHdrs(Module& pModule) 16755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 167622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat *file_format = getOutputFormat(); 1677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_PHDR 16795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_ELFSegmentTable.produce(llvm::ELF::PT_PHDR); 16805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_INTERP 1682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInterp()) { 16835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment* interp_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_INTERP); 1684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang interp_seg->addSection(&file_format->getInterp()); 1685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 168722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t cur_flag, prev_flag = getSegmentFlag(0); 16885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment* load_seg = NULL; 16895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make possible PT_LOAD segments 1690f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::AddressMap::iterator addrEnd 1691f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines = pModule.getScript().addressMap().end(); 169222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator sect, sect_end = pModule.end(); 169322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sect = pModule.begin(); sect != sect_end; ++sect) { 1694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == ((*sect)->flag() & llvm::ELF::SHF_ALLOC) && 16965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::Null != (*sect)->kind()) 16975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 16985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 169922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_flag = getSegmentFlag((*sect)->flag()); 170022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool createPT_LOAD = false; 170122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Null == (*sect)->kind()) { 170222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. create text segment 170322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 170422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 170522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (!config().options().omagic() && 170622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) { 170722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. create data segment if w/o omagic set 170822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 170922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 171022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*sect)->kind() == LDFileFormat::BSS && 171122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->isDataSegment() && 1712f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines addrEnd != pModule.getScript().addressMap().find(".bss")) { 171322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. create bss segment if w/ -Tbss and there is a data segment 171422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 171522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 171622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 171722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*sect != &(file_format->getText())) && 171822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect != &(file_format->getData())) && 171922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect != &(file_format->getBSS())) && 1720f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (addrEnd != pModule.getScript().addressMap().find((*sect)->name()))) 172122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 4. create PT_LOAD for sections in address map except for text, data, 172222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // and bss 172322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 172422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 17255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 172622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (createPT_LOAD) { 172722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create new PT_LOAD segment 172822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_LOAD, cur_flag); 17296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().nmagic() && !config().options().omagic()) 17306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines load_seg->setAlign(abiPageSize()); 17315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != load_seg); 1734affc150dc44fab1911775a49636d0ce85333b634Zonr Chang load_seg->addSection((*sect)); 173522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cur_flag != prev_flag) 173622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->updateFlag(cur_flag); 17375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 173822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao prev_flag = cur_flag; 17395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_DYNAMIC 1742affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasDynamic()) { 1743affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* dyn_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_DYNAMIC, 1744affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_R | 1745affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_W); 1746affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dyn_seg->addSection(&file_format->getDynamic()); 1747affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1748affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 174922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 1750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_RELRO 1751affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* relro_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_RELRO); 175222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 175322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) { 175422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::PT_LOAD != (*seg).type()) 175522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 175622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 175722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegment::sect_iterator sect = (*seg).begin(), 175822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sectEnd = (*seg).end(); sect != sectEnd; ++sect) { 175922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao unsigned int order = getSectionOrder(**sect); 176022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (SHO_RELRO_LOCAL == order || 176122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SHO_RELRO == order || 176222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SHO_RELRO_LAST == order) { 176322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relro_seg->addSection(*sect); 176422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1766affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 17675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 17685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1769affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_EH_FRAME 1770affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasEhFrameHdr()) { 1771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegment* eh_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_EH_FRAME); 1772affc150dc44fab1911775a49636d0ce85333b634Zonr Chang eh_seg->addSection(&file_format->getEhFrameHdr()); 1773affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 177422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 177522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_TLS 177622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData() || file_format->hasTBSS()) { 177722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFSegment* tls_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_TLS); 177822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData()) 177922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tls_seg->addSection(&file_format->getTData()); 178022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTBSS()) 178122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tls_seg->addSection(&file_format->getTBSS()); 178222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 178322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 178422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_GNU_STACK 178522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasStackNote()) { 178622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFSegmentTable.produce(llvm::ELF::PT_GNU_STACK, 178722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_R | 178822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_W | 178922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getSegmentFlag(file_format->getStackNote().flag())); 179022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 179122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 17926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // make PT_NOTE 17936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFSegment *note_seg = NULL; 17946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines prev_flag = getSegmentFlag(0); 17956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (sect = pModule.begin(); sect != sect_end; ++sect) { 17966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ((*sect)->kind() != LDFileFormat::Note || 17976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*sect)->flag() & llvm::ELF::SHF_ALLOC) == 0) 17986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines continue; 17996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 18006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines cur_flag = getSegmentFlag((*sect)->flag()); 18016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // we have different section orders for read-only and writable notes, so 18026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // create 2 segments if needed. 18036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (note_seg == NULL || 18046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (cur_flag & llvm::ELF::PF_W) != (prev_flag & llvm::ELF::PF_W)) 18056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines note_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_NOTE, cur_flag); 18066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 18076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines note_seg->addSection(*sect); 18086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines prev_flag = cur_flag; 18096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 18106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 181122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create target dependent segments 18126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines doCreateProgramHdrs(pModule); 1813affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1814affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments 1816f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::setupProgramHdrs(const LinkerScript& pScript) 1817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 18185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // update segment info 1819f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t seg_start_addr = getSegmentStartAddr(pScript); 18205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegmentFactory::iterator seg, seg_end = m_ELFSegmentTable.end(); 18215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (seg = m_ELFSegmentTable.begin(); seg != seg_end; ++seg) { 18225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment& segment = *seg; 18235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // update PT_PHDR 18255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::PT_PHDR == segment.type()) { 1826f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t offset = 0, phdr_size = 0; 1827d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) { 18285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf32_Ehdr); 18295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf32_Phdr); 18305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 18325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf64_Ehdr); 18335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf64_Phdr); 18345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setOffset(offset); 1836f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines segment.setVaddr(seg_start_addr + offset); 18375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setPaddr(segment.vaddr()); 18385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setFilesz(numOfSegments() * phdr_size); 18395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setMemsz(numOfSegments() * phdr_size); 1840d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao segment.setAlign(config().targets().bitclass() / 8); 18415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 18425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1844affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // bypass if there is no section in this segment (e.g., PT_GNU_STACK) 1845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (segment.numOfSections() == 0) 1846affc150dc44fab1911775a49636d0ce85333b634Zonr Chang continue; 1847affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 184822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segment.setOffset(segment.front()->offset()); 1849affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (llvm::ELF::PT_LOAD == segment.type() && 185022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Null == segment.front()->kind()) 1851f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines segment.setVaddr(seg_start_addr); 1852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 185322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segment.setVaddr(segment.front()->addr()); 18545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setPaddr(segment.vaddr()); 18555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 185622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* last_sect = segment.back(); 18575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != last_sect); 1858affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t file_size = last_sect->offset() - segment.offset(); 18595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (LDFileFormat::BSS != last_sect->kind()) 18605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_size += last_sect->size(); 18615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setFilesz(file_size); 18625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao segment.setMemsz(last_sect->addr() - segment.vaddr() + last_sect->size()); 18645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 18665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 186722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output 1868affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: layout.cc:2608 18696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::setupGNUStackInfo(Module& pModule) 18705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1871affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t flag = 0x0; 187222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasStackSet()) { 1873affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 1. check the command line option (-z execstack or -z noexecstack) 187422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasExecStack()) 1875affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 187622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 187722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 1878affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. check the stack info from the input objects 187922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: since we alway emit .note.GNU-stack in output now, we may be able 188022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to check this from the output .note.GNU-stack directly after section 188122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // merging is done 1882affc150dc44fab1911775a49636d0ce85333b634Zonr Chang size_t object_count = 0, stack_note_count = 0; 188322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_obj_iterator obj, objEnd = pModule.obj_end(); 188422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (obj = pModule.obj_begin(); obj != objEnd; ++obj) { 188522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++object_count; 188622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack"); 188722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != sect) { 188822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++stack_note_count; 188922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2.1 found a stack note that is set as executable 189022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) { 189122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao flag = llvm::ELF::SHF_EXECINSTR; 189222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 1893affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1894affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1895affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 18965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1897affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.2 there are no stack note sections in all input objects 1898affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == stack_note_count) 1899affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 19005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1901affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.3 a special case. Use the target default to decide if the stack should 1902affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // be executable 1903affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count) 19046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_pInfo->isDefaultExecStack()) 1905affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 19065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 19075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 190822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasStackNote()) { 190922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getOutputFormat()->getStackNote().setFlag(flag); 191022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 191122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 191222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 191322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupRelro - setup the offset constraint of PT_RELRO 191422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setupRelro(Module& pModule) 191522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 191622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(config().options().hasRelro()); 191722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if -z relro is given, we need to adjust sections' offset again, and let 191822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // PT_GNU_RELRO end on a common page boundary 191922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 192022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator sect = pModule.begin(); 192122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (Module::iterator sect_end = pModule.end(); sect != sect_end; ++sect) { 192222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // find the first non-relro section 192322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getSectionOrder(**sect) > SHO_RELRO_LAST) 192422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 192522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 192622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 192722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // align the first non-relro section to page boundary 192822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t offset = (*sect)->offset(); 192922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao alignAddress(offset, commonPageSize()); 193022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect)->setOffset(offset); 193122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 193222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // It seems that compiler think .got and .got.plt are continuous (w/o any 193322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // padding between). If .got is the last section in PT_RELRO and it's not 193422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // continuous to its next section (i.e. .got.plt), we need to add padding 193522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // in front of .got instead. 193622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: Maybe we can handle this in a more general way. 193722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = getOutputFormat()->getGOT(); 193822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((getSectionOrder(got) == SHO_RELRO_LAST) && 193922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (got.offset() + got.size() != offset)) { 194022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao got.setOffset(offset - got.size()); 194122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 194222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 194322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up remaining section's offset 194422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setOutputSectionOffset(pModule, ++sect, pModule.end()); 194522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 194622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 194722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set a group of output sections' 194822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// offset, and set pSectBegin to pStartOffset if pStartOffset is not -1U. 194922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::setOutputSectionOffset(Module& pModule, 195022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectBegin, 195122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectEnd, 195222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t pStartOffset) 195322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 195422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSectBegin == pModule.end()) 195522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 195622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 195722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pSectEnd == pModule.end() || 195822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (pSectEnd != pModule.end() && 195922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*pSectBegin)->index() <= (*pSectEnd)->index())); 196022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 196122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pStartOffset != -1U) { 196222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*pSectBegin)->setOffset(pStartOffset); 196322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++pSectBegin; 196422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 196522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 196622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up the "cur" and "prev" iterator 196722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator cur = pSectBegin; 196822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator prev = pSectBegin; 196922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cur != pModule.begin()) 197022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao --prev; 1971affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 197222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++cur; 197322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 197422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (; cur != pSectEnd; ++cur, ++prev) { 197522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t offset = 0x0; 197622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch ((*prev)->kind()) { 197722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Null: 197822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset = sectionStartOffset(); 197922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 198022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::BSS: 198122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset = (*prev)->offset(); 198222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 198322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 198422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset = (*prev)->offset() + (*prev)->size(); 198522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 198622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 198722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 198822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao alignAddress(offset, (*cur)->align()); 198922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*cur)->setOffset(offset); 199022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 199122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 199222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 199322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setOutputSectionOffset - helper function to set output sections' address 19946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::setOutputSectionAddress(Module& pModule, 199522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectBegin, 199622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator pSectEnd) 199722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 199822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSectBegin == pModule.end()) 199922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 200022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 200122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pSectEnd == pModule.end() || 200222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (pSectEnd != pModule.end() && 200322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*pSectBegin)->index() <= (*pSectEnd)->index())); 200422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2005f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const LinkerScript& script = pModule.getScript(); 2006f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t seg_start_addr = getSegmentStartAddr(script); 200722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 200822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao segEnd = elfSegmentTable().end(), prev = elfSegmentTable().end(); 200922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao seg != segEnd; prev = seg, ++seg) { 201022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::PT_LOAD != (*seg).type()) 201122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 201222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 201322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t start_addr = 0x0; 2014f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::AddressMap::const_iterator mapping; 201522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*seg).front()->kind() == LDFileFormat::Null) 2016f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines mapping = script.addressMap().find(".text"); 201722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*seg).isDataSegment()) 2018f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines mapping = script.addressMap().find(".data"); 201922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*seg).isBssSegment()) 2020f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines mapping = script.addressMap().find(".bss"); 202122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 2022f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines mapping = script.addressMap().find((*seg).front()->name()); 202322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2024f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (mapping != script.addressMap().end()) { 20256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // use address mapping in script options 202622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_addr = mapping.getEntry()->value(); 202722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 202822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 202922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*seg).front()->kind() == LDFileFormat::Null) { 203022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1st PT_LOAD 2031f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines start_addr = seg_start_addr; 203222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 203322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*prev).front()->kind() == LDFileFormat::Null) { 203422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // prev segment is 1st PT_LOAD 2035f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines start_addr = seg_start_addr + (*seg).front()->offset(); 203622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 203722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 203822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Others 203922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_addr = (*prev).front()->addr() + (*seg).front()->offset(); 204022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Try to align p_vaddr at page boundary if not in script options. 20426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // To do so will add more padding in file, but can save one page 20436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // at runtime. 20446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines alignAddress(start_addr, (*seg).align()); 20456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 204622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 20476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf 20486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // p_align: As "Program Loading" describes in this chapter of the 20496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // processor supplement, loadable process segments must have congruent 20506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // values for p_vaddr and p_offset, modulo the page size. 20516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ((start_addr & ((*seg).align() - 1)) != 20526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*seg).front()->offset() & ((*seg).align() - 1))) { 20536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t padding = (*seg).align() + 20546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (start_addr & ((*seg).align() - 1)) - 20556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*seg).front()->offset() & ((*seg).align() - 1)); 20566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setOutputSectionOffset(pModule, 20576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pModule.begin() + (*seg).front()->index(), 20586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pModule.end(), 20596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*seg).front()->offset() + padding); 20606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().options().hasRelro()) 20616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setupRelro(pModule); 206222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 206322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 206422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegment::sect_iterator sect = (*seg).begin(), 206522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sectEnd = (*seg).end(); sect != sectEnd; ++sect) { 206622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*sect)->index() < (*pSectBegin)->index()) 206722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 206822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 206922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Null == (*sect)->kind()) 207022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 207122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 207222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sect == pSectEnd) 207322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 207422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 207522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sect != (*seg).begin()) 207622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect)->setAddr(start_addr + (*sect)->offset() - 207722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*seg).front()->offset()); 207822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 207922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*sect)->setAddr(start_addr); 208022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 208122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 20835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2084d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// layout - layout method 20856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::layout(Module& pModule) 2086d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 2087d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::vector<SHOEntry> output_list; 2088d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1. determine what sections will go into final output, and push the needed 2089d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // sections into output_list for later processing 2090d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie; 2091d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ++it) { 2092d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch ((*it)->kind()) { 20936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // take NULL and StackNote directly 20946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Null: 20956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::StackNote: 20966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 20976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 20986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // ignore if section size is 0 20996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrame: 21006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*it)->size() != 0) || 21016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*it)->hasEhFrame() && 21026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 2103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 21046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 21056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Relocation: 21066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*it)->size() != 0) || 21076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*it)->hasRelocData() && 21086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 21096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 21106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 21116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Regular: 21126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Target: 21136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::MetaData: 21146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::BSS: 21156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Debug: 21166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::GCCExceptTable: 21176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Note: 21186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::NamePool: 21196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrameHdr: 21206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*it)->size() != 0) || 21216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*it)->hasSectionData() && 21226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 21236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 21246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 21256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Group: 21266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object == config().codeGenType()) { 21276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines //TODO: support incremental linking 21286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ; 21296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 21306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 21316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Version: 21326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 != (*it)->size()) { 21336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines output_list.push_back(std::make_pair(*it, getSectionOrder(**it))); 21346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name(); 21356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 21366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 21376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 21386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 != (*it)->size()) { 21396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines error(diag::err_unsupported_section) << (*it)->name() << (*it)->kind(); 21406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 21416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2143d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } // end of for 2144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 2. sort output section orders 2146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::stable_sort(output_list.begin(), output_list.end(), SHOCompare()); 2147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 3. update output sections in Module 2149d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.getSectionTable().clear(); 2150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao for(size_t index = 0; index < output_list.size(); ++index) { 2151d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (output_list[index].first)->setIndex(index); 2152d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.getSectionTable().push_back(output_list[index].first); 2153d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2154d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2155d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 4. create program headers 2156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 21576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createProgramHdrs(pModule); 2158d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2160d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 5. set output section offset 2161d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao setOutputSectionOffset(pModule, pModule.begin(), pModule.end(), 0x0); 2162d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 2163d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 21645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// preLayout - Backend can do any needed modification before layout 21656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::preLayout(Module& pModule, IRBuilder& pBuilder) 21665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 21675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // prelayout target first 21686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines doPreLayout(pBuilder); 2169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 21706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType() && 21716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // init EhFrameHdr and size the output section 217322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* format = getOutputFormat(); 217422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEhFrameHdr = new EhFrameHdr(format->getEhFrameHdr(), 217522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao format->getEhFrame()); 2176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pEhFrameHdr->sizeOutput(); 2177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 217822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 21796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // change .tbss and .tdata section symbol from Local to LocalDyn category 218022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pTDATA) 2181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*f_pTDATA); 218222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 218322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pTBSS) 2184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*f_pTBSS); 218522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 218622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // To merge input's relocation sections into output's relocation sections. 218722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 218822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are generating relocatables (-r), move input relocation sections 218922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to corresponding output relocation sections. 219022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 219122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = pModule.obj_end(); 219222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = pModule.obj_begin(); input != inEnd; ++input) { 219322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 219422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 219522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 219622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the output relocation LDSection with identical name. 219722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_sect = pModule.getSection((*rs)->name()); 219822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == output_sect) { 219922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect = LDSection::Create((*rs)->name(), 220022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->kind(), 220122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->type(), 220222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->flag()); 220322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 220422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setAlign((*rs)->align()); 220522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule.getSectionTable().push_back(output_sect); 220622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 220722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 220822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set output relocation section link 220922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* input_link = (*rs)->getLink(); 221022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != input_link && "Illegal input relocation section."); 221122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 221222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the linked output section 221322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_link = pModule.getSection(input_link->name()); 221422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != output_link); 221522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 221622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setLink(output_link); 221722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 221822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get output relcoationData, create one if not exist 221922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!output_sect->hasRelocData()) 222022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao IRBuilder::CreateRelocData(*output_sect); 222122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 222222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData* out_reloc_data = output_sect->getRelocData(); 222322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 222422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // move relocations from input's to output's RelcoationData 2225d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& out_list = 2226d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao out_reloc_data->getRelocationList(); 2227d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& in_list = 2228d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*rs)->getRelocData()->getRelocationList(); 222922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao out_list.splice(out_list.end(), in_list); 223022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 223122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size output 223222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::SHT_REL == output_sect->type()) 223322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelEntrySize()); 223422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (llvm::ELF::SHT_RELA == output_sect->type()) 223522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelaEntrySize()); 223622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 223722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unknown_reloc_section_type) << output_sect->type() 223822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << output_sect->name(); 223922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 224022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for each relocation section 224122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for each input 224222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of if 224322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 224422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up the section flag of .note.GNU-stack section 22456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setupGNUStackInfo(pModule); 22465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 22475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2248cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout 22496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::postLayout(Module& pModule, IRBuilder& pBuilder) 22505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2251d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1. set up section address and segment attributes 225222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 225322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 2254d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.1 set up the offset constraint of PT_RELRO 225522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setupRelro(pModule); 225622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 225722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2258d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.2 set up the output sections' address 22596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setOutputSectionAddress(pModule, pModule.begin(), pModule.end()); 226022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2261d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.3 do relaxation 22626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relax(pModule, pBuilder); 2263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2264d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 1.4 set up the attributes of program headers 2265f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setupProgramHdrs(pModule.getScript()); 2266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. target specific post layout 22696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines doPostLayout(pModule, pBuilder); 22705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 22715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::postProcessing(MemoryArea& pOutput) 2273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 22746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType() && 22756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // emit eh_frame_hdr 2277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pEhFrameHdr->emitOutput<32>(pOutput); 2278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 22815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count. 22825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker, dynobj.cc:791 22835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols, 22845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool pIsGNUStyle) 22855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 22865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // @ref Google gold, dynobj.cc:loc 791 22875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static const unsigned int buckets[] = 22885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 22895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, 22905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16411, 32771, 65537, 131101, 262147 22915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao }; 22925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const unsigned buckets_count = sizeof buckets / sizeof buckets[0]; 22935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int result = 1; 22955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (unsigned i = 0; i < buckets_count; ++i) { 22965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pNumOfSymbols < buckets[i]) 22975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 22985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = buckets[i]; 22995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 23005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pIsGNUStyle && result < 2) 23025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = 2; 23035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 23055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 23065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2 23086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref binutils gold, dynobj.cc:1165 23096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned GNULDBackend::getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const 23106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 23116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbitslog2 = 1; 23126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (uint32_t x = pNumOfSymbols >> 1; x != 0; x >>=1) 23136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++maskbitslog2; 23146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (maskbitslog2 < 3) 23166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 = 5; 23176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (((1U << (maskbitslog2 - 2)) & pNumOfSymbols) != 0) 23186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 += 3; 23196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 23206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 += 2; 23216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().bitclass() == 64 && maskbitslog2 == 5) 23236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 = 6; 23246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return maskbitslog2; 23266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 23276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol 23295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker: symtab.cc:311 233022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol) 23315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 23325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 23335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol. We should not add it 23345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.binding() == ResolveInfo::Local) 23355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 23365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we are building shared object, and the visibility is external, we 23385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // need to add it. 233922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 2340d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Exec == config().codeGenType() || 2341d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 23425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default || 23436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected) 23445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 234522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 234622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 234722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 234822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 234922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol 235022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker: symtab.cc:311 235122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo) 235222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 235322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 235422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol. We should not add it 235522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.binding() == ResolveInfo::Local) 235622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 235722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 235822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are building shared object, and the visibility is external, we 235922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // need to add it. 236022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 2361d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Exec == config().codeGenType() || 2362d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 236322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.visibility() == ResolveInfo::Default || 23646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pResolveInfo.visibility() == ResolveInfo::Protected) 236522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 236622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine. 2371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:135 237222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::commonPageSize() const 2373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 237422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().commPageSize() > 0) 237522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return std::min(config().options().commPageSize(), abiPageSize()); 2376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 23776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return std::min(m_pInfo->commonPageSize(), abiPageSize()); 2378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine. 2381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:125 238222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::abiPageSize() const 2383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 238422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().maxPageSize() > 0) 238522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return config().options().maxPageSize(); 2386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 23876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pInfo->abiPageSize(); 2388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other 2391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit 2392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:551 239322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const 2394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 2395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.other() != ResolveInfo::Default) 2396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 239822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This is because the codeGenType of pie is DynObj. And gold linker check 239922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the "shared" option instead. 240022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 240122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 240222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 240322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj != config().codeGenType()) 240422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 240522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 240622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().Bsymbolic()) 2407affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2408affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 240922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // A local defined symbol should be non-preemptible. 241022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32 241122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relocation refers to a local defined symbol, and we should generate a 241222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relative dynamic relocation when applying the relocation. 241322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local) 2414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2415affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2418affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 241922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation 242022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, symtab.h:645 24216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsDynRel(const ResolveInfo& pSym, 242222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool pSymHasPLT, 242322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isAbsReloc) const 242422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 242522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // an undefined reference in the executables should be statically 242622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // resolved to 0 and no need a dynamic relocation 242722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isUndef() && 242822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !pSym.isDyn() && 2429d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::Exec == config().codeGenType() || 2430d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType())) 243122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 243222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // An absolute symbol can be resolved directly if it is either local 24346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // or we are linking statically. Otherwise it can still be overridden 24356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // at runtime. 24366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSym.isAbsolute() && 24376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (pSym.binding() == ResolveInfo::Local || config().isCodeStatic())) 243822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 24396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() && isAbsReloc) 244022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 244122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymHasPLT && ResolveInfo::Function == pSym.type()) 244222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 24436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeIndep() && pSymHasPLT) 244422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 244522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDyn() || pSym.isUndef() || 244622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isSymbolPreemptible(pSym)) 244722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 244822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 244922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 245022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 245122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry 2453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:596 24546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsPLT(const ResolveInfo& pSym) const 2455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 245622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isUndef() && 245722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !pSym.isDyn() && 245822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkerConfig::DynObj != config().codeGenType()) 2459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry 2462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() == ResolveInfo::IndirectFunc) 2463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() != ResolveInfo::Function) 2466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 24686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeStatic()) 246922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 247022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 247122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 2472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (pSym.isDyn() || 2475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.isUndef() || 247622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isSymbolPreemptible(pSym)); 2477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 247922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at 248022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time 248122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, Symbol::final_value_is_known 24826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolFinalValueIsKnown(const ResolveInfo& pSym) const 2483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 248422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the output is pic code or if not executables, symbols' value may change 248522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // at runtime 24866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: CodeIndep() || LinkerConfig::Relocatable == CodeGenType 24876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() || 2488d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::Exec != config().codeGenType() && 2489d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary != config().codeGenType())) 2490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 249122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 249222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is from dynamic object, then its value is unknown 249322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDyn()) 2494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 249522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 249622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is not in dynamic object and is not undefined, then its value 249722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is known 249822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSym.isUndef()) 2499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 250122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is undefined and not in dynamic objects, for example, a weak 250222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // undefined symbol, then whether the symbol's final value can be known 250322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // depends on whrther we're doing static link 25046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return config().isCodeStatic(); 2505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation 25086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsCopyReloc(const Relocation& pReloc, 250922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo& pSym) const 2510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 2511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // only the reference from dynamic executable to non-function symbol in 2512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // the dynamic objects may need copy relocation 25136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() || 2514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang !pSym.isDyn() || 2515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.type() == ResolveInfo::Function || 2516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.size() == 0) 2517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // check if the option -z nocopyreloc is given 252022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNoCopyReloc()) 2521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // TODO: Is this check necessary? 2524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if relocation target place is readonly, a copy relocation is needed 252522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag(); 252622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE)) 2527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 25285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 25295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 25305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 253222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTDATASymbol() 253322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 253422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTDATA); 253522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 253622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 253722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 253822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTDATASymbol() const 253922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 254022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTDATA); 254122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 254222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 254322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 254422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTBSSSymbol() 254522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 254622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTBSS); 254722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 254822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 254922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 255022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTBSSSymbol() const 255122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 255222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTBSS); 255322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 255422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 255522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 255622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection) 255722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 255822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_bHasTextRel) 255922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 256022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 256122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the target section of the dynamic relocation is ALLOCATE but is not 256222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // writable, than we should set DF_TEXTREL 256322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const uint32_t flag = pSection.flag(); 256422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC)) 256522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasTextRel = true; 256622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 256722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 256822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 256922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 257022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation 257122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initBRIslandFactory() 257222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 257322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pBRIslandFactory) { 257422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pBRIslandFactory = new BranchIslandFactory(maxBranchOffset()); 257522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 257622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 257722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 257822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 257922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation 258022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStubFactory() 258122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 258222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pStubFactory) { 258322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pStubFactory = new StubFactory(); 258422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 258522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 258622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 258722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) 258922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 259022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!mayRelax()) 259122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 259222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 259322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool finished = true; 259422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao do { 25956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (doRelax(pModule, pBuilder, finished)) { 259622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the sections (e.g., .text) are relaxed, the layout is also changed 259722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // We need to do the following: 259822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 259922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. set up the offset 260022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setOutputSectionOffset(pModule, pModule.begin(), pModule.end()); 260122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 260222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. set up the offset constraint of PT_RELRO 260322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) 260422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setupRelro(pModule); 260522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 260622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. set up the output sections' address 26076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setOutputSectionAddress(pModule, pModule.begin(), pModule.end()); 260822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 260922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } while (!finished); 261022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 261122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 261222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 261322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 26146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::needGNUHash(const LDSymbol& X) const 26156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 26166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: in bfd and gold linker, an undefined symbol might be hashed 26176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // when the ouput is not PIC, if the symbol is referred by a non pc-relative 26186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // reloc, and its value is set to the addr of the plt entry. 26196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return !X.resolveInfo()->isUndef() && !X.isDyn(); 26206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 26216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::operator()(const LDSymbol* X, 26236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSymbol* Y) const 26246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 26256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return !needGNUHash(*X) && needGNUHash(*Y); 26266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 26276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2628