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 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 1387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LinkerScript.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h> 16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Config/Config.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h> 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/LDSymbol.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDContext.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h> 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrameHdr.h> 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h> 23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIslandFactory.h> 2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFSegmentFactory.h> 2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFSegment.h> 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/StubFactory.h> 2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFFileFormat.h> 2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFObjectFileFormat.h> 3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFDynObjFileFormat.h> 3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFExecFileFormat.h> 3287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Target/ELFAttribute.h> 3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Target/ELFDynamic.h> 3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Target/GNUInfo.h> 3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/FileOutputBuffer.h> 3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/MsgHandling.h> 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Object/SectionMap.h> 3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/RpnEvaluator.h> 4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/Operand.h> 4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Script/OutputSectDesc.h> 4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Fragment/FillFragment.h> 4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/MC/Attribute.h> 4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 45a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <llvm/ADT/StringRef.h> 4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Host.h> 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 48a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <algorithm> 49a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <cstring> 50a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <cassert> 51a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <map> 52a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <string> 53a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <vector> 54a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace { 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===--------------------------------------------------------------------===// 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesstatic const std::string simple_c_identifier_allowed_chars = 61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "0123456789" 62f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "ABCDEFGHIJKLMNOPWRSTUVWXYZ" 63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "abcdefghijklmnopqrstuvwxyz" 64f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "_"; 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatic bool isCIdentifier(const std::string& pName) 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return (pName.find_first_not_of(simple_c_identifier_allowed_chars) 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines == std::string::npos); 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} // anonymous namespace 74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesusing namespace mcld; 76f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend 79cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 80d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : TargetLDBackend(pConfig), 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pObjectReader(NULL), 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pDynObjFileFormat(NULL), 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pExecFileFormat(NULL), 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectFileFormat(NULL), 86d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pInfo(pInfo), 8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pELFSegmentTable(NULL), 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pBRIslandFactory(NULL), 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pStubFactory(NULL), 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pEhFrameHdr(NULL), 9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pAttribute(NULL), 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasTextRel(false), 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasStaticTLS(false), 94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart(NULL), 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd(NULL), 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart(NULL), 97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd(NULL), 98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart(NULL), 99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd(NULL), 100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack(NULL), 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic(NULL), 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTDATA(NULL), 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTBSS(NULL), 104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart(NULL), 105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText(NULL), 106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText(NULL), 107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText(NULL), 108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData(NULL), 109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData(NULL), 110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart(NULL), 111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd(NULL), 112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End(NULL) { 11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pELFSegmentTable = new ELFSegmentFactory(); 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymIndexMap = new HashTableType(1024); 11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pAttribute = new ELFAttribute(*this, pConfig); 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGNULDBackend::~GNULDBackend() 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 12087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pELFSegmentTable; 121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pInfo; 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynObjFileFormat; 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pExecFileFormat; 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pObjectFileFormat; 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pSymIndexMap; 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pEhFrameHdr; 12787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pAttribute; 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pBRIslandFactory; 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pStubFactory; 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t GNULDBackend::sectionStartOffset() const 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Binary == config().codeGenType()) 135d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0x0; 136d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 137d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch (config().targets().bitclass()) { 138d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 32u: 139d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf32_Ehdr) + 14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().size() * sizeof(llvm::ELF::Elf32_Phdr); 141d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 64u: 142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf64_Ehdr) + 14387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().size() * sizeof(llvm::ELF::Elf64_Phdr); 144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao default: 145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0; 148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesuint64_t GNULDBackend::getSegmentStartAddr(const LinkerScript& pScript) const 152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::AddressMap::const_iterator mapping = 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pScript.addressMap().find(".text"); 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pScript.addressMap().end() != mapping) 15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return mapping.getEntry()->value(); 1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (config().isCodeIndep()) 158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return 0x0; 159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pInfo->defaultTextSegmentAddr(); 161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader* 16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::createArchiveReader(Module& pModule) 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectReader); 16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return new GNUArchiveReader(pModule, *m_pObjectReader); 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 170d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder) 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 172d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectReader = new ELFObjectReader(*this, pBuilder, config()); 17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectReader; 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 176d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder) 177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFDynObjReader(*this, pBuilder, config()); 179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 180d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 181d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder) 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 18387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return new ELFBinaryReader(pBuilder, config()); 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter* GNULDBackend::createWriter() 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 188d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFObjectWriter(*this, config()); 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStdSections(ObjectBuilder& pBuilder) 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pDynObjFileFormat) 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pDynObjFileFormat = new ELFDynObjFileFormat(); 197d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pDynObjFileFormat->initStdSections(pBuilder, 198d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 201d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 202d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pExecFileFormat) 20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pExecFileFormat = new ELFExecFileFormat(); 205d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pExecFileFormat->initStdSections(pBuilder, 206d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pObjectFileFormat) 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectFileFormat = new ELFObjectFileFormat(); 212d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectFileFormat->initStdSections(pBuilder, 213d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols. 22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations. 2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::initStandardSymbols(IRBuilder& pBuilder, 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule) 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // GNU extension: define __start and __stop symbols for the sections whose 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // name can be presented as C symbol 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ref: GNU gold, Layout::define_section_symbols 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator iter, iterEnd = pModule.end(); 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iter = pModule.begin(); iter != iterEnd; ++iter) { 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* section = *iter; 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (section->kind()) { 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: 24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasEhFrame()) 24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasSectionData()) 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of switch 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isCIdentifier(section->name())) { 251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::string start_name = "__start_" + section->name(); 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* start_fragref = FragmentRef::Create( 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->getSectionData()->front(), 0x0); 2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines start_name, 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::NoType, 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Global, 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao start_fragref, // FragRef 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Default); 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 264f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::string stop_name = "__stop_" + section->name(); 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* stop_fragref = FragmentRef::Create( 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->getSectionData()->front(), section->size()); 2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines stop_name, 26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::NoType, 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Global, 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stop_fragref, // FragRef 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Default); 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .preinit_array 283cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* preinit_array = NULL; 284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasPreInitArray()) { 28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Create( 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getPreInitArray().getSectionData()->front(), 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Null(); 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart = 2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__preinit_array_start", 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang preinit_array, // FragRef 301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd = 3036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__preinit_array_end", 305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .init_array 314cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* init_array = NULL; 315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInitArray()) { 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Create( 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getInitArray().getSectionData()->front(), 318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Null(); 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 324affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart = 3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__init_array_start", 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang init_array, // FragRef 333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 334affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd = 3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__init_array_end", 337affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang init_array, // FragRef 343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .fini_array 346cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* fini_array = NULL; 347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasFiniArray()) { 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Create( 34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getFiniArray().getSectionData()->front(), 350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Null(); 35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart = 3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__fini_array_start", 359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fini_array, // FragRef 365affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd = 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__fini_array_end", 369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fini_array, // FragRef 375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .stack 378cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* stack = NULL; 379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasStack()) { 38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Create( 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getStack().getSectionData()->front(), 382affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0); 383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Null(); 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack = 3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__stack", 391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Global, 394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang stack, // FragRef 397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Hidden); 398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // _DYNAMIC 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: add SectionData for .dynamic section, and then we can get the correct 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol section index for _DYNAMIC. Now it will be ABS. 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic = 4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_DYNAMIC", 40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Object, 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Local, 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Hidden); 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart = 4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__executable_start", 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_pEText = 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_p_EText = 4356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_etext", 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 f_p__EText = 4456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__etext", 447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData = 4556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "edata", 457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd = 4666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 4676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "end", 468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _edata is defined forcefully. 477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 186 478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData = 4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_edata", 481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // __bss_start is defined forcefully. 490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 214 491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart = 4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "__bss_start", 494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _end is defined forcefully. 503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // @ref Google gold linker: defstd.cc: 228 504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End = 5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_end", 507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::NoType, 508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Absolute, 510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // size 511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Default); 514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::finalizeStandardSymbols() 519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pPreInitArrayStart) { 527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pPreInitArrayStart->hasFragRef()) { 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->setValue(0x0); 530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pPreInitArrayEnd) { 534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pPreInitArrayEnd->hasFragRef()) { 535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() + 536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getPreInitArray().size()); 537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(0x0); 541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pInitArrayStart) { 545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pInitArrayStart->hasFragRef()) { 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->setValue(0x0); 548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pInitArrayEnd) { 552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pInitArrayEnd->hasFragRef()) { 553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() + 554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getInitArray().size()); 555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(0x0); 559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pFiniArrayStart) { 563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pFiniArrayStart->hasFragRef()) { 564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->setValue(0x0); 566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pFiniArrayEnd) { 570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pFiniArrayEnd->hasFragRef()) { 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() + 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getFiniArray().size()); 573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(0x0); 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pStack) { 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pStack->hasFragRef()) { 582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute); 583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->setValue(0x0); 584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 58722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pDynamic) { 58822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local); 58922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setValue(file_format->getDynamic().addr()); 59022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setSize(file_format->getDynamic().size()); 59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 59222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pExecutableStart) { 59587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::const_iterator exec_start = 59687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, 0x0, 0x0); 59787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != exec_start) { 598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) { 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(f_pExecutableStart->value() + 60087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*exec_start)->vaddr()); 601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(0x0); 605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText || NULL != f_p_EText || NULL !=f_p__EText) { 60887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::const_iterator etext = 60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, 61087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::ELF::PF_X, 61187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::ELF::PF_W); 61287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != etext) { 613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText && ResolveInfo::ThreadLocal != f_pEText->type()) { 614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText->setValue(f_pEText->value() + 61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->vaddr() + 61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->memsz()); 617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EText && ResolveInfo::ThreadLocal != f_p_EText->type()) { 619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText->setValue(f_p_EText->value() + 62087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->vaddr() + 62187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->memsz()); 622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p__EText && ResolveInfo::ThreadLocal != f_p__EText->type()) { 624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText->setValue(f_p__EText->value() + 62587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->vaddr() + 62687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->memsz()); 627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEText) 631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText->setValue(0x0); 632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EText) 633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText->setValue(0x0); 634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p__EText) 635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText->setValue(0x0); 636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData || NULL != f_p_EData || NULL != f_pBSSStart || 640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang NULL != f_pEnd || NULL != f_p_End) { 64187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::const_iterator edata = 64287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, llvm::ELF::PF_W, 0x0); 64387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != edata) { 644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) { 645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData->setValue(f_pEData->value() + 64687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->vaddr() + 64787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->filesz()); 648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) { 650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData->setValue(f_p_EData->value() + 65187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->vaddr() + 65287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->filesz()); 653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pBSSStart && ResolveInfo::ThreadLocal != f_pBSSStart->type()) { 655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart->setValue(f_pBSSStart->value() + 65687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->vaddr() + 65787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->filesz()); 658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) { 661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd->setValue(f_pEnd->value() + 66287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->vaddr() + 66387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->memsz()); 664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) { 666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End->setValue(f_p_End->value() + 66787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->vaddr() + 66887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->memsz()); 669affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEData) 673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData->setValue(0x0); 674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_EData) 675affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData->setValue(0x0); 676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pBSSStart) 677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart->setValue(0x0); 678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_pEnd) 680affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd->setValue(0x0); 681affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != f_p_End) 682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End->setValue(0x0); 683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol) 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ignore if symbol has no fragRef 69222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSymbol.hasFragRef()) 69322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the value of a TLS symbol is the offset to the TLS segment 69687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator tls_seg = 69787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_TLS, llvm::ELF::PF_R, 0x0); 69887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(tls_seg != elfSegmentTable().end()); 69922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t value = pSymbol.fragRef()->getOutputOffset(); 70022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t addr = pSymbol.fragRef()->frag()->getParent()->getSection().addr(); 70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymbol.setValue(value + addr - (*tls_seg)->vaddr()); 70222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFFileFormat* GNULDBackend::getOutputFormat() 706affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 70722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 70822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 70922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pDynObjFileFormat); 71022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 712d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 71322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pExecFileFormat); 71422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 71522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectFileFormat); 71722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 718affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 71922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 721affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 722affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 723affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst ELFFileFormat* GNULDBackend::getOutputFormat() const 725affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pDynObjFileFormat); 72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 731d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pExecFileFormat); 73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != m_pObjectFileFormat); 73622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 737affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 739affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 740affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 741affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 742affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 74387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sizeShstrtab - compute the size of .shstrtab 74487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::sizeShstrtab(Module& pModule) 74587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 74687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t shstrtab = 0; 74787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // compute the size of .shstrtab section. 74887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Module::const_iterator sect, sectEnd = pModule.end(); 74987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = pModule.begin(); sect != sectEnd; ++sect) { 75087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines shstrtab += (*sect)->name().size() + 1; 75187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // end of for 75287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getOutputFormat()->getShStrTab().setSize(shstrtab); 75387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 75487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab, 75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab. 758f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::sizeNamePools(Module& pModule) 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 760f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(LinkerConfig::Unset != config().codePosition()); 761f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // number of entries in symbol tables starts from 1 to hold the special entry 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21. 76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t symtab = 1; 765f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t dynsym = config().isCodeStatic()? 0 : 1; 76622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 76722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size of string tables starts from 1 to hold the null character in their 76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // first byte 7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t strtab = 1; 770f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t dynstr = config().isCodeStatic()? 0 : 1; 7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hash = 0; 7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t gnuhash = 0; 7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // number of local symbol in the .symtab and .dynsym 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symtab_local_cnt = 0; 776d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao size_t dynsym_local_cnt = 0; 777d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd; 7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// Compute the size of .symtab, .strtab, and symtab_local_cnt 78122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 78287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /* TODO: 78387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1. discard locals and temporary locals 78487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2. check whether the symbol is used 78587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 78687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (config().options().getStripSymbolMode()) { 78787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case GeneralOptions::StripAllSymbols: { 78887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab = strtab = 0; 78987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 79087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 79187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: { 79287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symEnd = symbols.end(); 79387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (symbol = symbols.begin(); symbol != symEnd; ++symbol) { 79487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ++symtab; 79587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (hasEntryInStrTab(**symbol)) 79687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtab += (*symbol)->nameSize() + 1; 79787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 79887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab_local_cnt = 1 + symbols.numOfFiles() + symbols.numOfLocals() + 79987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symbols.numOfLocalDyns(); 80087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 80187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 80287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // end of switch 8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 80422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch(config().codeGenType()) { 80722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // soname 80987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines dynstr += config().options().soname().size() + 1; 81022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 81122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /** fall through **/ 812d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 813d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 814f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!config().isCodeStatic()) { 8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// Compute the size of .dynsym, .dynstr, and dynsym_local_cnt 8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.dynamicEnd(); 8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) { 8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dynsym; 819f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*symbol)->nameSize() + 1; 8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynsym_local_cnt = 1 + symbols.numOfLocalDyns(); 8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // compute .gnu.hash 8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::GNU == config().options().getHashStyle() || 8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) { 8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // count the number of dynsym to hash 8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashed_sym_cnt = 0; 8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.dynamicEnd(); 8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.dynamicBegin(); symbol != symEnd; ++symbol) { 8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (DynsymCompare().needGNUHash(**symbol)) 8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++hashed_sym_cnt; 8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Special case for empty .dynsym 8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (hashed_sym_cnt == 0) 8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash = 5 * 4 + config().targets().bitclass() / 8; 8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t nbucket = getHashBucketCount(hashed_sym_cnt, true); 8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash = (4 + nbucket + hashed_sym_cnt) * 4; 8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash += (1U << getGNUHashMaskbitslog2(hashed_sym_cnt)) / 8; 8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 84422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute .hash 8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::SystemV == config().options().getHashStyle() || 8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) { 8476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Both Elf32_Word and Elf64_Word are 4 bytes 8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hash = (2 + getHashBucketCount(dynsym, false) + dynsym) * 8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf32_Word); 8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // add DT_NEEDED 8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 8546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) { 8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*lib)->name().size() + 1; 8576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveNeedEntry(); 8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // add DT_RPATH 8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().getRpathList().empty()) { 8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveNeedEntry(); 8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::const_rpath_iterator rpath, 8656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rpathEnd = config().options().rpath_end(); 8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (rpath = config().options().rpath_begin(); 8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rpath != rpathEnd; ++rpath) 8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*rpath).size() + 1; 8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set size 8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setSize(dynsym * 8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf32_Sym)); 8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setSize(dynsym * 8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf64_Sym)); 8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynStrTab().setSize(dynstr); 8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getHashTab().setSize(hash); 8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getGNUHashTab().setSize(gnuhash); 8826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .dynsym sh_info to one greater than the symbol table 8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // index of the last local symbol 8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setInfo(dynsym_local_cnt); 8866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Because some entries in .dynamic section need information of .dynsym, 8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED 8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // entries until we get the size of the sections mentioned above 8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveEntries(*file_format); 8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynamic().setSize(dynamic().numOfBytes()); 8926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /* fall through */ 89522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 896d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym)); 8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym)); 9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getStrTab().setSize(strtab); 901d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 902d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // set .symtab sh_info to one greater than the symbol table 903d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // index of the last local symbol 9046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getSymTab().setInfo(symtab_local_cnt); 9056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 90687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The size of .shstrtab should be decided after output sections are all 90787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set, so we just set it to 1 here. 90887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines file_format->getShStrTab().setSize(0x1); 9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 91122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 91222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::fatal_illegal_codegen_type) << pModule.name(); 91322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end of switch 91522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 91722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol 91822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym, 91922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 92022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 92122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 92222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx) 92322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 92422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check the endian between host and target 92522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out symbol 926f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(pSymbol)) { 92722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = pStrtabsize; 92822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((pStrtab + pStrtabsize), pSymbol.name()); 92922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 93022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 93122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = 0; 93222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 93322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_value = pSymbol.value(); 93422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_size = getSymbolSize(pSymbol); 93522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_info = getSymbolInfo(pSymbol); 93622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_other = pSymbol.visibility(); 93722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_shndx = getSymbolShndx(pSymbol); 93822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 93922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 94022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol 94122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym, 94222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 94322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 94422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 94522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx) 94622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 94722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check the endian between host and target 94822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out symbol 949f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(pSymbol)) { 9506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSym.st_name = pStrtabsize; 9516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strcpy((pStrtab + pStrtabsize), pSymbol.name()); 9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSym.st_name = 0; 9556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 95622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_value = pSymbol.value(); 95722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_size = getSymbolSize(pSymbol); 95822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_info = getSymbolInfo(pSymbol); 95922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_other = pSymbol.visibility(); 96022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_shndx = getSymbolShndx(pSymbol); 9615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab 9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 9665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 96722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule, 96887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FileOutputBuffer& pOutput) 9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 97022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 97187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!file_format->hasSymTab()) 97287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 9735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getSymTab(); 9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getStrTab(); 9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 97787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion symtab_region = pOutput.request(symtab_sect.offset(), 97887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab_sect.size()); 97987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion strtab_region = pOutput.request(strtab_sect.offset(), 98087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtab_sect.size()); 9815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 9845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 985d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 98687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin(); 987d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 98887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin(); 989d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 990d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 991d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 992d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 993d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 9945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 99587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines char* strtab = (char*)strtab_region.begin(); 9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit the first ELF symbol 9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) 9996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0); 10006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0); 10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 100322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool sym_exist = false; 100422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao HashTableType::entry_type* entry = NULL; 100522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 10066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry = m_pSymIndexMap->insert(LDSymbol::Null(), sym_exist); 100722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(0); 100822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 100922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symIdx = 1; 10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 10126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Module::SymbolTable& symbols = pModule.getSymbolTable(); 10146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd; 10156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.end(); 10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.begin(); symbol != symEnd; ++symbol) { 101822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 101922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry->setValue(symIdx); 10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1022d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 10236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx); 102422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx); 10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symIdx; 1027f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 102822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 103222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 10345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 103687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput) 10375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 103822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!file_format->hasDynSymTab() || 104022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynStrTab() || 104122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynamic()) 104222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 10435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 10455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 10465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 10485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& dyn_sect = file_format->getDynamic(); 10505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 105187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion symtab_region = pOutput.request(symtab_sect.offset(), 105287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab_sect.size()); 105387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion strtab_region = pOutput.request(strtab_sect.offset(), 105487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtab_sect.size()); 105587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion dyn_region = pOutput.request(dyn_sect.offset(), 105687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines dyn_sect.size()); 10575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 10585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 10595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 1060d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 106187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin(); 1062d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 106387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin(); 1064d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 1065d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 1066d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 1067d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 10685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 107087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines char* strtab = (char*)strtab_region.begin(); 10715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit the first ELF symbol 10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) 10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0); 10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0); 10775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symIdx = 1; 10795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 10805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 10826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .gnu.hash 10836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::GNU == config().options().getHashStyle() || 1084f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) 10856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitGNUHashTab(symbols, pOutput); 1086f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .hash 10886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (GeneralOptions::SystemV == config().options().getHashStyle() || 10896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) 10906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitELFHashTab(symbols, pOutput); 10916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category) 10936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = symbols.dynamicEnd(); 10946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) { 1095d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx); 109722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx); 10995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // maintain output's symbol and index map 11005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry->setValue(symIdx); 110222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sum up counters 11036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symIdx; 1104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 110522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 11065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 11075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 11095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 11105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 111122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 111222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) { 11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strcpy((strtab + strtabsize), (*lib)->name().c_str()); 11156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 11166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtabsize += (*lib)->name().size() + 1; 11176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dt_need; 11186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().getRpathList().empty()) { 11226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().hasNewDTags()) 11236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_RPATH, strtabsize); 11246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 11256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_RUNPATH, strtabsize); 11266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dt_need; 11276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::const_rpath_iterator rpath, 11296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rpathEnd = config().options().rpath_end(); 11306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (rpath = config().options().rpath_begin(); rpath != rpathEnd; ++rpath) { 11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy((strtab + strtabsize), (*rpath).data(), (*rpath).size()); 11326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtabsize += (*rpath).size(); 11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtab[strtabsize++] = (rpath + 1 == rpathEnd ? '\0' : ':'); 11345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 113522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 113822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 113922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set pointer to SONAME entry in dynamic string table. 1140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dynamic().applySoname(strtabsize); 114122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynamic().applyEntries(*file_format); 114387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines dynamic().emit(dyn_sect, dyn_region); 11445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 114522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit soname 114622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 114787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strcpy((strtab + strtabsize), config().options().soname().c_str()); 114887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtabsize += config().options().soname().size() + 1; 114922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 11515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitELFHashTab - emit .hash 11536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitELFHashTab(const Module::SymbolTable& pSymtab, 115487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FileOutputBuffer& pOutput) 11556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 11566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 11576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!file_format->hasHashTab()) 11586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 11596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& hash_sect = file_format->getHashTab(); 116087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion hash_region = pOutput.request(hash_sect.offset(), 116187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines hash_sect.size()); 11625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 11635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 116487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* word_array = (uint32_t*)hash_region.begin(); 11655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 11665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nchain = word_array[1]; 11675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t dynsymSize = 1 + pSymtab.numOfLocalDyns() + pSymtab.numOfDynamics(); 11696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nbucket = getHashBucketCount(dynsymSize, false); 11706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nchain = dynsymSize; 11715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 11735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* chain = (bucket + nbucket); 11745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 1176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memset((void*)bucket, 0, nbucket); 11775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines hash::StringHash<hash::ELF> hash_func; 11795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t idx = 1; 11816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd(); 11826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.localDynBegin(); symbol != symEnd; ++symbol) { 11836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::StringRef name((*symbol)->name()); 11846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t bucket_pos = hash_func(name) % nbucket; 11856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain[idx] = bucket[bucket_pos]; 11866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[bucket_pos] = idx; 11876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++idx; 11886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 11906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitGNUHashTab - emit .gnu.hash 11926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitGNUHashTab(Module::SymbolTable& pSymtab, 119387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FileOutputBuffer& pOutput) 11946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 11956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 11966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!file_format->hasGNUHashTab()) 11976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 11986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 119987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion gnuhash_region = 12006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pOutput.request(file_format->getGNUHashTab().offset(), 12016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getGNUHashTab().size()); 12026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 120387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* word_array = (uint32_t*)gnuhash_region.begin(); 12046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // fixed-length fields 12056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& nbucket = word_array[0]; 12066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& symidx = word_array[1]; 12076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& maskwords = word_array[2]; 12086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& shift2 = word_array[3]; 12096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // variable-length fields 12106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t* bitmask = (uint8_t*)(word_array + 4); 12116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* bucket = NULL; 12126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* chain = NULL; 12136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // count the number of dynsym to hash 12156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t unhashed_sym_cnt = pSymtab.numOfLocalDyns(); 12166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashed_sym_cnt = pSymtab.numOfDynamics(); 12176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd(); 12186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.dynamicBegin(); symbol != symEnd; ++symbol) { 12196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (DynsymCompare().needGNUHash(**symbol)) 12206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 12216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++unhashed_sym_cnt; 12226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines --hashed_sym_cnt; 12236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // special case for the empty hash table 12266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (hashed_sym_cnt == 0) { 12276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nbucket = 1; // one empty bucket 12286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symidx = 1 + unhashed_sym_cnt; // symidx above unhashed symbols 12296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskwords = 1; // bitmask length 12306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shift2 = 0; // bloom filter 12316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 12336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* maskval = (uint32_t*)bitmask; 12346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *maskval = 0; // no valid hashes 12356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 12366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be 64 12376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t* maskval = (uint64_t*)bitmask; 12386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *maskval = 0; // no valid hashes 12395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket = (uint32_t*)(bitmask + config().targets().bitclass() / 8); 12416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *bucket = 0; // no hash in the only bucket 12426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 12435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbitslog2 = getGNUHashMaskbitslog2(hashed_sym_cnt); 12466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbits = 1u << maskbitslog2; 12476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shift1 = config().targets().is32Bits() ? 5 : 6; 12486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t mask = (1u << shift1) - 1; 12496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nbucket = getHashBucketCount(hashed_sym_cnt, true); 12516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symidx = 1 + unhashed_sym_cnt; 12526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskwords = 1 << (maskbitslog2 - shift1); 12536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shift2 = maskbitslog2; 12546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // setup bucket and chain 12566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket = (uint32_t*)(bitmask + maskbits / 8); 12576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain = (bucket + nbucket); 12586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // build the gnu style hash table 12606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef std::multimap<uint32_t, 12616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::pair<LDSymbol*, uint32_t> > SymMapType; 12626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines SymMapType symmap; 12636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = pSymtab.dynamicEnd(); 12646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.localDynBegin() + symidx - 1; symbol != symEnd; 12656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symbol) { 1266f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines hash::StringHash<hash::DJB> hasher; 12676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t djbhash = hasher((*symbol)->name()); 12686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t hash = djbhash % nbucket; 12696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symmap.insert(std::make_pair(hash, std::make_pair(*symbol, djbhash))); 12706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // compute bucket, chain, and bitmask 12736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::vector<uint64_t> bitmasks(maskwords); 12746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashedidx = symidx; 12756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < nbucket; ++idx) { 12766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t count = 0; 12776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::pair<SymMapType::iterator, SymMapType::iterator> ret; 12786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ret = symmap.equal_range(idx); 12796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (SymMapType::iterator it = ret.first; it != ret.second; ) { 12806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // rearrange the hashed symbol ordering 12816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *(pSymtab.localDynBegin() + hashedidx - 1) = it->second.first; 12826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t djbhash = it->second.second; 12836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t val = ((djbhash >> shift1) & ((maskbits >> shift1) - 1)); 12846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bitmasks[val] |= 1u << (djbhash & mask); 12856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bitmasks[val] |= 1u << ((djbhash >> shift2) & mask); 12866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines val = djbhash & ~1u; 12876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // advance the iterator and check if we're dealing w/ the last elment 12886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (++it == ret.second) { 12896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // last element terminates the chain 12906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines val |= 1; 12916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain[hashedidx - symidx] = val; 12936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++hashedidx; 12956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++count; 12965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (count == 0) 12996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[idx] = 0; 13006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 13016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[idx] = hashedidx - count; 13026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 13036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 13046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // write the bitmasks 13056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 13066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t* maskval = (uint32_t*)bitmask; 13076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t i = 0; i < maskwords; ++i) 13086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(maskval + i, &bitmasks[i], 4); 13096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 13106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be 64 13116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t* maskval = (uint64_t*)bitmask; 13126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t i = 0; i < maskwords; ++i) 13136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(maskval + i, &bitmasks[i], 8); 13145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 13155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 13165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section 131822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::sizeInterp() 1319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 1320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const char* dyld_name; 132122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 132222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 1323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 13246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dyld_name = m_pInfo->dyld(); 1325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 132622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& interp = getOutputFormat()->getInterp(); 1327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang interp.setSize(std::strlen(dyld_name) + 1); 1328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp 133187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitInterp(FileOutputBuffer& pOutput) 1332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 133322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasInterp()) { 133422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& interp = getOutputFormat()->getInterp(); 133587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion region = pOutput.request(interp.offset(), interp.size()); 133622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* dyld_name; 133722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 133822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 133922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 13406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dyld_name = m_pInfo->dyld(); 1341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 134287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::memcpy(region.begin(), dyld_name, interp.size()); 134322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool GNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const 1347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 1348f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ResolveInfo::Section != pSym.type(); 1349f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 1350f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1351f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::orderSymbolTable(Module& pModule) 1352f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 1353f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 1354f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (GeneralOptions::GNU == config().options().getHashStyle() || 1356f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) 1357f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Currently we may add output symbols after sizeNamePools(), and a 1358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // non-stable sort is used in SymbolCategory::arrange(), so we just 1359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort .dynsym right before emitting .gnu.hash 1360f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(), 1361f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines DynsymCompare()); 1362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 1363f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 13645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder 136522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaounsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const 13665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 136722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 136822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // NULL section should be the "1st" section 13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (LDFileFormat::Null == pSectHdr.kind()) 137187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return SHO_NULL; 13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 137322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getStrTab()) 137422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_STRTAB; 137522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if the section is not ALLOC, lay it out until the last possible moment 13775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC)) 13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 13795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0; 13815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0; 13825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: need to take care other possible output sections 13835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pSectHdr.kind()) { 1384a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines case LDFileFormat::TEXT: 1385a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines case LDFileFormat::DATA: 13865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (is_exec) { 13875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getInit()) 13885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_INIT; 13895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getFini()) 13905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_FINI; 13915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_TEXT; 13925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else if (!is_write) { 13935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RO; 13945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 139522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 139622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getPreInitArray() || 139722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getInitArray() || 139822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getFiniArray() || 1399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getCtors() || 1400affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getDtors() || 1401affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getJCR() || 1402d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao &pSectHdr == &file_format->getDataRelRo()) 1403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 1404d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (&pSectHdr == &file_format->getDataRelRoLocal()) 1405affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO_LOCAL; 1406affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 140722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) { 140822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_DATA; 140922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 14115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::BSS: 141422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) 141522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_BSS; 14165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_BSS; 14175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 141822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::NamePool: { 14195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getDynamic()) 14205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO; 14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NAMEPOOL; 142222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Relocation: 14245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getRelPlt() || 14255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &pSectHdr == &file_format->getRelaPlt()) 14265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_REL_PLT; 14275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELOCATION; 14285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get the order from target for target specific sections 14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Target: 143122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return getTargetSectionOrder(pSectHdr); 14325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // handle .interp and .note.* sections 14345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Note: 14356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (file_format->hasInterp() && (&pSectHdr == &file_format->getInterp())) 14366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_INTERP; 14376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (is_write) 14386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RW_NOTE; 14396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 14406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RO_NOTE; 14415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrame: 1443f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set writable .eh_frame as relro 1444f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (is_write) 1445f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO; 1446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrameHdr: 1447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::GCCExceptTable: 1448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_EXCEPTION; 14495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::MetaData: 14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Debug: 14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize 14585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const 14595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // @ref Google gold linker: symtab.cc: 2780 14615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // undefined and dynamic symbols should have zero size. 14625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined) 14635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 14645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.resolveInfo()->size(); 14655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo 14685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const 14695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set binding 14715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t bind = 0x0; 14725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isLocal()) 14735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isGlobal()) 14755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isWeak()) 14775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_WEAK; 14785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isAbsolute()) { 14795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // (Luba) Is a absolute but not global (weak or local) symbol meaningful? 14805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1483d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().codeGenType() != LinkerConfig::Object && 1484d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (pSymbol.visibility() == llvm::ELF::STV_INTERNAL || 1485d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pSymbol.visibility() == llvm::ELF::STV_HIDDEN)) 14865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t type = pSymbol.resolveInfo()->type(); 1489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change 1490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // its type to Function 1491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn()) 1492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang type = ResolveInfo::Function; 1493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (type | (bind << 4)); 14945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout() 14975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const 14985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn()) 15005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 15015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.value(); 15035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 15045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout() 15065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t 150722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const 15085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 15095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isAbsolute()) 15105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_ABS; 15115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isCommon()) 15125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_COMMON; 15135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn()) 15145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_UNDEF; 15155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 151622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef()) 151722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return llvm::ELF::SHN_ABS; 151822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pSymbol.hasFragRef() && "symbols must have fragment reference to get its index"); 152022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return pSymbol.fragRef()->frag()->getParent()->getSection().index(); 15215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 15225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index 15246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinessize_t GNULDBackend::getSymbolIdx(const LDSymbol* pSymbol) const 15255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 15266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HashTableType::iterator entry = m_pSymIndexMap->find(const_cast<LDSymbol *>(pSymbol)); 15276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(entry != m_pSymIndexMap->end() && "symbol not found in the symbol table"); 15285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return entry.getEntry()->value(); 15295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 15305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isTemporary - Whether pSymbol is a local label. 15326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::isTemporary(const LDSymbol& pSymbol) const 15336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 15346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (ResolveInfo::Local != pSymbol.binding()) 15356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSymbol.nameSize() < 2) 15386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* name = pSymbol.name(); 15416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ('.' == name[0] && 'L' == name[1]) 15426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 15436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // UnixWare 2.1 cc generate DWARF debugging symbols with `..' prefix. 15456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name() 15466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (name[0] == '.' && name[1] == '.') 15476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 15486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Work arround for gcc's bug 15506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // gcc sometimes generate symbols with '_.L_' prefix. 15516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // @ref Google gold linker, target.cc:39 @@ Target::do_is_local_label_name() 15526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSymbol.nameSize() < 4) 15536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_') 15566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 15576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 15596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 15606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding 156222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage. 1563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @refer Google gold linker: common.cc: 214 1564affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool 156522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNULDBackend::allocateCommonSymbols(Module& pModule) 15665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 156722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymbolCategory& symbol_list = pModule.getSymbolTable(); 1568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (symbol_list.emptyCommons() && symbol_list.emptyFiles() && 15706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symbol_list.emptyLocals() && symbol_list.emptyLocalDyns()) 1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 1572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 1574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: If the order of common symbols is defined, then sort common symbols 1576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // std::sort(com_sym, com_end, some kind of order); 1577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 157822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get corresponding BSS LDSection 157922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 158022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& bss_sect = file_format->getBSS(); 158122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& tbss_sect = file_format->getTBSS(); 1582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1583cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 158422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_sect_data = NULL; 158522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect.hasSectionData()) 158622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = bss_sect.getSectionData(); 158722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 158822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 158922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 159022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* tbss_sect_data = NULL; 159122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (tbss_sect.hasSectionData()) 159222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = tbss_sect.getSectionData(); 159322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 159422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 1595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 159722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t bss_offset = bss_sect.size(); 159822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tbss_offset = tbss_sect.size(); 1599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all local common symbols 1601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.localEnd(); 1602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 1604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::Common == (*com_sym)->desc()) { 1605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1611cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 1612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 161522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 161622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 161722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1618551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 161987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 162222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 162322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 162422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1625551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 162687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 16305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all global common symbols 1632affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.commonEnd(); 1633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 1634affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1637affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1639affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1640cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 1641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 164422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 164522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 164622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1647551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 164887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 165122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 165222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 165322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 1654551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 165587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 165922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect.setSize(bss_offset); 166022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect.setSize(tbss_offset); 1661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang symbol_list.changeCommonsToGlobal(); 1662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 16635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 16645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// updateSectionFlags - update pTo's flags when merging pFrom 16666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// update the output section flags based on input section flags. 16676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref The Google gold linker: 16686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// output.cc: 2809: Output_section::update_flags_for_input_section 16696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::updateSectionFlags(LDSection& pTo, const LDSection& pFrom) 16706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 16716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // union the flags from input 16726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t flags = pTo.flag(); 16736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags |= (pFrom.flag() & 16746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (llvm::ELF::SHF_WRITE | 16756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHF_ALLOC | 16766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHF_EXECINSTR)); 16776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is an input section is not SHF_MERGE, clean this flag 16796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == (pFrom.flag() & llvm::ELF::SHF_MERGE)) 16806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags &= ~llvm::ELF::SHF_MERGE; 16816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is an input section is not SHF_STRINGS, clean this flag 16836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == (pFrom.flag() & llvm::ELF::SHF_STRINGS)) 16846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags &= ~llvm::ELF::SHF_STRINGS; 16856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pTo.setFlag(flags); 16876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 16886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 169087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rel entry 169187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel, 169287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 169387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 169487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset) const 169587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 169687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t r_info = 0x0; 169787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 169887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 169987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = pRel.r_info; 170087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 170187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 170287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap32(pRel.r_offset); 170387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = mcld::bswap32(pRel.r_info); 170487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 170587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 170687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<unsigned char>(r_info); 170787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 8); 170887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 170987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 171087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 171187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rela entry 171287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel, 171387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 171487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 171587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset, 171687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t& pAddend) const 171787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 171887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t r_info = 0x0; 171987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 172087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 172187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = pRel.r_info; 172287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = pRel.r_addend; 172387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 172487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 172587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap32(pRel.r_offset); 172687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = mcld::bswap32(pRel.r_info); 172787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = mcld::bswap32(pRel.r_addend); 172887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 172987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 173087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<unsigned char>(r_info); 173187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 8); 173287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 173387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 173487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 173587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF64_Rel entry 173687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel, 173787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 173887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 173987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t& pOffset) const 174087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 174187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 174287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 174387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 174487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = pRel.r_info; 174587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 174687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 174787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 174887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = mcld::bswap64(pRel.r_info); 174987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 175087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 175187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<uint32_t>(r_info); 175287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 32); 175387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 175487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 175587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 175687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRel - read ELF64_Rela entry 175787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel, 175887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 175987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 176087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t& pOffset, 176187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int64_t& pAddend) const 176287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 176387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 176487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 176587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 176687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = pRel.r_info; 176787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = pRel.r_addend; 176887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 176987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 177087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 177187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = mcld::bswap64(pRel.r_info); 177287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = mcld::bswap64(pRel.r_addend); 177387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 177487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 177587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<uint32_t>(r_info); 177687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 32); 177787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 177887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 177987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 178087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rel entry 178187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel, 178287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 178387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 178487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset) const 178587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 178687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 178787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 178887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 178987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 179087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rela entry 179187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel, 179287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 179387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 179487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset, 179587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t pAddend) const 179687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 179787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 179887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_addend = pAddend; 179987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 180087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 180187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 180287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rel entry 180387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel, 180487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 180587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 180687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset) const 180787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 180887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 180987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 181087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 181187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 181287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rela entry 181387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel, 181487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 181587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 181687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset, 181787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int64_t pAddend) const 181887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 181987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 182087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_addend = pAddend; 182187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 182287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 182387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 18245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers 18256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::createProgramHdrs(Module& pModule) 18265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 182722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat *file_format = getOutputFormat(); 1828affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 18295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_INTERP 1830affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInterp()) { 183187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // make PT_PHDR 183287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().produce(llvm::ELF::PT_PHDR); 183387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 183487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* interp_seg = elfSegmentTable().produce(llvm::ELF::PT_INTERP); 183587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines interp_seg->append(&file_format->getInterp()); 1836affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1837affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 183887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t cur_flag, prev_flag = 0x0; 18395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment* load_seg = NULL; 18405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make possible PT_LOAD segments 184187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript& ldscript = pModule.getScript(); 184287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript::AddressMap::iterator addrEnd= ldscript.addressMap().end(); 184387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, prev, outBegin, outEnd; 184487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = ldscript.sectionMap().begin(); 184587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = ldscript.sectionMap().end(); 184687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin, prev = outEnd; out != outEnd; prev = out, ++out) { 184787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* sect = (*out)->getSection(); 184887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 184987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (0 == (sect->flag() & llvm::ELF::SHF_ALLOC) && 185087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDFileFormat::Null != sect->kind()) 185187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 1852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 185387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // bypass empty sections 185487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!(*out)->hasContent() && 185587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() != LDFileFormat::Null) 18565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 18575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 185887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur_flag = getSegmentFlag(sect->flag()); 185922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool createPT_LOAD = false; 186087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LDFileFormat::Null == sect->kind()) { 186122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. create text segment 186222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 186322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 186422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (!config().options().omagic() && 186522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) { 186622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. create data segment if w/o omagic set 186722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 186822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 186987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (sect->kind() == LDFileFormat::BSS && 187022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->isDataSegment() && 187187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addrEnd != ldscript.addressMap().find(".bss")) { 187222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. create bss segment if w/ -Tbss and there is a data segment 187322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 187422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 187587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if ((sect != &(file_format->getText())) && 187687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (sect != &(file_format->getData())) && 187787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (sect != &(file_format->getBSS())) && 187887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (addrEnd != ldscript.addressMap().find(sect->name()))) { 187987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 4. create PT_LOAD for sections in address map except for text, data, 188087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // and bss 188187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines createPT_LOAD = true; 188287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 188387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (LDFileFormat::Null == (*prev)->getSection()->kind() && 188487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines !config().options().getScriptList().empty()) { 188587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 5. create PT_LOAD to hold NULL section if there is a default ldscript 188687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines createPT_LOAD = true; 188722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 18885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 188922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (createPT_LOAD) { 189022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create new PT_LOAD segment 189187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines load_seg = elfSegmentTable().produce(llvm::ELF::PT_LOAD, cur_flag); 18926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().nmagic() && !config().options().omagic()) 18936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines load_seg->setAlign(abiPageSize()); 18945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != load_seg); 189787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines load_seg->append(sect); 189822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cur_flag != prev_flag) 189922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->updateFlag(cur_flag); 19005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 190122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao prev_flag = cur_flag; 19025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 19035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 19045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_DYNAMIC 1905affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasDynamic()) { 190687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* dyn_seg = elfSegmentTable().produce(llvm::ELF::PT_DYNAMIC, 1907affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_R | 1908affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::PF_W); 190987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines dyn_seg->append(&file_format->getDynamic()); 1910affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1911affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 191222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 1913affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_RELRO 191487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* relro_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_RELRO); 191522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 191687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) { 191787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::PT_LOAD != (*seg)->type()) 191822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 191922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 192087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (ELFSegment::iterator sect = (*seg)->begin(), 192187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectEnd = (*seg)->end(); sect != sectEnd; ++sect) { 192222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao unsigned int order = getSectionOrder(**sect); 192322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (SHO_RELRO_LOCAL == order || 192422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SHO_RELRO == order || 192522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SHO_RELRO_LAST == order) { 192687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines relro_seg->append(*sect); 192722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1928affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1929affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 19305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 19315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1932affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_EH_FRAME 1933affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasEhFrameHdr()) { 193487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* eh_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_EH_FRAME); 193587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_seg->append(&file_format->getEhFrameHdr()); 1936affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 193722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 193822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_TLS 193922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData() || file_format->hasTBSS()) { 194087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* tls_seg = elfSegmentTable().produce(llvm::ELF::PT_TLS); 194122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData()) 194287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines tls_seg->append(&file_format->getTData()); 194322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTBSS()) 194487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines tls_seg->append(&file_format->getTBSS()); 194522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 194622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 194722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_GNU_STACK 194822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasStackNote()) { 194987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().produce(llvm::ELF::PT_GNU_STACK, 195022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_R | 195122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::PF_W | 195222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getSegmentFlag(file_format->getStackNote().flag())); 195322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 195422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 19556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // make PT_NOTE 19566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFSegment *note_seg = NULL; 195787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines prev_flag = 0x0; 195887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Module::iterator sect, sectBegin, sectEnd; 195987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectBegin = pModule.begin(); 196087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectEnd = pModule.end(); 196187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = sectBegin; sect != sectEnd; ++sect) { 196287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*sect)->type() != llvm::ELF::SHT_NOTE || 19636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*sect)->flag() & llvm::ELF::SHF_ALLOC) == 0) 19646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines continue; 19656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 19666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines cur_flag = getSegmentFlag((*sect)->flag()); 19676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // we have different section orders for read-only and writable notes, so 19686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // create 2 segments if needed. 19696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (note_seg == NULL || 19706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (cur_flag & llvm::ELF::PF_W) != (prev_flag & llvm::ELF::PF_W)) 197187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines note_seg = elfSegmentTable().produce(llvm::ELF::PT_NOTE, cur_flag); 19726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 197387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines note_seg->append(*sect); 19746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines prev_flag = cur_flag; 19756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 19766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 197722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create target dependent segments 19786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines doCreateProgramHdrs(pModule); 1979affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1980affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1981affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments 1982f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid GNULDBackend::setupProgramHdrs(const LinkerScript& pScript) 1983affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 19845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // update segment info 198587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 198687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines segEnd = elfSegmentTable().end(); seg != segEnd; ++seg) { 198787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 198887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // bypass if there is no section in this segment (e.g., PT_GNU_STACK) 198987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->size() == 0) 199087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 199187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 199287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // bypass the PT_LOAD that only has NULL section now 199387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->type() == llvm::ELF::PT_LOAD && 199487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->front()->kind() == LDFileFormat::Null && 199587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->size() == 1) 199687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 199787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 199887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setOffset((*seg)->front()->offset()); 199987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->type() == llvm::ELF::PT_LOAD && 200087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->front()->kind() == LDFileFormat::Null) { 200187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const LDSection* second = *((*seg)->begin() + 1); 200287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(second != NULL); 200387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setVaddr(second->addr() - second->offset()); 200487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 200587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setVaddr((*seg)->front()->addr()); 200687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 200787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setPaddr((*seg)->vaddr()); 200887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 200987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment::reverse_iterator sect, sectREnd = (*seg)->rend(); 201087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = (*seg)->rbegin(); sect != sectREnd; ++sect) { 201187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*sect)->kind() != LDFileFormat::BSS) 201287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 201387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 201487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (sect != sectREnd) { 201587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setFilesz((*sect)->offset() + 201687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*sect)->size() - 201787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->offset()); 201887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 201987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setFilesz(0x0); 202087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 202187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 202287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setMemsz((*seg)->back()->addr() + 202387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->back()->size() - 202487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->vaddr()); 202587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // end of for 202687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 202787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // handle the case if text segment only has NULL section 202887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* null_sect = &getOutputFormat()->getNULLSection(); 202987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator null_seg = 203087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect); 203187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 203287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*null_seg)->size() == 1) { 203387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // find 2nd PT_LOAD 203487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end(); 203587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (seg = null_seg + 1; seg != segEnd; ++seg) { 203687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->type() == llvm::ELF::PT_LOAD) 203787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 203887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 203987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (seg != segEnd) { 204087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t addr = (*seg)->front()->addr() - (*seg)->front()->offset(); 204187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t size = sectionStartOffset(); 204287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (addr + size == (*seg)->front()->addr()) { 204387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // if there is no space between the 2 segments, we can merge them. 204487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setOffset(0x0); 204587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setVaddr(addr); 204687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setPaddr(addr); 204787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 204887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment::iterator sect, sectEnd = (*seg)->end(); 204987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = (*seg)->begin(); sect != sectEnd; ++sect) { 205087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*sect)->kind() == LDFileFormat::BSS) { 205187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines --sect; 205287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 205387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 205487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 205587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (sect == sectEnd) { 205687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setFilesz((*seg)->back()->offset() + 205787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->back()->size() - 205887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->offset()); 205987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if (*sect != (*seg)->front()) { 206087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines --sect; 206187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setFilesz((*sect)->offset() + 206287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*sect)->size() - 206387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->offset()); 206487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 206587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setFilesz(0x0); 206687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 206787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 206887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setMemsz((*seg)->back()->addr() + 206987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->back()->size() - 207087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->vaddr()); 207187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 207287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->insert((*seg)->begin(), null_sect); 207387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().erase(null_seg); 207487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 207587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if (addr + size < (*seg)->vaddr()) { 207687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setOffset(0x0); 207787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setVaddr(addr); 207887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setPaddr(addr); 207987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setFilesz(size); 208087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setMemsz(size); 208187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 208287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // erase the non valid segment contains NULL. 208387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().erase(null_seg); 208487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 208587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 208687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 208787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 208887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up PT_PHDR 208987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator phdr = 209087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_PHDR, llvm::ELF::PF_R, 0x0); 209187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 209287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (phdr != elfSegmentTable().end()) { 209387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator null_seg = 209487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect); 209587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (null_seg != elfSegmentTable().end()) { 209687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t offset = 0x0, phdr_size = 0x0; 2097d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) { 20985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf32_Ehdr); 20995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf32_Phdr); 210087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 21015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf64_Ehdr); 21025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf64_Phdr); 21035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 210487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setOffset(offset); 210587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setVaddr((*null_seg)->vaddr() + offset); 210687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setPaddr((*phdr)->vaddr()); 210787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setFilesz(elfSegmentTable().size() * phdr_size); 210887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setMemsz(elfSegmentTable().size() * phdr_size); 210987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setAlign(config().targets().bitclass() / 8); 211087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 211187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().erase(phdr); 21125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 21135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 21145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 21155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 211687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// getSegmentFlag - give a section flag and return the corresponding segment 211787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// flag 211887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesuint32_t GNULDBackend::getSegmentFlag(const uint32_t pSectionFlag) 211987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 212087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t flag = 0x0; 212187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pSectionFlag & llvm::ELF::SHF_ALLOC) != 0x0) 212287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag |= llvm::ELF::PF_R; 212387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pSectionFlag & llvm::ELF::SHF_WRITE) != 0x0) 212487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag |= llvm::ELF::PF_W; 212587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pSectionFlag & llvm::ELF::SHF_EXECINSTR) != 0x0) 212687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag |= llvm::ELF::PF_X; 212787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return flag; 212887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 212987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 213022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output 2131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: layout.cc:2608 21326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::setupGNUStackInfo(Module& pModule) 21335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t flag = 0x0; 213522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasStackSet()) { 2136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 1. check the command line option (-z execstack or -z noexecstack) 213722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasExecStack()) 2138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 213922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 214022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 2141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. check the stack info from the input objects 214222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: since we alway emit .note.GNU-stack in output now, we may be able 214322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to check this from the output .note.GNU-stack directly after section 214422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // merging is done 2145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang size_t object_count = 0, stack_note_count = 0; 214622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_obj_iterator obj, objEnd = pModule.obj_end(); 214722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (obj = pModule.obj_begin(); obj != objEnd; ++obj) { 214822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++object_count; 214922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack"); 215022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != sect) { 215122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++stack_note_count; 215222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2.1 found a stack note that is set as executable 215322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) { 215422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao flag = llvm::ELF::SHF_EXECINSTR; 215522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 2156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 21595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.2 there are no stack note sections in all input objects 2161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == stack_note_count) 2162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 21635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.3 a special case. Use the target default to decide if the stack should 2165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // be executable 2166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count) 21676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_pInfo->isDefaultExecStack()) 2168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 21695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 21705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 217122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasStackNote()) { 217222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getOutputFormat()->getStackNote().setFlag(flag); 217322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 217422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 217522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 217687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionOffset - helper function to set output sections' offset. 217787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::setOutputSectionOffset(Module& pModule) 217822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 217987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript& script = pModule.getScript(); 218087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t offset = 0x0; 218187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* cur = NULL; 218287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* prev = NULL; 218387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 218487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = script.sectionMap().begin(); 218587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = script.sectionMap().end(); 218687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; ++out, prev = cur) { 218787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur = (*out)->getSection(); 218887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (cur->kind() == LDFileFormat::Null) { 218987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(0x0); 219087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 219187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 219222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 219387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (prev->kind()) { 219487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case LDFileFormat::Null: 219587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = sectionStartOffset(); 219687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 219787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case LDFileFormat::BSS: 219887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = prev->offset(); 219987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 220087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: 220187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = prev->offset() + prev->size(); 220222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 220322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 220487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(offset, cur->align()); 220587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(offset); 220687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 220787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 220887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 220987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionAddress - helper function to set output sections' address. 221087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::setOutputSectionAddress(Module& pModule) 221187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 221287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines RpnEvaluator evaluator(pModule, *this); 221387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript& script = pModule.getScript(); 221487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t vma = 0x0, offset = 0x0; 221587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* cur = NULL; 221687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* prev = NULL; 221787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript::AddressMap::iterator addr, addrEnd = script.addressMap().end(); 221887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end(); 221987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::Output::dot_iterator dot; 222087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 222187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = script.sectionMap().begin(); 222287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = script.sectionMap().end(); 222387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; prev = cur, ++out) { 222487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur = (*out)->getSection(); 222587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 222687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (cur->kind() == LDFileFormat::Null) { 222787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(0x0); 222822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 222987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 223022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 223187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // process dot assignments between 2 output sections 223287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::Output::dot_iterator it = (*out)->dot_begin(), 223387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ie = (*out)->dot_end(); it != ie; ++it) { 223487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*it).assign(evaluator); 223587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 223687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 223787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines seg = elfSegmentTable().find(llvm::ELF::PT_LOAD, cur); 223887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (seg != segEnd && cur == (*seg)->front()) { 223987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->isBssSegment()) 224087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = script.addressMap().find(".bss"); 224187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if ((*seg)->isDataSegment()) 224287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = script.addressMap().find(".data"); 224387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 224487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = script.addressMap().find(cur->name()); 224587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else 224687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = addrEnd; 224722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 224887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (addr != addrEnd) { 22496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // use address mapping in script options 225087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = addr.getEntry()->value(); 225187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if ((*out)->prolog().hasVMA()) { 225287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // use address from output section description 225387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines evaluator.eval((*out)->prolog().vma(), vma); 225487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if ((dot = (*out)->find_last_explicit_dot()) != (*out)->dot_end()) { 225587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // assign address based on `.' symbol in ldscript 225687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = (*dot).symbol().value(); 225787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(vma, cur->align()); 225887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 225987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->prolog().type() == OutputSectDesc::NOLOAD) { 226087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = prev->addr() + prev->size(); 226187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0) { 226287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (prev->kind() == LDFileFormat::Null) { 226387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Let SECTIONS starts at 0 if we have a default ldscript but don't 226487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // have any initial value (VMA or `.'). 226587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!config().options().getScriptList().empty()) 226687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = 0x0; 226787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 226887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = getSegmentStartAddr(script) + sectionStartOffset(); 226987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 227087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((prev->kind() == LDFileFormat::BSS)) 227187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = prev->addr(); 227287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 227387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = prev->addr() + prev->size(); 227487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 227587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(vma, cur->align()); 227687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().getScriptList().empty()) { 227787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (seg != segEnd && cur == (*seg)->front()) { 227887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Try to align p_vaddr at page boundary if not in script options. 227987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // To do so will add more padding in file, but can save one page 228087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // at runtime. 228187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(vma, (*seg)->align()); 228287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 228387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 228487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 228587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = 0x0; 228622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 22876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 228822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 228987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().hasRelro()) { 229087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // if -z relro is given, we need to adjust sections' offset again, and 229187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // let PT_GNU_RELRO end on a abi page boundary 229287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 229387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // check if current is the first non-relro section 229487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator relro_last = out - 1; 229587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (relro_last != outEnd && 229687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*relro_last)->order() <= SHO_RELRO_LAST && 229787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->order() > SHO_RELRO_LAST) { 229887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // align the first non-relro section to page boundary 229987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(vma, abiPageSize()); 230087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 230187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // It seems that compiler think .got and .got.plt are continuous (w/o 230287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // any padding between). If .got is the last section in PT_RELRO and 230387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // it's not continuous to its next section (i.e. .got.plt), we need to 230487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // add padding in front of .got instead. 230587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FIXME: Maybe we can handle this in a more general way. 230687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& got = getOutputFormat()->getGOT(); 230787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((getSectionOrder(got) == SHO_RELRO_LAST) && 230887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (got.addr() + got.size() < vma)) { 230987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t diff = vma - got.addr() - got.size(); 231087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines got.setAddr(vma - got.size()); 231187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines got.setOffset(got.offset() + diff); 231287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 231387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 231487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // end of if - for relro processing 231587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 231687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setAddr(vma); 231787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 231887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (prev->kind()) { 231987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case LDFileFormat::Null: 232087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = sectionStartOffset(); 232187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 232287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case LDFileFormat::BSS: 232387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = prev->offset(); 232487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 232587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: 232687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = prev->offset() + prev->size(); 232787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 232887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 232987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(offset, cur->align()); 23306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf 23316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // p_align: As "Program Loading" describes in this chapter of the 23326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // processor supplement, loadable process segments must have congruent 23336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // values for p_vaddr and p_offset, modulo the page size. 233487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FIXME: Now make all sh_addr and sh_offset are congruent, modulo the page 233587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // size. Otherwise, old objcopy (e.g., binutils 2.17) may fail with our 233687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // output! 233787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0 && 233887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (vma & (abiPageSize() - 1)) != (offset & (abiPageSize() - 1))) { 233987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t padding = abiPageSize() + 234087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (vma & (abiPageSize() - 1)) - 234187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (offset & (abiPageSize() - 1)); 234287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += padding; 234322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 234422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 234587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(offset); 234622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 234787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // process dot assignments in the output section 234887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool changed = false; 234987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* invalid = NULL; 235087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::Output::iterator in = (*out)->begin(), 235187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines inEnd = (*out)->end(); in != inEnd; ++in) { 235222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 235387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (invalid != NULL && !(*in)->dotAssignments().empty()) { 235487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines while (invalid != (*in)->dotAssignments().front().first) { 235587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* prev = invalid->getPrevNode(); 235687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid->setOffset(prev->getOffset() + prev->size()); 235787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = invalid->getNextNode(); 235887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 235987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = NULL; 236087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 236122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 236287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::Input::dot_iterator it = (*in)->dot_begin(), 236387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ie = (*in)->dot_end(); it != ie; ++it) { 236487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*it).second.assign(evaluator); 236587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it).first != NULL) { 236687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t new_offset = (*it).second.symbol().value() - vma; 236787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (new_offset != (*it).first->getOffset()) { 236887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*it).first->setOffset(new_offset); 236987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = (*it).first->getNextNode(); 237087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines changed = true; 237187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 237287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 237387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each dot assignment 237487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each input description 237587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 237687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (changed) { 237787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines while (invalid != NULL) { 237887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* prev = invalid->getPrevNode(); 237987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid->setOffset(prev->getOffset() + prev->size()); 238087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = invalid->getNextNode(); 238187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 238287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 238387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setSize(cur->getSectionData()->back().getOffset() + 238487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->getSectionData()->back().size()); 238522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 238687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 238787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each output section description 23885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 23895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 239087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// placeOutputSections - place output sections based on SectionMap 239187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::placeOutputSections(Module& pModule) 2392d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 239387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines typedef std::vector<LDSection*> Orphans; 239487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Orphans orphans; 239587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap& sectionMap = pModule.getScript().sectionMap(); 239687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2397d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie; 239887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ++it) { 239987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool wanted = false; 240087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2401d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch ((*it)->kind()) { 24026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // take NULL and StackNote directly 24036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Null: 24046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::StackNote: 240587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines wanted = true; 24066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 24076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // ignore if section size is 0 24086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrame: 24096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*it)->size() != 0) || 24106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*it)->hasEhFrame() && 24116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 241287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines wanted = true; 24136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 24146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Relocation: 24156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*it)->size() != 0) || 24166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*it)->hasRelocData() && 24176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 241887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines wanted = true; 24196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2420a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines case LDFileFormat::TEXT: 2421a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines case LDFileFormat::DATA: 24226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Target: 24236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::MetaData: 24246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::BSS: 24256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Debug: 24266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::GCCExceptTable: 24276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Note: 24286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::NamePool: 24296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrameHdr: 24306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (((*it)->size() != 0) || 24316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*it)->hasSectionData() && 24326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().codeGenType() == LinkerConfig::Object)) 243387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines wanted = true; 24346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 24356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Group: 24366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object == config().codeGenType()) { 24376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines //TODO: support incremental linking 24386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ; 24396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 24406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 24416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Version: 244287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it)->size() != 0) { 244387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines wanted = true; 24446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name(); 24456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 24466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 24476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 244887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it)->size() != 0) { 24496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines error(diag::err_unsupported_section) << (*it)->name() << (*it)->kind(); 24506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 24516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 245287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // end of switch 245387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 245487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (wanted) { 245587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 245687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = sectionMap.begin(); 245787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = sectionMap.end(); 245887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; ++out) { 245987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool matched = false; 246087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it)->name().compare((*out)->name()) == 0) { 246187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch ((*out)->prolog().constraint()) { 246287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case OutputSectDesc::NO_CONSTRAINT: 246387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines matched = true; 246487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 246587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case OutputSectDesc::ONLY_IF_RO: 246687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) == 0; 246787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 246887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case OutputSectDesc::ONLY_IF_RW: 246987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) != 0; 247087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 247187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // end of switch 247287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 247387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (matched) 247487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 247587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 247687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each output section description 247787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 247887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out != outEnd) { 247987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up the section 248087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setSection(*it); 248187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setOrder(getSectionOrder(**it)); 248287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 248387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines orphans.push_back(*it); 248487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 2485d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 248687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each section in Module 248787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 248887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up sections in SectionMap but do not exist at all. 248987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t flag = 0x0; 249087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned int order = SHO_UNDEFINED; 249187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines OutputSectDesc::Type type = OutputSectDesc::LOAD; 249287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::reverse_iterator out = sectionMap.rbegin(), 249387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = sectionMap.rend(); out != outEnd; ++out) { 249487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->hasContent() || 249587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::Null || 249687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::StackNote) { 249787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag = (*out)->getSection()->flag(); 249887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines order = (*out)->order(); 249987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines type = (*out)->prolog().type(); 250087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 250187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->setFlag(flag); 250287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setOrder(order); 250387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->prolog().setType(type); 250487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 250587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each output section description 250687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 250787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // place orphan sections 250887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (Orphans::iterator it = orphans.begin(), ie = orphans.end(); it != ie; 250987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ++it) { 251087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t order = getSectionOrder(**it); 251187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 251287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = sectionMap.begin(); 251387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = sectionMap.end(); 251487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 251587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it)->kind() == LDFileFormat::Null) 251687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out = sectionMap.insert(outBegin, *it); 251787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 251887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; ++out) { 251987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->order() > order) 252087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 252187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 252287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out = sectionMap.insert(out, *it); 252387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 252487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setOrder(order); 252587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each orphan section 252687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 252787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // sort output section orders if there is no default ldscript 252887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().getScriptList().empty()) { 252987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::stable_sort(sectionMap.begin(), 253087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectionMap.end(), 253187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::SHOCompare()); 253287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 2533d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 253487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // when section ordering is fixed, now we can make sure dot assignments are 253587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // all set appropriately 253687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectionMap.fixupDotSymbols(); 253787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 253887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 253987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// layout - layout method 254087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::layout(Module& pModule) 254187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 254287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. place output sections based on SectionMap from SECTIONS command 254387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines placeOutputSections(pModule); 2544d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 254587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. update output sections in Module 254687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap& sectionMap = pModule.getScript().sectionMap(); 2547d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.getSectionTable().clear(); 254887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::iterator out = sectionMap.begin(), outEnd = sectionMap.end(); 254987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out != outEnd; ++out) { 255087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->hasContent() || 255187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::Null || 255287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::StackNote || 255387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines config().codeGenType() == LinkerConfig::Object) { 255487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->setIndex(pModule.size()); 255587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pModule.getSectionTable().push_back((*out)->getSection()); 255687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 255787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } // for each output section description 255887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 255987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 3. update the size of .shstrtab 256087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sizeShstrtab(pModule); 2561d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2562d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 4. create program headers 2563d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 25646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createProgramHdrs(pModule); 2565d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2566d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 256787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 5. set output section address/offset 256887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object != config().codeGenType()) 256987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines setOutputSectionAddress(pModule); 257087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 257187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines setOutputSectionOffset(pModule); 2572d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 2573d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 257487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::createAndSizeEhFrameHdr(Module& pModule) 25755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 25766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType() && 25776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // init EhFrameHdr and size the output section 257922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* format = getOutputFormat(); 258022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pEhFrameHdr = new EhFrameHdr(format->getEhFrameHdr(), 258122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao format->getEhFrame()); 2582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pEhFrameHdr->sizeOutput(); 2583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 258487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 258587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2586a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 2587a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines/// function pointer access 2588a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesbool GNULDBackend::mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) 2589a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines const 2590a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines{ 2591a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines llvm::StringRef name(pSection.name()); 2592a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines return !name.startswith(".rodata._ZTV") && 2593a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines !name.startswith(".data.rel.ro._ZTV") && 2594a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines !name.startswith(".rodata._ZTC") && 2595a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines !name.startswith(".data.rel.ro._ZTC") && 2596a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines !name.startswith(".eh_frame"); 2597a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines} 2598a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 259987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// preLayout - Backend can do any needed modification before layout 260087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::preLayout(Module& pModule, IRBuilder& pBuilder) 260187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 260287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // prelayout target first 260387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines doPreLayout(pBuilder); 260422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 26056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // change .tbss and .tdata section symbol from Local to LocalDyn category 260622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pTDATA) 2607f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*f_pTDATA); 260822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 260922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != f_pTBSS) 2610f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*f_pTBSS); 261122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 261222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // To merge input's relocation sections into output's relocation sections. 261322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 261422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are generating relocatables (-r), move input relocation sections 261522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to corresponding output relocation sections. 261622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 261722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = pModule.obj_end(); 261822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = pModule.obj_begin(); input != inEnd; ++input) { 261922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 262022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 262122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 262222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the output relocation LDSection with identical name. 262322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_sect = pModule.getSection((*rs)->name()); 262422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == output_sect) { 262522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect = LDSection::Create((*rs)->name(), 262622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->kind(), 262722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->type(), 262822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*rs)->flag()); 262922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 263022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setAlign((*rs)->align()); 263122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule.getSectionTable().push_back(output_sect); 263222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 263322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 263422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set output relocation section link 263522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* input_link = (*rs)->getLink(); 263622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != input_link && "Illegal input relocation section."); 263722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 263822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the linked output section 263922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_link = pModule.getSection(input_link->name()); 264022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != output_link); 264122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 264222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setLink(output_link); 264322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 264422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get output relcoationData, create one if not exist 264522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!output_sect->hasRelocData()) 264622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao IRBuilder::CreateRelocData(*output_sect); 264722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 264822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData* out_reloc_data = output_sect->getRelocData(); 264922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 265022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // move relocations from input's to output's RelcoationData 2651d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& out_list = 2652d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao out_reloc_data->getRelocationList(); 2653d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& in_list = 2654d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*rs)->getRelocData()->getRelocationList(); 265522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao out_list.splice(out_list.end(), in_list); 265622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 265722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size output 265822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::SHT_REL == output_sect->type()) 265922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelEntrySize()); 266022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (llvm::ELF::SHT_RELA == output_sect->type()) 266122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelaEntrySize()); 266222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 266322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unknown_reloc_section_type) << output_sect->type() 266422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << output_sect->name(); 266522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 266622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for each relocation section 266722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for each input 266822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of if 266922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 267022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up the section flag of .note.GNU-stack section 26716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setupGNUStackInfo(pModule); 26725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 26735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2674cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout 26756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::postLayout(Module& pModule, IRBuilder& pBuilder) 26765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 267722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 267887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // do relaxation 26796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relax(pModule, pBuilder); 268087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up the attributes of program headers 2681f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setupProgramHdrs(pModule.getScript()); 2682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 26846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines doPostLayout(pModule, pBuilder); 26855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 26865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 268787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::postProcessing(FileOutputBuffer& pOutput) 2688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 26896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType() && 26906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // emit eh_frame_hdr 2692f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pEhFrameHdr->emitOutput<32>(pOutput); 2693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 26965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count. 26975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker, dynobj.cc:791 26985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols, 26995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool pIsGNUStyle) 27005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 27015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // @ref Google gold, dynobj.cc:loc 791 27025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static const unsigned int buckets[] = 27035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 27045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, 27055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16411, 32771, 65537, 131101, 262147 27065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao }; 27075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const unsigned buckets_count = sizeof buckets / sizeof buckets[0]; 27085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 27095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int result = 1; 27105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (unsigned i = 0; i < buckets_count; ++i) { 27115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pNumOfSymbols < buckets[i]) 27125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 27135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = buckets[i]; 27145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 27155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 27165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pIsGNUStyle && result < 2) 27175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = 2; 27185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 27195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 27205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 27215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 27226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2 27236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// @ref binutils gold, dynobj.cc:1165 27246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned GNULDBackend::getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const 27256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 27266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbitslog2 = 1; 27276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (uint32_t x = pNumOfSymbols >> 1; x != 0; x >>=1) 27286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++maskbitslog2; 27296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 27306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (maskbitslog2 < 3) 27316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 = 5; 27326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (((1U << (maskbitslog2 - 2)) & pNumOfSymbols) != 0) 27336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 += 3; 27346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 27356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 += 2; 27366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 27376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().bitclass() == 64 && maskbitslog2 == 5) 27386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 = 6; 27396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 27406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return maskbitslog2; 27416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 27426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 27435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol 27445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref Google gold linker: symtab.cc:311 274587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol) const 27465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 27475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 27485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol. We should not add it 27495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.binding() == ResolveInfo::Local) 27505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 27515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 27525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we are building shared object, and the visibility is external, we 27535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // need to add it. 275422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 2755d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Exec == config().codeGenType() || 2756d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 27575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default || 27586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected) 27595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 276022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 276122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 276222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 276322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 276422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol 276522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker: symtab.cc:311 276687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo) const 276722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 276822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 276922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol. We should not add it 277022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.binding() == ResolveInfo::Local) 277122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 277222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 277322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are building shared object, and the visibility is external, we 277422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // need to add it. 277522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 2776d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Exec == config().codeGenType() || 2777d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 277822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.visibility() == ResolveInfo::Default || 27796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pResolveInfo.visibility() == ResolveInfo::Protected) 278022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 278122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2782affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2783affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2784affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 278587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table 278687f34658dec9097d987d254a990ea7f311bfc95fStephen HinesELFSegmentFactory& GNULDBackend::elfSegmentTable() 278787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 278887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!"); 278987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pELFSegmentTable; 279087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 279187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 279287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table 279387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesconst ELFSegmentFactory& GNULDBackend::elfSegmentTable() const 279487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 279587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!"); 279687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pELFSegmentTable; 279787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 279887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2799affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine. 2800affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:135 280122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::commonPageSize() const 2802affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 280322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().commPageSize() > 0) 280422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return std::min(config().options().commPageSize(), abiPageSize()); 2805affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 28066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return std::min(m_pInfo->commonPageSize(), abiPageSize()); 2807affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2808affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2809affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine. 2810affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref gold linker: target.h:125 281122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t GNULDBackend::abiPageSize() const 2812affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 281322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().maxPageSize() > 0) 281422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return config().options().maxPageSize(); 2815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 28166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pInfo->abiPageSize(); 2817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2818affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2819affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other 2820affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit 2821affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:551 282222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const 2823affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 2824affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.other() != ResolveInfo::Default) 2825affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2826affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 282722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This is because the codeGenType of pie is DynObj. And gold linker check 282822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the "shared" option instead. 282922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 283022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 283122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 283222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj != config().codeGenType()) 283322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 283422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 283522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().Bsymbolic()) 2836affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2837affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 283822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // A local defined symbol should be non-preemptible. 283922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32 284022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relocation refers to a local defined symbol, and we should generate a 284122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relative dynamic relocation when applying the relocation. 284222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local) 2843affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2844affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2846affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2847affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 284822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation 284922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, symtab.h:645 28506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsDynRel(const ResolveInfo& pSym, 285122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool pSymHasPLT, 285222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isAbsReloc) const 285322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 285422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // an undefined reference in the executables should be statically 285522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // resolved to 0 and no need a dynamic relocation 285622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isUndef() && 285722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !pSym.isDyn() && 2858d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::Exec == config().codeGenType() || 2859d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType())) 286022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 286122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // An absolute symbol can be resolved directly if it is either local 28636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // or we are linking statically. Otherwise it can still be overridden 28646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // at runtime. 28656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSym.isAbsolute() && 28666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (pSym.binding() == ResolveInfo::Local || config().isCodeStatic())) 286722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 28686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() && isAbsReloc) 286922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 287022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymHasPLT && ResolveInfo::Function == pSym.type()) 287122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 28726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeIndep() && pSymHasPLT) 287322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 287422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDyn() || pSym.isUndef() || 287522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isSymbolPreemptible(pSym)) 287622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 287722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 287822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 287922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 288022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2881affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry 2882affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @ref Google gold linker, symtab.h:596 28836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsPLT(const ResolveInfo& pSym) const 2884affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 288522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isUndef() && 288622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !pSym.isDyn() && 288722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkerConfig::DynObj != config().codeGenType()) 2888affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2889affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2890affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry 2891affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() == ResolveInfo::IndirectFunc) 2892affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2893affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2894affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() != ResolveInfo::Function) 2895affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2896affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 28976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeStatic()) 289822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 289922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 290022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 2901affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2902affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2903affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (pSym.isDyn() || 2904affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.isUndef() || 290522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isSymbolPreemptible(pSym)); 2906affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2907affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 290822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at 290922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time 291022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @ref Google gold linker, Symbol::final_value_is_known 29116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolFinalValueIsKnown(const ResolveInfo& pSym) const 2912affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 291322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the output is pic code or if not executables, symbols' value may change 291422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // at runtime 29156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: CodeIndep() || LinkerConfig::Relocatable == CodeGenType 29166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() || 2917d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::Exec != config().codeGenType() && 2918d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary != config().codeGenType())) 2919affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 292022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 292122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is from dynamic object, then its value is unknown 292222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDyn()) 2923affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 292422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 292522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is not in dynamic object and is not undefined, then its value 292622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is known 292722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSym.isUndef()) 2928affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2929affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 293022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is undefined and not in dynamic objects, for example, a weak 293122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // undefined symbol, then whether the symbol's final value can be known 293222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // depends on whrther we're doing static link 29336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return config().isCodeStatic(); 2934affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2935affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2936affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation 29376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsCopyReloc(const Relocation& pReloc, 293822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo& pSym) const 2939affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 2940affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // only the reference from dynamic executable to non-function symbol in 2941affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // the dynamic objects may need copy relocation 29426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() || 2943affc150dc44fab1911775a49636d0ce85333b634Zonr Chang !pSym.isDyn() || 2944affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.type() == ResolveInfo::Function || 2945affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.size() == 0) 2946affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2947affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2948affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // check if the option -z nocopyreloc is given 294922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNoCopyReloc()) 2950affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2951affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2952affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // TODO: Is this check necessary? 2953affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if relocation target place is readonly, a copy relocation is needed 295422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag(); 295522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE)) 2956affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 29575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 29585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 29595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2960affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 296122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTDATASymbol() 296222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 296322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTDATA); 296422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 296522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 296622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 296722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTDATASymbol() const 296822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 296922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTDATA); 297022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 297122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 297222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 297322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& GNULDBackend::getTBSSSymbol() 297422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 297522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTBSS); 297622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 297722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 297822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 297922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst LDSymbol& GNULDBackend::getTBSSSymbol() const 298022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 298122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != f_pTBSS); 298222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 298322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 298422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 298587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef GNULDBackend::getEntry(const Module& pModule) const 298687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 298787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pModule.getScript().hasEntry()) 298887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return pModule.getScript().entry(); 298987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 299087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return getInfo().entry(); 299187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 299287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 299322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection) 299422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 299522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_bHasTextRel) 299622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 299722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 299822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the target section of the dynamic relocation is ALLOCATE but is not 299922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // writable, than we should set DF_TEXTREL 300022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const uint32_t flag = pSection.flag(); 300122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC)) 300222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasTextRel = true; 300322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 300422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 300522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 300622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 300787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sortRelocation - sort the dynamic relocations to let dynamic linker 300887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// process relocations more efficiently 300987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::sortRelocation(LDSection& pSection) 301087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 301187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!config().options().hasCombReloc()) 301287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 301387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 301487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(pSection.kind() == LDFileFormat::Relocation); 301587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 301687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (config().codeGenType()) { 301787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case LinkerConfig::DynObj: 301887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case LinkerConfig::Exec: 301987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (&pSection == &getOutputFormat()->getRelDyn() || 302087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines &pSection == &getOutputFormat()->getRelaDyn()) { 302187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pSection.hasRelocData()) 302287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSection.getRelocData()->sort(RelocCompare(*this)); 302387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 302487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: 302587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 302687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 302787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 302887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 302922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation 303022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initBRIslandFactory() 303122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 303222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pBRIslandFactory) { 3033a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines m_pBRIslandFactory = new BranchIslandFactory(maxFwdBranchOffset(), 3034a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines maxBwdBranchOffset()); 303522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 303622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 303722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 303822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 303922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation 304022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNULDBackend::initStubFactory() 304122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 304222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == m_pStubFactory) { 304322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pStubFactory = new StubFactory(); 304422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 304522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 304622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 304722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) 304922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 305022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!mayRelax()) 305122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 305222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 305387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getBRIslandFactory()->group(pModule); 305487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 305522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool finished = true; 305622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao do { 30576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (doRelax(pModule, pBuilder, finished)) { 305887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines setOutputSectionAddress(pModule); 305922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 306022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } while (!finished); 306122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 306222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 306322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 306422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::needGNUHash(const LDSymbol& X) const 30666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 30676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: in bfd and gold linker, an undefined symbol might be hashed 30686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // when the ouput is not PIC, if the symbol is referred by a non pc-relative 30696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // reloc, and its value is set to the addr of the plt entry. 30706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return !X.resolveInfo()->isUndef() && !X.isDyn(); 30716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 30726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 30736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::operator()(const LDSymbol* X, 30746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSymbol* Y) const 30756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 30766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return !needGNUHash(*X) && needGNUHash(*Y); 30776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 30786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 307987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::RelocCompare::operator()(const Relocation* X, 308087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const Relocation* Y) const 308187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 308287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. compare if relocation is relative 308387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (X->symInfo() == NULL) { 308487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (Y->symInfo() != NULL) 308587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 308687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if (Y->symInfo() == NULL) { 308787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 308887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 308987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. compare the symbol index 309087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t symIdxX = m_Backend.getSymbolIdx(X->symInfo()->outSymbol()); 309187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t symIdxY = m_Backend.getSymbolIdx(Y->symInfo()->outSymbol()); 309287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (symIdxX < symIdxY) 309387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 309487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (symIdxX > symIdxY) 309587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 309687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 309787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 309887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 3. compare the relocation address 309987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (X->place() < Y->place()) 310087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 310187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (X->place() > Y->place()) 310287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 310387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 310487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 4. compare the relocation type 310587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (X->type() < Y->type()) 310687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 310787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (X->type() > Y->type()) 310887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 310987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 311087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 5. compare the addend 311187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (X->addend() < Y->addend()) 311287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 311387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (X->addend() > Y->addend()) 311487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 311587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 311687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 311787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 3118