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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/InputTree.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerScript.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/ADT/SizeTraits.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Config/Config.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/BranchIslandFactory.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrameHdr.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFDynObjFileFormat.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFExecFileFormat.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFObjectFileFormat.h" 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegment.h" 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegmentFactory.h" 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h" 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h" 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocationFactory.h" 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/StubFactory.h" 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Attribute.h" 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/SectionMap.h" 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operand.h" 3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/OutputSectDesc.h" 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnEvaluator.h" 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileOutputBuffer.h" 4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFAttribute.h" 4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFDynamic.h" 4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNUInfo.h" 4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 450dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/ADT/StringRef.h> 4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Host.h> 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 480dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <algorithm> 490dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <cstring> 500dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <cassert> 510dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <map> 520dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <string> 530dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <vector> 540dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace { 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===----------------------------------------------------------------------===// 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// non-member functions 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesstatic const std::string simple_c_identifier_allowed_chars = 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "0123456789" 62b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines "abcdefghijklmnopqrstuvwxyz" 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_"; 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isCIdentifier - return if the pName is a valid C identifier 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic bool isCIdentifier(const std::string& pName) { 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines return (pName.find_first_not_of(simple_c_identifier_allowed_chars) == 6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::string::npos); 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // anonymous namespace 73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 7437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// GNULDBackend 78cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 79d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoGNULDBackend::GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo) 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines : TargetLDBackend(pConfig), 8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pObjectReader(NULL), 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pDynObjFileFormat(NULL), 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pExecFileFormat(NULL), 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pObjectFileFormat(NULL), 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pInfo(pInfo), 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pELFSegmentTable(NULL), 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pBRIslandFactory(NULL), 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pStubFactory(NULL), 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEhFrameHdr(NULL), 9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pAttribute(NULL), 9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_bHasTextRel(false), 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_bHasStaticTLS(false), 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pPreInitArrayStart(NULL), 9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pPreInitArrayEnd(NULL), 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pInitArrayStart(NULL), 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pInitArrayEnd(NULL), 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pFiniArrayStart(NULL), 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pFiniArrayEnd(NULL), 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pStack(NULL), 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pDynamic(NULL), 10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pTDATA(NULL), 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pTBSS(NULL), 10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pExecutableStart(NULL), 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEText(NULL), 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_EText(NULL), 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p__EText(NULL), 10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEData(NULL), 10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_EData(NULL), 10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pBSSStart(NULL), 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEnd(NULL), 11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_End(NULL) { 11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pELFSegmentTable = new ELFSegmentFactory(); 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymIndexMap = new HashTableType(1024); 11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pAttribute = new ELFAttribute(*this, pConfig); 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11737b74a387bb3993387029859c2d9d051c41c724eStephen HinesGNULDBackend::~GNULDBackend() { 11887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pELFSegmentTable; 119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pInfo; 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynObjFileFormat; 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pExecFileFormat; 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pObjectFileFormat; 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pSymIndexMap; 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pEhFrameHdr; 12587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pAttribute; 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pBRIslandFactory; 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pStubFactory; 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t GNULDBackend::sectionStartOffset() const { 131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Binary == config().codeGenType()) 132d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0x0; 133d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch (config().targets().bitclass()) { 135d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 32u: 136d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf32_Ehdr) + 13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().size() * sizeof(llvm::ELF::Elf32_Phdr); 138d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 64u: 139d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return sizeof(llvm::ELF::Elf64_Ehdr) + 14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().size() * sizeof(llvm::ELF::Elf64_Phdr); 141d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao default: 142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 143d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return 0; 145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSegmentStartAddr(const LinkerScript& pScript) const { 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LinkerScript::AddressMap::const_iterator mapping = 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines pScript.addressMap().find(".text"); 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pScript.addressMap().end() != mapping) 15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return mapping.getEntry()->value(); 1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (config().isCodeIndep()) 154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return 0x0; 155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pInfo->defaultTextSegmentAddr(); 157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15937b74a387bb3993387029859c2d9d051c41c724eStephen HinesGNUArchiveReader* GNULDBackend::createArchiveReader(Module& pModule) { 16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pObjectReader != NULL); 16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return new GNUArchiveReader(pModule, *m_pObjectReader); 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16437b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFObjectReader* GNULDBackend::createObjectReader(IRBuilder& pBuilder) { 165d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectReader = new ELFObjectReader(*this, pBuilder, config()); 16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectReader; 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16937b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFDynObjReader* GNULDBackend::createDynObjReader(IRBuilder& pBuilder) { 170d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFDynObjReader(*this, pBuilder, config()); 171d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 172d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 17337b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFBinaryReader* GNULDBackend::createBinaryReader(IRBuilder& pBuilder) { 17487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return new ELFBinaryReader(pBuilder, config()); 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17737b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFObjectWriter* GNULDBackend::createWriter() { 178d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new ELFObjectWriter(*this, config()); 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initStdSections(ObjectBuilder& pBuilder) { 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 18437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pDynObjFileFormat == NULL) 18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pDynObjFileFormat = new ELFDynObjFileFormat(); 186d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pDynObjFileFormat->initStdSections(pBuilder, 187d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pExecFileFormat == NULL) 19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pExecFileFormat = new ELFExecFileFormat(); 194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pExecFileFormat->initStdSections(pBuilder, 195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 19937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pObjectFileFormat == NULL) 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pObjectFileFormat = new ELFObjectFileFormat(); 201d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pObjectFileFormat->initStdSections(pBuilder, 202d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao config().targets().bitclass()); 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStandardSymbols - define and initialize standard symbols. 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This function is called after section merging but before read relocations. 21337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initStandardSymbols(IRBuilder& pBuilder, Module& pModule) { 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // GNU extension: define __start and __stop symbols for the sections whose 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // name can be presented as C symbol 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator iter, iterEnd = pModule.end(); 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iter = pModule.begin(); iter != iterEnd; ++iter) { 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* section = *iter; 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (section->kind()) { 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: 22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasEhFrame()) 22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!section->hasSectionData()) 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 23437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isCIdentifier(section->name())) { 237f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::string start_name = "__start_" + section->name(); 23837b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef* start_fragref = 23937b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(section->getSectionData()->front(), 0x0); 24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 24237b74a387bb3993387029859c2d9d051c41c724eStephen Hines start_name, 24337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 24437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 24537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 24637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 24737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 24837b74a387bb3993387029859c2d9d051c41c724eStephen Hines start_fragref, // FragRef 24937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::string stop_name = "__stop_" + section->name(); 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* stop_fragref = FragmentRef::Create( 25337b74a387bb3993387029859c2d9d051c41c724eStephen Hines section->getSectionData()->front(), section->size()); 2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 25537b74a387bb3993387029859c2d9d051c41c724eStephen Hines stop_name, 25637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 25737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 25837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 25937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines stop_fragref, // FragRef 26237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .preinit_array 270cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* preinit_array = NULL; 271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasPreInitArray()) { 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Create( 27337b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getPreInitArray().getSectionData()->front(), 0x0); 27437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao preinit_array = FragmentRef::Null(); 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 27737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart = 27937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 28037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__preinit_array_start", 28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 28237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 28337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 28437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 28537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 28637b74a387bb3993387029859c2d9d051c41c724eStephen Hines preinit_array, // FragRef 28737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 28837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd = 29037b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 29137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__preinit_array_end", 29237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 29337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 29437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 29537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 29637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 29737b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .init_array 301cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* init_array = NULL; 302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInitArray()) { 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Create( 30437b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getInitArray().getSectionData()->front(), 0x0); 30537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao init_array = FragmentRef::Null(); 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart = 31037b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 31137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__init_array_start", 31237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 31337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 31437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 31537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 31637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 31737b74a387bb3993387029859c2d9d051c41c724eStephen Hines init_array, // FragRef 31837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 31937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd = 32137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 32237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__init_array_end", 32337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 32437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 32537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 32637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 32737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 32837b74a387bb3993387029859c2d9d051c41c724eStephen Hines init_array, // FragRef 32937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .fini_array 332cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* fini_array = NULL; 333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasFiniArray()) { 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Create( 33537b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getFiniArray().getSectionData()->front(), 0x0); 33637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fini_array = FragmentRef::Null(); 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart = 34137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 34237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__fini_array_start", 34337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 34437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 34537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 34637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 34737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 34837b74a387bb3993387029859c2d9d051c41c724eStephen Hines fini_array, // FragRef 34937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 35037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd = 35237b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 35337b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__fini_array_end", 35437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 35537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 35637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 35737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 35837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 35937b74a387bb3993387029859c2d9d051c41c724eStephen Hines fini_array, // FragRef 36037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // .stack 363cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* stack = NULL; 364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasStack()) { 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Create( 36637b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getStack().getSectionData()->front(), 0x0); 36737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stack = FragmentRef::Null(); 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37137b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pStack = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 37237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__stack", 37337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 37537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Global, 37637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 37737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 37837b74a387bb3993387029859c2d9d051c41c724eStephen Hines stack, // FragRef 37937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // _DYNAMIC 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: add SectionData for .dynamic section, and then we can get the correct 38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol section index for _DYNAMIC. Now it will be ABS. 38437b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pDynamic = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 38537b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_DYNAMIC", 38637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 38737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 38837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 38937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 39037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 39137b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 39237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart = 39637b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 39737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__executable_start", 39837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 39937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 40037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 40137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 40237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 40337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 40437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 40537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 40637b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEText = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 40737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "etext", 40837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 40937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 41037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 41137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 41237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 41337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 41437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 41537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 41637b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_EText = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 41737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_etext", 41837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 41937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 42037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 42137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 42237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 42337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 42437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 42537b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p__EText = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 42637b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__etext", 42737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 42837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 42937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 43037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 43137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 43237b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 43437b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEData = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 43537b74a387bb3993387029859c2d9d051c41c724eStephen Hines "edata", 43637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 43737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 43837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 43937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 44037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 44137b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 44237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 44337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 44437b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 44537b74a387bb3993387029859c2d9d051c41c724eStephen Hines "end", 44637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 44737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 44837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 44937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 45037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 45137b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 45237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _edata is defined forcefully. 45537b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_EData = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 45637b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_edata", 45737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 45837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 45937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 46037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 46137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 46237b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 46337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // __bss_start is defined forcefully. 46637b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pBSSStart = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 46737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__bss_start", 46837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 46937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 47037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 47137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 47237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 47337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 47437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // _end is defined forcefully. 47737b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_End = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 47837b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_end", 47937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 48037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 48137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 48237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 48337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 48437b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 48537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 49037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::finalizeStandardSymbols() { 49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- section symbols ----- // 49737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pPreInitArrayStart != NULL) { 498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pPreInitArrayStart->hasFragRef()) { 499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayStart->setValue(0x0); 501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 50437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pPreInitArrayEnd != NULL) { 505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pPreInitArrayEnd->hasFragRef()) { 506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(f_pPreInitArrayEnd->value() + 507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getPreInitArray().size()); 50837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pPreInitArrayEnd->setValue(0x0); 511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 51437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pInitArrayStart != NULL) { 515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pInitArrayStart->hasFragRef()) { 516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayStart->setValue(0x0); 518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 52137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pInitArrayEnd != NULL) { 522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pInitArrayEnd->hasFragRef()) { 523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(f_pInitArrayEnd->value() + 524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getInitArray().size()); 52537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pInitArrayEnd->setValue(0x0); 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 53137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pFiniArrayStart != NULL) { 532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pFiniArrayStart->hasFragRef()) { 533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->resolveInfo()->setBinding(ResolveInfo::Absolute); 534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayStart->setValue(0x0); 535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 53837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pFiniArrayEnd != NULL) { 539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (f_pFiniArrayEnd->hasFragRef()) { 540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(f_pFiniArrayEnd->value() + 541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getFiniArray().size()); 54237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->resolveInfo()->setBinding(ResolveInfo::Absolute); 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pFiniArrayEnd->setValue(0x0); 545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 54837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pStack != NULL) { 549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!f_pStack->hasFragRef()) { 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->resolveInfo()->setBinding(ResolveInfo::Absolute); 551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pStack->setValue(0x0); 552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 55537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pDynamic != NULL) { 55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->resolveInfo()->setBinding(ResolveInfo::Local); 55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setValue(file_format->getDynamic().addr()); 55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pDynamic->setSize(file_format->getDynamic().size()); 55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- segment symbols ----- // 56237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pExecutableStart != NULL) { 56387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::const_iterator exec_start = 56437b74a387bb3993387029859c2d9d051c41c724eStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, 0x0, 0x0); 56587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != exec_start) { 566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal != f_pExecutableStart->type()) { 567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(f_pExecutableStart->value() + 56887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*exec_start)->vaddr()); 569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 57037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pExecutableStart->setValue(0x0); 57237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 57537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEText != NULL || f_p_EText != NULL || f_p__EText != NULL) { 57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFSegmentFactory::const_iterator etext = elfSegmentTable().find( 57737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::PT_LOAD, llvm::ELF::PF_X, llvm::ELF::PF_W); 57887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != etext) { 57937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEText != NULL && ResolveInfo::ThreadLocal != f_pEText->type()) { 58037b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEText->setValue(f_pEText->value() + (*etext)->vaddr() + 58187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->memsz()); 582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 58337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_EText != NULL && ResolveInfo::ThreadLocal != f_p_EText->type()) { 58437b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_EText->setValue(f_p_EText->value() + (*etext)->vaddr() + 58587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*etext)->memsz()); 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 58737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p__EText != NULL && 58837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::ThreadLocal != f_p__EText->type()) { 58937b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p__EText->setValue(f_p__EText->value() + (*etext)->vaddr() + 59037b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*etext)->memsz()); 591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 59237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 59337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEText != NULL) 594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEText->setValue(0x0); 59537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_EText != NULL) 596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EText->setValue(0x0); 59737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p__EText != NULL) 598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p__EText->setValue(0x0); 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 60237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEData != NULL || f_p_EData != NULL || f_pBSSStart != NULL || 60337b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEnd != NULL || f_p_End != NULL) { 60487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::const_iterator edata = 60537b74a387bb3993387029859c2d9d051c41c724eStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, llvm::ELF::PF_W, 0x0); 60687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != edata) { 60737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEData != NULL && ResolveInfo::ThreadLocal != f_pEData->type()) { 60837b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEData->setValue(f_pEData->value() + (*edata)->vaddr() + 60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->filesz()); 610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 61137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_EData != NULL && ResolveInfo::ThreadLocal != f_p_EData->type()) { 61237b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_EData->setValue(f_p_EData->value() + (*edata)->vaddr() + 61387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->filesz()); 614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 61537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pBSSStart != NULL && 61637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::ThreadLocal != f_pBSSStart->type()) { 61737b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pBSSStart->setValue(f_pBSSStart->value() + (*edata)->vaddr() + 61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->filesz()); 619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 62137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEnd != NULL && ResolveInfo::ThreadLocal != f_pEnd->type()) { 62237b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEnd->setValue(f_pEnd->value() + (*edata)->vaddr() + 62387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->memsz()); 624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 62537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_End != NULL && ResolveInfo::ThreadLocal != f_p_End->type()) { 62637b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_End->setValue(f_p_End->value() + (*edata)->vaddr() + 62787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->memsz()); 628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 62937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 63037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEData != NULL) 631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEData->setValue(0x0); 63237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_EData != NULL) 633affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_EData->setValue(0x0); 63437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pBSSStart != NULL) 635affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pBSSStart->setValue(0x0); 636affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 63737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEnd != NULL) 638affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_pEnd->setValue(0x0); 63937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_End != NULL) 640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang f_p_End->setValue(0x0); 641affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 642affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 643affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 64737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::finalizeTLSSymbol(LDSymbol& pSymbol) { 64822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ignore if symbol has no fragRef 64922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSymbol.hasFragRef()) 65022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 651affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 65222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the value of a TLS symbol is the offset to the TLS segment 65387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator tls_seg = 65437b74a387bb3993387029859c2d9d051c41c724eStephen Hines elfSegmentTable().find(llvm::ELF::PT_TLS, llvm::ELF::PF_R, 0x0); 65587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(tls_seg != elfSegmentTable().end()); 65622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t value = pSymbol.fragRef()->getOutputOffset(); 65737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t addr = pSymbol.fragRef()->frag()->getParent()->getSection().addr(); 65887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymbol.setValue(value + addr - (*tls_seg)->vaddr()); 65922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 66237b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFFileFormat* GNULDBackend::getOutputFormat() { 66322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 66422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 66537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynObjFileFormat != NULL); 66622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 66722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 668d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 66937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pExecFileFormat != NULL); 67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 67122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 67237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pObjectFileFormat != NULL); 67322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 67522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 679affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 68037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ELFFileFormat* GNULDBackend::getOutputFormat() const { 68122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (config().codeGenType()) { 68222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: 68337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynObjFileFormat != NULL); 68422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pDynObjFileFormat; 68522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: 686d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: 68737b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pExecFileFormat != NULL); 68822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pExecFileFormat; 68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: 69037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pObjectFileFormat != NULL); 69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return m_pObjectFileFormat; 692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 69322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unrecognized_output_file) << config().codeGenType(); 694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 69887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sizeShstrtab - compute the size of .shstrtab 69937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sizeShstrtab(Module& pModule) { 70087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t shstrtab = 0; 70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // compute the size of .shstrtab section. 70287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Module::const_iterator sect, sectEnd = pModule.end(); 70387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = pModule.begin(); sect != sectEnd; ++sect) { 70487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines shstrtab += (*sect)->name().size() + 1; 70537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 70687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getOutputFormat()->getShStrTab().setSize(shstrtab); 70787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 70887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sizeNamePools - compute the size of regular name pools 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab, 71122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab. 71237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sizeNamePools(Module& pModule) { 713f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(LinkerConfig::Unset != config().codePosition()); 714f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // number of entries in symbol tables starts from 1 to hold the special entry 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21. 71722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t symtab = 1; 71837b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t dynsym = config().isCodeStatic() ? 0 : 1; 71922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 72022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size of string tables starts from 1 to hold the null character in their 72122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // first byte 72237b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t strtab = 1; 72337b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t dynstr = config().isCodeStatic() ? 0 : 1; 72437b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t hash = 0; 72537b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t gnuhash = 0; 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // number of local symbol in the .symtab and .dynsym 7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symtab_local_cnt = 0; 729d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao size_t dynsym_local_cnt = 0; 730d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd; 7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// Compute the size of .symtab, .strtab, and symtab_local_cnt 73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 73587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /* TODO: 73687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1. discard locals and temporary locals 73787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2. check whether the symbol is used 73887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 73987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (config().options().getStripSymbolMode()) { 7402bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar case GeneralOptions::StripSymbolMode::StripAllSymbols: { 74187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab = strtab = 0; 74287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 74387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 74487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: { 74587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symEnd = symbols.end(); 74687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (symbol = symbols.begin(); symbol != symEnd; ++symbol) { 74787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ++symtab; 74887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (hasEntryInStrTab(**symbol)) 74987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtab += (*symbol)->nameSize() + 1; 75087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 75187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab_local_cnt = 1 + symbols.numOfFiles() + symbols.numOfLocals() + 75287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symbols.numOfLocalDyns(); 75387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 75487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 75537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 75937b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (config().codeGenType()) { 76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // soname 76287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines dynstr += config().options().soname().size() + 1; 76322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 76422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /** fall through **/ 765d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Exec: 766d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LinkerConfig::Binary: { 767f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!config().isCodeStatic()) { 7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// Compute the size of .dynsym, .dynstr, and dynsym_local_cnt 7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.dynamicEnd(); 7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) { 7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dynsym; 772f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 7736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*symbol)->nameSize() + 1; 7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynsym_local_cnt = 1 + symbols.numOfLocalDyns(); 7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // compute .gnu.hash 7782bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if (config().options().hasGNUHash()) { 7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // count the number of dynsym to hash 7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashed_sym_cnt = 0; 7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.dynamicEnd(); 7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.dynamicBegin(); symbol != symEnd; ++symbol) { 7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (DynsymCompare().needGNUHash(**symbol)) 7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++hashed_sym_cnt; 7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Special case for empty .dynsym 7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (hashed_sym_cnt == 0) 7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash = 5 * 4 + config().targets().bitclass() / 8; 7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t nbucket = getHashBucketCount(hashed_sym_cnt, true); 7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash = (4 + nbucket + hashed_sym_cnt) * 4; 7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines gnuhash += (1U << getGNUHashMaskbitslog2(hashed_sym_cnt)) / 8; 7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 79622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute .hash 7972bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if (config().options().hasSysVHash()) { 7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Both Elf32_Word and Elf64_Word are 4 bytes 7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hash = (2 + getHashBucketCount(dynsym, false) + dynsym) * 8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf32_Word); 8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // add DT_NEEDED 8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 8056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) { 8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*lib)->name().size() + 1; 8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveNeedEntry(); 8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // add DT_RPATH 8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().getRpathList().empty()) { 8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveNeedEntry(); 8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::const_rpath_iterator rpath, 81637b74a387bb3993387029859c2d9d051c41c724eStephen Hines rpathEnd = config().options().rpath_end(); 81737b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (rpath = config().options().rpath_begin(); rpath != rpathEnd; 81837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++rpath) 8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynstr += (*rpath).size() + 1; 8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set size 8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setSize(dynsym * 8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf32_Sym)); 8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setSize(dynsym * 8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf64_Sym)); 8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynStrTab().setSize(dynstr); 8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getHashTab().setSize(hash); 8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getGNUHashTab().setSize(gnuhash); 8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .dynsym sh_info to one greater than the symbol table 8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // index of the last local symbol 8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynSymTab().setInfo(dynsym_local_cnt); 8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Because some entries in .dynamic section need information of .dynsym, 8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED 8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // entries until we get the size of the sections mentioned above 8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dynamic().reserveEntries(*file_format); 8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getDynamic().setSize(dynamic().numOfBytes()); 8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /* fall through */ 84622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 847d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 84837b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getSymTab().setSize(symtab * sizeof(llvm::ELF::Elf32_Sym)); 8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 85037b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getSymTab().setSize(symtab * sizeof(llvm::ELF::Elf64_Sym)); 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao file_format->getStrTab().setSize(strtab); 852d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 853d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // set .symtab sh_info to one greater than the symbol table 854d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // index of the last local symbol 8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getSymTab().setInfo(symtab_local_cnt); 8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 85787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The size of .shstrtab should be decided after output sections are all 85887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set, so we just set it to 1 here. 85987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines file_format->getShStrTab().setSize(0x1); 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 86222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 86322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::fatal_illegal_codegen_type) << pModule.name(); 86422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 86537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 86622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 86722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 86822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol 86922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym, 87022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 87122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 87222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 87337b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t pSymtabIdx) { 87437b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: check the endian between host and target 87537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // write out symbol 87637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (hasEntryInStrTab(pSymbol)) { 87737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_name = pStrtabsize; 87837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ::memcpy((pStrtab + pStrtabsize), pSymbol.name(), pSymbol.nameSize()); 87937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 88037b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_name = 0; 88137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 88237b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_value = pSymbol.value(); 88337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_size = getSymbolSize(pSymbol); 88437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_info = getSymbolInfo(pSymbol); 88537b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_other = pSymbol.visibility(); 88637b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_shndx = getSymbolShndx(pSymbol); 88722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 88822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 88922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol64 - emit an ELF64 symbol 89022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitSymbol64(llvm::ELF::Elf64_Sym& pSym, 89122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 89222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 89322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 89437b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t pSymtabIdx) { 89537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: check the endian between host and target 89637b74a387bb3993387029859c2d9d051c41c724eStephen Hines // write out symbol 89737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (hasEntryInStrTab(pSymbol)) { 89837b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_name = pStrtabsize; 89937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ::memcpy((pStrtab + pStrtabsize), pSymbol.name(), pSymbol.nameSize()); 90037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 90137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_name = 0; 90237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 90337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_value = pSymbol.value(); 90437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_size = getSymbolSize(pSymbol); 90537b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_info = getSymbolInfo(pSymbol); 90637b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_other = pSymbol.visibility(); 90737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.st_shndx = getSymbolShndx(pSymbol); 9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRegNamePools - emit regular name pools - .symtab, .strtab 9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 91422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid GNULDBackend::emitRegNamePools(const Module& pModule, 91537b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) { 91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 91787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!file_format->hasSymTab()) 91887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 9195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getSymTab(); 9215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getStrTab(); 9225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 92337b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion symtab_region = 92437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pOutput.request(symtab_sect.offset(), symtab_sect.size()); 92537b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion strtab_region = 92637b74a387bb3993387029859c2d9d051c41c724eStephen Hines pOutput.request(strtab_sect.offset(), strtab_sect.size()); 9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 9295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 9305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 931d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 93287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin(); 933d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 93487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin(); 935d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 936d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 937d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 938d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 939d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 9405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 94137b74a387bb3993387029859c2d9d051c41c724eStephen Hines char* strtab = reinterpret_cast<char*>(strtab_region.begin()); 9425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit the first ELF symbol 9446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) 9456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0); 9466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 9476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0); 9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 94922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool sym_exist = false; 95022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao HashTableType::entry_type* entry = NULL; 95122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry = m_pSymIndexMap->insert(LDSymbol::Null(), sym_exist); 95322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(0); 95422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 95522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symIdx = 1; 9575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 9586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Module::SymbolTable& symbols = pModule.getSymbolTable(); 9606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd; 9616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = symbols.end(); 9636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.begin(); symbol != symEnd; ++symbol) { 96422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 96522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 9666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry->setValue(symIdx); 9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 968d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 9696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx); 97022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 9716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx); 9726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symIdx; 973f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 97422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 97822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitDynNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 9795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 9805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 9815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 98237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::emitDynNamePools(Module& pModule, 98337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) { 98422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 98537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!file_format->hasDynSymTab() || !file_format->hasDynStrTab() || 98622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynamic()) 98722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 9885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 9905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 9915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 9935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 99437b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection& dyn_sect = file_format->getDynamic(); 99537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 99637b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion symtab_region = 99737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pOutput.request(symtab_sect.offset(), symtab_sect.size()); 99837b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion strtab_region = 99937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pOutput.request(strtab_sect.offset(), strtab_sect.size()); 100037b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion dyn_region = pOutput.request(dyn_sect.offset(), dyn_sect.size()); 10015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf64_Sym* symtab64 = NULL; 1004d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 100587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region.begin(); 1006d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (config().targets().is64Bits()) 100787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region.begin(); 1008d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else { 1009d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << config().targets().triple().str() 1010d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << config().targets().bitclass(); 1011d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 101437b74a387bb3993387029859c2d9d051c41c724eStephen Hines char* strtab = reinterpret_cast<char*>(strtab_region.begin()); 10155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit the first ELF symbol 10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) 10186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[0], *LDSymbol::Null(), strtab, 0, 0); 10196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[0], *LDSymbol::Null(), strtab, 0, 0); 10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t symIdx = 1; 10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .gnu.hash 10272bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if (config().options().hasGNUHash()) 10286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitGNUHashTab(symbols, pOutput); 1029f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .hash 10312bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if (config().options().hasSysVHash()) 10326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitELFHashTab(symbols, pOutput); 10336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category) 10356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = symbols.dynamicEnd(); 10366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = symbols.localDynBegin(); symbol != symEnd; ++symbol) { 1037d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 10386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol32(symtab32[symIdx], **symbol, strtab, strtabsize, symIdx); 103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 10406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSymbol64(symtab64[symIdx], **symbol, strtab, strtabsize, symIdx); 10415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // maintain output's symbol and index map 10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 10436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry->setValue(symIdx); 104422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sum up counters 10456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++symIdx; 1046f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (hasEntryInStrTab(**symbol)) 104722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 10485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 10515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 10525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 105322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 105422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!(*lib)->attribute()->isAsNeeded() || (*lib)->isNeeded()) { 105637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ::memcpy((strtab + strtabsize), 105737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*lib)->name().c_str(), 105837b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*lib)->name().size()); 10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 10606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtabsize += (*lib)->name().size() + 1; 10616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dt_need; 10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().getRpathList().empty()) { 10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().hasNewDTags()) 10676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_RPATH, strtabsize); 10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (*dt_need)->setValue(llvm::ELF::DT_RUNPATH, strtabsize); 10706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++dt_need; 10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines GeneralOptions::const_rpath_iterator rpath, 107337b74a387bb3993387029859c2d9d051c41c724eStephen Hines rpathEnd = config().options().rpath_end(); 10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (rpath = config().options().rpath_begin(); rpath != rpathEnd; ++rpath) { 10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy((strtab + strtabsize), (*rpath).data(), (*rpath).size()); 10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtabsize += (*rpath).size(); 10776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strtab[strtabsize++] = (rpath + 1 == rpathEnd ? '\0' : ':'); 10785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 107922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 108222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 108322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set pointer to SONAME entry in dynamic string table. 1084affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dynamic().applySoname(strtabsize); 108522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1086d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynamic().applyEntries(*file_format); 108787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines dynamic().emit(dyn_sect, dyn_region); 10885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 108922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit soname 109022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 109137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ::memcpy((strtab + strtabsize), 109237b74a387bb3993387029859c2d9d051c41c724eStephen Hines config().options().soname().c_str(), 109337b74a387bb3993387029859c2d9d051c41c724eStephen Hines config().options().soname().size()); 109487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtabsize += config().options().soname().size() + 1; 109522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitELFHashTab - emit .hash 10996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitELFHashTab(const Module::SymbolTable& pSymtab, 110037b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) { 11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 11026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!file_format->hasHashTab()) 11036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 11046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& hash_sect = file_format->getHashTab(); 110537b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion hash_region = 110637b74a387bb3993387029859c2d9d051c41c724eStephen Hines pOutput.request(hash_sect.offset(), hash_sect.size()); 11075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 11085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 110937b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t* word_array = reinterpret_cast<uint32_t*>(hash_region.begin()); 11105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 111137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& nchain = word_array[1]; 11125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t dynsymSize = 1 + pSymtab.numOfLocalDyns() + pSymtab.numOfDynamics(); 11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines nbucket = getHashBucketCount(dynsymSize, false); 111537b74a387bb3993387029859c2d9d051c41c724eStephen Hines nchain = dynsymSize; 11165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 111837b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t* chain = (bucket + nbucket); 11195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 112137b74a387bb3993387029859c2d9d051c41c724eStephen Hines memset(reinterpret_cast<void*>(bucket), 0, nbucket); 11225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines hash::StringHash<hash::ELF> hash_func; 11245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t idx = 1; 11266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd(); 11276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.localDynBegin(); symbol != symEnd; ++symbol) { 11286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::StringRef name((*symbol)->name()); 11296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t bucket_pos = hash_func(name) % nbucket; 11306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain[idx] = bucket[bucket_pos]; 11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[bucket_pos] = idx; 11326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++idx; 11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 11356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitGNUHashTab - emit .gnu.hash 11376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid GNULDBackend::emitGNUHashTab(Module::SymbolTable& pSymtab, 113837b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) { 11396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 11406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!file_format->hasGNUHashTab()) 11416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 11426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 114387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion gnuhash_region = 114437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pOutput.request(file_format->getGNUHashTab().offset(), 114537b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getGNUHashTab().size()); 11466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 114737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t* word_array = reinterpret_cast<uint32_t*>(gnuhash_region.begin()); 11486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // fixed-length fields 114937b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& nbucket = word_array[0]; 115037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& symidx = word_array[1]; 11516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t& maskwords = word_array[2]; 115237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& shift2 = word_array[3]; 11536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // variable-length fields 115437b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t* bitmask = reinterpret_cast<uint8_t*>(word_array + 4); 115537b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t* bucket = NULL; 115637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t* chain = NULL; 11576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // count the number of dynsym to hash 11596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t unhashed_sym_cnt = pSymtab.numOfLocalDyns(); 116037b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t hashed_sym_cnt = pSymtab.numOfDynamics(); 11616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_sym_iterator symbol, symEnd = pSymtab.dynamicEnd(); 11626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.dynamicBegin(); symbol != symEnd; ++symbol) { 11636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (DynsymCompare().needGNUHash(**symbol)) 11646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 116537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++unhashed_sym_cnt; 116637b74a387bb3993387029859c2d9d051c41c724eStephen Hines --hashed_sym_cnt; 11676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // special case for the empty hash table 11706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (hashed_sym_cnt == 0) { 117137b74a387bb3993387029859c2d9d051c41c724eStephen Hines nbucket = 1; // one empty bucket 117237b74a387bb3993387029859c2d9d051c41c724eStephen Hines symidx = 1 + unhashed_sym_cnt; // symidx above unhashed symbols 117337b74a387bb3993387029859c2d9d051c41c724eStephen Hines maskwords = 1; // bitmask length 117437b74a387bb3993387029859c2d9d051c41c724eStephen Hines shift2 = 0; // bloom filter 11756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 117737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t* maskval = reinterpret_cast<uint32_t*>(bitmask); 117837b74a387bb3993387029859c2d9d051c41c724eStephen Hines *maskval = 0; // no valid hashes 11796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 11806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be 64 118137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t* maskval = reinterpret_cast<uint64_t*>(bitmask); 118237b74a387bb3993387029859c2d9d051c41c724eStephen Hines *maskval = 0; // no valid hashes 11835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 118437b74a387bb3993387029859c2d9d051c41c724eStephen Hines bucket = reinterpret_cast<uint32_t*>(bitmask + 118537b74a387bb3993387029859c2d9d051c41c724eStephen Hines config().targets().bitclass() / 8); 118637b74a387bb3993387029859c2d9d051c41c724eStephen Hines *bucket = 0; // no hash in the only bucket 11876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 11885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 11896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbitslog2 = getGNUHashMaskbitslog2(hashed_sym_cnt); 11916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbits = 1u << maskbitslog2; 11926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shift1 = config().targets().is32Bits() ? 5 : 6; 11936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t mask = (1u << shift1) - 1; 11946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 119537b74a387bb3993387029859c2d9d051c41c724eStephen Hines nbucket = getHashBucketCount(hashed_sym_cnt, true); 119637b74a387bb3993387029859c2d9d051c41c724eStephen Hines symidx = 1 + unhashed_sym_cnt; 11976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskwords = 1 << (maskbitslog2 - shift1); 119837b74a387bb3993387029859c2d9d051c41c724eStephen Hines shift2 = maskbitslog2; 11996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // setup bucket and chain 120137b74a387bb3993387029859c2d9d051c41c724eStephen Hines bucket = reinterpret_cast<uint32_t*>(bitmask + maskbits / 8); 120237b74a387bb3993387029859c2d9d051c41c724eStephen Hines chain = (bucket + nbucket); 12036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // build the gnu style hash table 120537b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef std::multimap<uint32_t, std::pair<LDSymbol*, uint32_t> > SymMapType; 12066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines SymMapType symmap; 12076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symEnd = pSymtab.dynamicEnd(); 12086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (symbol = pSymtab.localDynBegin() + symidx - 1; symbol != symEnd; 120937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++symbol) { 1210f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines hash::StringHash<hash::DJB> hasher; 12116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t djbhash = hasher((*symbol)->name()); 12126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t hash = djbhash % nbucket; 12136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symmap.insert(std::make_pair(hash, std::make_pair(*symbol, djbhash))); 12146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // compute bucket, chain, and bitmask 12176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::vector<uint64_t> bitmasks(maskwords); 12186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t hashedidx = symidx; 12196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < nbucket; ++idx) { 12206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t count = 0; 12216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::pair<SymMapType::iterator, SymMapType::iterator> ret; 12226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ret = symmap.equal_range(idx); 122337b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (SymMapType::iterator it = ret.first; it != ret.second;) { 12246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // rearrange the hashed symbol ordering 12256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *(pSymtab.localDynBegin() + hashedidx - 1) = it->second.first; 12266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t djbhash = it->second.second; 12276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t val = ((djbhash >> shift1) & ((maskbits >> shift1) - 1)); 12286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bitmasks[val] |= 1u << (djbhash & mask); 12296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bitmasks[val] |= 1u << ((djbhash >> shift2) & mask); 12306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines val = djbhash & ~1u; 12316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // advance the iterator and check if we're dealing w/ the last elment 12326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (++it == ret.second) { 12336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // last element terminates the chain 12346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines val |= 1; 12356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines chain[hashedidx - symidx] = val; 12376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++hashedidx; 12396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++count; 12405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (count == 0) 12436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[idx] = 0; 12446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 12456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bucket[idx] = hashedidx - count; 12466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 12476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // write the bitmasks 12496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().is32Bits()) { 125037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t* maskval = reinterpret_cast<uint32_t*>(bitmask); 12516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t i = 0; i < maskwords; ++i) 12526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(maskval + i, &bitmasks[i], 4); 12536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 12546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be 64 125537b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t* maskval = reinterpret_cast<uint64_t*>(bitmask); 12566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t i = 0; i < maskwords; ++i) 12576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(maskval + i, &bitmasks[i], 8); 12585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 12605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// sizeInterp - compute the size of the .interp section 126237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sizeInterp() { 1263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const char* dyld_name; 126422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 126522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 1266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 12676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dyld_name = m_pInfo->dyld(); 1268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 126922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& interp = getOutputFormat()->getInterp(); 1270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang interp.setSize(std::strlen(dyld_name) + 1); 1271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitInterp - emit the .interp 127437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::emitInterp(FileOutputBuffer& pOutput) { 127522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasInterp()) { 127622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& interp = getOutputFormat()->getInterp(); 127787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion region = pOutput.request(interp.offset(), interp.size()); 127822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* dyld_name; 127922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasDyld()) 128022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyld_name = config().options().dyld().c_str(); 128122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 12826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dyld_name = m_pInfo->dyld(); 1283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 128487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::memcpy(region.begin(), dyld_name, interp.size()); 128522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 128837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const { 1289f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ResolveInfo::Section != pSym.type(); 1290f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 1291f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 129237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::orderSymbolTable(Module& pModule) { 1293f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 1294f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 12952bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if (config().options().hasGNUHash()) { 1296f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Currently we may add output symbols after sizeNamePools(), and a 1297f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // non-stable sort is used in SymbolCategory::arrange(), so we just 1298f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort .dynsym right before emitting .gnu.hash 129937b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::stable_sort( 130037b74a387bb3993387029859c2d9d051c41c724eStephen Hines symbols.dynamicBegin(), symbols.dynamicEnd(), DynsymCompare()); 13012bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar } 1302f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 1303f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 13045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectionOrder 130537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int GNULDBackend::getSectionOrder(const LDSection& pSectHdr) const { 130622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 130722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // NULL section should be the "1st" section 13095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (LDFileFormat::Null == pSectHdr.kind()) 131087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return SHO_NULL; 13115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 131222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getStrTab()) 131322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_STRTAB; 131422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if the section is not ALLOC, lay it out until the last possible moment 13165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC)) 13175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 13185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0; 13205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0; 13215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: need to take care other possible output sections 13225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pSectHdr.kind()) { 13230dea6bc96bb52346737966839ac68644f7939f58Stephen Hines case LDFileFormat::TEXT: 13240dea6bc96bb52346737966839ac68644f7939f58Stephen Hines case LDFileFormat::DATA: 13255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (is_exec) { 13265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getInit()) 13275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_INIT; 13285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getFini()) 13295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_FINI; 13305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_TEXT; 13315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else if (!is_write) { 13325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RO; 13335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } else { 133422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 133522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&pSectHdr == &file_format->getPreInitArray() || 133622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getInitArray() || 133722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSectHdr == &file_format->getFiniArray() || 1338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getCtors() || 1339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getDtors() || 1340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &pSectHdr == &file_format->getJCR() || 1341d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao &pSectHdr == &file_format->getDataRelRo()) 1342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 134337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1344d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (&pSectHdr == &file_format->getDataRelRoLocal()) 1345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO_LOCAL; 134637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 134737b74a387bb3993387029859c2d9d051c41c724eStephen Hines // Make special sections that end with .rel.ro suffix as RELRO. 134837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef name(pSectHdr.name()); 134937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (name.endswith(".rel.ro")) { 135037b74a387bb3993387029859c2d9d051c41c724eStephen Hines return SHO_RELRO; 135137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 1352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 135322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) { 135422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_DATA; 135522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 13575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 13585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::BSS: 136022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((pSectHdr.flag() & llvm::ELF::SHF_TLS) != 0x0) 136122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return SHO_TLS_BSS; 13625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_BSS; 13635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 136422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::NamePool: { 13655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getDynamic()) 13665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO; 13675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NAMEPOOL; 136822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Relocation: 13705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getRelPlt() || 13715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &pSectHdr == &file_format->getRelaPlt()) 13725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_REL_PLT; 13735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELOCATION; 13745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get the order from target for target specific sections 13765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Target: 137722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return getTargetSectionOrder(pSectHdr); 13785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // handle .interp and .note.* sections 13805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Note: 13816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (file_format->hasInterp() && (&pSectHdr == &file_format->getInterp())) 13826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_INTERP; 13836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (is_write) 13846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RW_NOTE; 13856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 13866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RO_NOTE; 13875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrame: 1389f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set writable .eh_frame as relro 1390f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (is_write) 1391f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO; 1392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrameHdr: 1393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::GCCExceptTable: 1394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_EXCEPTION; 13955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::MetaData: 13975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case LDFileFormat::Debug: 139837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::DebugString: 13995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 14005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 14015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolSize 140537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const { 14065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // undefined and dynamic symbols should have zero size. 14075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined) 14085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 14095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.resolveInfo()->size(); 14105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolInfo 141337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const { 14145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set binding 14155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t bind = 0x0; 14165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isLocal()) 14175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isGlobal()) 14195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isWeak()) 14215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_WEAK; 14225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSymbol.resolveInfo()->isAbsolute()) { 14235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // (Luba) Is a absolute but not global (weak or local) symbol meaningful? 14245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_GLOBAL; 14255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 14265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1427d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().codeGenType() != LinkerConfig::Object && 1428d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (pSymbol.visibility() == llvm::ELF::STV_INTERNAL || 142937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSymbol.visibility() == llvm::ELF::STV_HIDDEN)) 14305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bind = llvm::ELF::STB_LOCAL; 14315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t type = pSymbol.resolveInfo()->type(); 1433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if the IndirectFunc symbol (i.e., STT_GNU_IFUNC) is from dynobj, change 1434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // its type to Function 1435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (type == ResolveInfo::IndirectFunc && pSymbol.isDyn()) 1436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang type = ResolveInfo::Function; 1437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (type | (bind << 4)); 14385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolValue - this function is called after layout() 144137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const { 14425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.isDyn()) 14435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 14445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return pSymbol.value(); 14465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolShndx - this function is called after layout() 144937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::getSymbolShndx(const LDSymbol& pSymbol) const { 14505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isAbsolute()) 14515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_ABS; 14525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isCommon()) 14535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_COMMON; 14545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn()) 14555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_UNDEF; 14565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 145722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymbol.resolveInfo()->isDefine() && !pSymbol.hasFragRef()) 145822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return llvm::ELF::SHN_ABS; 145922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 146037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(pSymbol.hasFragRef() && 146137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "symbols must have fragment reference to get its index"); 146222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return pSymbol.fragRef()->frag()->getParent()->getSection().index(); 14635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index 146637b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t GNULDBackend::getSymbolIdx(const LDSymbol* pSymbol) const { 146737b74a387bb3993387029859c2d9d051c41c724eStephen Hines HashTableType::iterator entry = 146837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pSymIndexMap->find(const_cast<LDSymbol*>(pSymbol)); 146937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(entry != m_pSymIndexMap->end() && 147037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "symbol not found in the symbol table"); 147137b74a387bb3993387029859c2d9d051c41c724eStephen Hines return entry.getEntry()->value(); 14725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isTemporary - Whether pSymbol is a local label. 147537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isTemporary(const LDSymbol& pSymbol) const { 14766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (ResolveInfo::Local != pSymbol.binding()) 14776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 14786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 14796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSymbol.nameSize() < 2) 14806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 14816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 14826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* name = pSymbol.name(); 14836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ('.' == name[0] && 'L' == name[1]) 14846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 14856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 14866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // UnixWare 2.1 cc generate DWARF debugging symbols with `..' prefix. 14876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (name[0] == '.' && name[1] == '.') 14886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 14896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 14906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Work arround for gcc's bug 14916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // gcc sometimes generate symbols with '_.L_' prefix. 14926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSymbol.nameSize() < 4) 14936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 14946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 14956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_') 14966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 14976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 14986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 14996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 15006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// allocateCommonSymbols - allocate common symbols in the corresponding 150222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is executed at pre-layout stage. 150337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::allocateCommonSymbols(Module& pModule) { 150422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymbolCategory& symbol_list = pModule.getSymbolTable(); 1505affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (symbol_list.emptyCommons() && symbol_list.emptyFiles() && 15076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symbol_list.emptyLocals() && symbol_list.emptyLocalDyns()) 1508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 1509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 1511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: If the order of common symbols is defined, then sort common symbols 1513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // std::sort(com_sym, com_end, some kind of order); 1514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 151522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get corresponding BSS LDSection 151622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 151722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& bss_sect = file_format->getBSS(); 151822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& tbss_sect = file_format->getTBSS(); 1519affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1520cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 152122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_sect_data = NULL; 152222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect.hasSectionData()) 152322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = bss_sect.getSectionData(); 152422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 152522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 152622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 152722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* tbss_sect_data = NULL; 152822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (tbss_sect.hasSectionData()) 152922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = tbss_sect.getSectionData(); 153022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 153122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 1532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 153437b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t bss_offset = bss_sect.size(); 153522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tbss_offset = tbss_sect.size(); 1536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all local common symbols 1538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.localEnd(); 1539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 1541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::Common == (*com_sym)->desc()) { 1542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1548cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 1549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 155237b74a387bb3993387029859c2d9d051c41c724eStephen Hines tbss_offset += ObjectBuilder::AppendFragment( 155337b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *tbss_sect_data, (*com_sym)->value()); 1554551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 155587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 155637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 155737b74a387bb3993387029859c2d9d051c41c724eStephen Hines bss_offset += ObjectBuilder::AppendFragment( 155837b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *bss_sect_data, (*com_sym)->value()); 1559551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 156087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 15645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate all global common symbols 1566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang com_end = symbol_list.commonEnd(); 1567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 1568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We have to reset the description of the symbol here. When doing 1569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // incremental linking, the output relocatable object may have common 1570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbols. Therefore, we can not treat common symbols as normal symbols 1571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when emitting the regular name pools. We must change the symbols' 1572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // description here. 1573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 1574cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 1575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 1577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 157837b74a387bb3993387029859c2d9d051c41c724eStephen Hines tbss_offset += ObjectBuilder::AppendFragment( 157937b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *tbss_sect_data, (*com_sym)->value()); 1580551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 158187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 158237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 158337b74a387bb3993387029859c2d9d051c41c724eStephen Hines bss_offset += ObjectBuilder::AppendFragment( 158437b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *bss_sect_data, (*com_sym)->value()); 1585551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 158687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 1587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 159022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect.setSize(bss_offset); 159122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect.setSize(tbss_offset); 1592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang symbol_list.changeCommonsToGlobal(); 1593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 15945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 15955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// updateSectionFlags - update pTo's flags when merging pFrom 15976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// update the output section flags based on input section flags. 159837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::updateSectionFlags(LDSection& pTo, const LDSection& pFrom) { 15996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // union the flags from input 16006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t flags = pTo.flag(); 160137b74a387bb3993387029859c2d9d051c41c724eStephen Hines flags |= (pFrom.flag() & (llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC | 160237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHF_EXECINSTR)); 16036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is an input section is not SHF_MERGE, clean this flag 16056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == (pFrom.flag() & llvm::ELF::SHF_MERGE)) 16066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags &= ~llvm::ELF::SHF_MERGE; 16076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is an input section is not SHF_STRINGS, clean this flag 16096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == (pFrom.flag() & llvm::ELF::SHF_STRINGS)) 16106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines flags &= ~llvm::ELF::SHF_STRINGS; 16116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pTo.setFlag(flags); 16136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 16146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 161687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rel entry 161787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel, 161887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 161987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 162037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& pOffset) const { 162187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t r_info = 0x0; 162287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 162387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 162437b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = pRel.r_info; 162537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 162687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap32(pRel.r_offset); 162737b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = mcld::bswap32(pRel.r_info); 162887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 162987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 163087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<unsigned char>(r_info); 163187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 8); 163287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 163387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 163487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 163587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF32_Rela entry 163687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel, 163787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 163887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 163987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset, 164037b74a387bb3993387029859c2d9d051c41c724eStephen Hines int32_t& pAddend) const { 164137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t r_info = 0x0; 164287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 164387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 164437b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = pRel.r_info; 164587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = pRel.r_addend; 164637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 164787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap32(pRel.r_offset); 164837b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = mcld::bswap32(pRel.r_info); 164987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = mcld::bswap32(pRel.r_addend); 165087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 165187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 165287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<unsigned char>(r_info); 165387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 8); 165487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 165587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 165687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 165787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRelocation - read ELF64_Rel entry 165887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel, 165937b74a387bb3993387029859c2d9d051c41c724eStephen Hines Relocation::Type& pType, 166037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& pSymIdx, 166137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t& pOffset) const { 166287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 166387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 166487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 166537b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = pRel.r_info; 166637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 166787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 166837b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = mcld::bswap64(pRel.r_info); 166987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 167087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 167187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<uint32_t>(r_info); 167287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 32); 167387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 167487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 167587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 167687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// readRel - read ELF64_Rela entry 167787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel, 167837b74a387bb3993387029859c2d9d051c41c724eStephen Hines Relocation::Type& pType, 167937b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& pSymIdx, 168037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t& pOffset, 168137b74a387bb3993387029859c2d9d051c41c724eStephen Hines int64_t& pAddend) const { 168287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 168387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 168487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 168537b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = pRel.r_info; 168687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = pRel.r_addend; 168737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 168887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 168937b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = mcld::bswap64(pRel.r_info); 169087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = mcld::bswap64(pRel.r_addend); 169187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 169287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 169387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = static_cast<uint32_t>(r_info); 169487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = (r_info >> 32); 169587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 169687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 169787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 169887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rel entry 169987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel, 170087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 170187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 170237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t pOffset) const { 170387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 170487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 170587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 170687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 170787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF32_Rela entry 170887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel, 170987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 171087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 171187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset, 171237b74a387bb3993387029859c2d9d051c41c724eStephen Hines int32_t pAddend) const { 171387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 171487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_addend = pAddend; 171587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 171687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 171787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 171887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rel entry 171987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel, 172087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 172187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 172237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t pOffset) const { 172387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 172487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 172587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 172687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 172787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitRelocation - write data to the ELF64_Rela entry 172887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid GNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel, 172987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 173087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 173187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset, 173237b74a387bb3993387029859c2d9d051c41c724eStephen Hines int64_t pAddend) const { 173387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 173487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_addend = pAddend; 173587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.setSymbolAndType(pSymIdx, pType); 173687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 173787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 17385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createProgramHdrs - base on output sections to create the program headers 173937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::createProgramHdrs(Module& pModule) { 174037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFFileFormat* file_format = getOutputFormat(); 1741affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 17425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_INTERP 1743affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasInterp()) { 174487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // make PT_PHDR 174587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().produce(llvm::ELF::PT_PHDR); 174687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 174787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* interp_seg = elfSegmentTable().produce(llvm::ELF::PT_INTERP); 174887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines interp_seg->append(&file_format->getInterp()); 1749affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 175187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t cur_flag, prev_flag = 0x0; 17525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFSegment* load_seg = NULL; 17535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make possible PT_LOAD segments 175487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript& ldscript = pModule.getScript(); 175537b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkerScript::AddressMap::iterator addrEnd = ldscript.addressMap().end(); 175687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, prev, outBegin, outEnd; 175787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = ldscript.sectionMap().begin(); 175887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = ldscript.sectionMap().end(); 175987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin, prev = outEnd; out != outEnd; prev = out, ++out) { 176087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* sect = (*out)->getSection(); 176187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 176287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (0 == (sect->flag() & llvm::ELF::SHF_ALLOC) && 176387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDFileFormat::Null != sect->kind()) 176487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 1765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 176687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // bypass empty sections 176787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!(*out)->hasContent() && 176887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() != LDFileFormat::Null) 17695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 17705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 177187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur_flag = getSegmentFlag(sect->flag()); 177222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool createPT_LOAD = false; 177387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LDFileFormat::Null == sect->kind()) { 177422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. create text segment 177522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 177637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (!config().options().omagic() && 177737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (prev_flag & llvm::ELF::PF_W) ^ (cur_flag & llvm::ELF::PF_W)) { 177822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. create data segment if w/o omagic set 177922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 178037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (sect->kind() == LDFileFormat::BSS && load_seg->isDataSegment() && 178137b74a387bb3993387029859c2d9d051c41c724eStephen Hines addrEnd != ldscript.addressMap().find(".bss")) { 178222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. create bss segment if w/ -Tbss and there is a data segment 178322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createPT_LOAD = true; 178437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if ((sect != &(file_format->getText())) && 178537b74a387bb3993387029859c2d9d051c41c724eStephen Hines (sect != &(file_format->getData())) && 178637b74a387bb3993387029859c2d9d051c41c724eStephen Hines (sect != &(file_format->getBSS())) && 178737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (addrEnd != ldscript.addressMap().find(sect->name()))) { 178887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 4. create PT_LOAD for sections in address map except for text, data, 178987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // and bss 179087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines createPT_LOAD = true; 179137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (LDFileFormat::Null == (*prev)->getSection()->kind() && 179237b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().options().getScriptList().empty()) { 179387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 5. create PT_LOAD to hold NULL section if there is a default ldscript 179487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines createPT_LOAD = true; 179522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 17965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 179722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (createPT_LOAD) { 179822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create new PT_LOAD segment 179987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines load_seg = elfSegmentTable().produce(llvm::ELF::PT_LOAD, cur_flag); 18006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().options().nmagic() && !config().options().omagic()) 18016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines load_seg->setAlign(abiPageSize()); 18025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 180437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(load_seg != NULL); 180587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines load_seg->append(sect); 180622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cur_flag != prev_flag) 180722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao load_seg->updateFlag(cur_flag); 18085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 180922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao prev_flag = cur_flag; 18105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // make PT_DYNAMIC 1813affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasDynamic()) { 181437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFSegment* dyn_seg = elfSegmentTable().produce( 181537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::PT_DYNAMIC, llvm::ELF::PF_R | llvm::ELF::PF_W); 181687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines dyn_seg->append(&file_format->getDynamic()); 1817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1818affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 181922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasRelro()) { 1820affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_RELRO 182187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* relro_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_RELRO); 182222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 182337b74a387bb3993387029859c2d9d051c41c724eStephen Hines segEnd = elfSegmentTable().end(); 182437b74a387bb3993387029859c2d9d051c41c724eStephen Hines seg != segEnd; 182537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++seg) { 182687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::PT_LOAD != (*seg)->type()) 182722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 182822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 182937b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (ELFSegment::iterator sect = (*seg)->begin(), sectEnd = (*seg)->end(); 183037b74a387bb3993387029859c2d9d051c41c724eStephen Hines sect != sectEnd; 183137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++sect) { 183222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao unsigned int order = getSectionOrder(**sect); 183337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (SHO_RELRO_LOCAL == order || SHO_RELRO == order || 183422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SHO_RELRO_LAST == order) { 183587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines relro_seg->append(*sect); 183622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1837affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1838affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 18395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 18405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1841affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // make PT_GNU_EH_FRAME 1842affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (file_format->hasEhFrameHdr()) { 184387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* eh_seg = elfSegmentTable().produce(llvm::ELF::PT_GNU_EH_FRAME); 184487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_seg->append(&file_format->getEhFrameHdr()); 1845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 184622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 184722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_TLS 184822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData() || file_format->hasTBSS()) { 184987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment* tls_seg = elfSegmentTable().produce(llvm::ELF::PT_TLS); 185022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTData()) 185187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines tls_seg->append(&file_format->getTData()); 185222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasTBSS()) 185387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines tls_seg->append(&file_format->getTBSS()); 185422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 185522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 185622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // make PT_GNU_STACK 185722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (file_format->hasStackNote()) { 185837b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t flag = getSegmentFlag(file_format->getStackNote().flag()); 185987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().produce(llvm::ELF::PT_GNU_STACK, 186037b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::PF_R | llvm::ELF::PF_W | flag); 186122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 186222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 18636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // make PT_NOTE 186437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFSegment* note_seg = NULL; 186587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines prev_flag = 0x0; 186687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Module::iterator sect, sectBegin, sectEnd; 186787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectBegin = pModule.begin(); 186887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectEnd = pModule.end(); 186987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = sectBegin; sect != sectEnd; ++sect) { 187087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*sect)->type() != llvm::ELF::SHT_NOTE || 18716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ((*sect)->flag() & llvm::ELF::SHF_ALLOC) == 0) 18726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines continue; 18736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 18746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines cur_flag = getSegmentFlag((*sect)->flag()); 18756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // we have different section orders for read-only and writable notes, so 18766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // create 2 segments if needed. 18776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (note_seg == NULL || 18786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (cur_flag & llvm::ELF::PF_W) != (prev_flag & llvm::ELF::PF_W)) 187987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines note_seg = elfSegmentTable().produce(llvm::ELF::PT_NOTE, cur_flag); 18806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 188187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines note_seg->append(*sect); 18826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines prev_flag = cur_flag; 18836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 18846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 188522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create target dependent segments 18866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines doCreateProgramHdrs(pModule); 1887affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1888affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1889affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// setupProgramHdrs - set up the attributes of segments 189037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setupProgramHdrs(const LinkerScript& pScript) { 18915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // update segment info 189287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (ELFSegmentFactory::iterator seg = elfSegmentTable().begin(), 189337b74a387bb3993387029859c2d9d051c41c724eStephen Hines segEnd = elfSegmentTable().end(); 189437b74a387bb3993387029859c2d9d051c41c724eStephen Hines seg != segEnd; 189537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++seg) { 189687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // bypass if there is no section in this segment (e.g., PT_GNU_STACK) 189787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->size() == 0) 189887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 189987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 190087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // bypass the PT_LOAD that only has NULL section now 190187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->type() == llvm::ELF::PT_LOAD && 190237b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*seg)->front()->kind() == LDFileFormat::Null && (*seg)->size() == 1) 190337b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 190487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 190587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setOffset((*seg)->front()->offset()); 190687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->type() == llvm::ELF::PT_LOAD && 190787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->front()->kind() == LDFileFormat::Null) { 190887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const LDSection* second = *((*seg)->begin() + 1); 190987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(second != NULL); 191087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setVaddr(second->addr() - second->offset()); 191187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 191287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setVaddr((*seg)->front()->addr()); 191387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 191487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setPaddr((*seg)->vaddr()); 191587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 191687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment::reverse_iterator sect, sectREnd = (*seg)->rend(); 191787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = (*seg)->rbegin(); sect != sectREnd; ++sect) { 191887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*sect)->kind() != LDFileFormat::BSS) 191987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 192087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 192187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (sect != sectREnd) { 192237b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*seg)->setFilesz((*sect)->offset() + (*sect)->size() - (*seg)->offset()); 192387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 192487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setFilesz(0x0); 192587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 192687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 192737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*seg)->setMemsz((*seg)->back()->addr() + (*seg)->back()->size() - 192887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->vaddr()); 192937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 193087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 193187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // handle the case if text segment only has NULL section 193287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* null_sect = &getOutputFormat()->getNULLSection(); 193387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator null_seg = 193437b74a387bb3993387029859c2d9d051c41c724eStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect); 193587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 193687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*null_seg)->size() == 1) { 193787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // find 2nd PT_LOAD 193887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end(); 193987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (seg = null_seg + 1; seg != segEnd; ++seg) { 194087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->type() == llvm::ELF::PT_LOAD) 194187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 194287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 194387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (seg != segEnd) { 194487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t addr = (*seg)->front()->addr() - (*seg)->front()->offset(); 194587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t size = sectionStartOffset(); 194687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (addr + size == (*seg)->front()->addr()) { 194787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // if there is no space between the 2 segments, we can merge them. 194887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setOffset(0x0); 194987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setVaddr(addr); 195087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setPaddr(addr); 195187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 195287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment::iterator sect, sectEnd = (*seg)->end(); 195387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = (*seg)->begin(); sect != sectEnd; ++sect) { 195487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*sect)->kind() == LDFileFormat::BSS) { 195587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines --sect; 195687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 195787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 195887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 195987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (sect == sectEnd) { 196037b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*seg)->setFilesz((*seg)->back()->offset() + (*seg)->back()->size() - 196187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->offset()); 196287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if (*sect != (*seg)->front()) { 196387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines --sect; 196437b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*seg)->setFilesz((*sect)->offset() + (*sect)->size() - 196587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->offset()); 196687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 196787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->setFilesz(0x0); 196887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 196987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 197037b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*seg)->setMemsz((*seg)->back()->addr() + (*seg)->back()->size() - 197187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->vaddr()); 197287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 197387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*seg)->insert((*seg)->begin(), null_sect); 197487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().erase(null_seg); 197587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 197687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if (addr + size < (*seg)->vaddr()) { 197787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setOffset(0x0); 197887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setVaddr(addr); 197987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setPaddr(addr); 198087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setFilesz(size); 198187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*null_seg)->setMemsz(size); 198287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 198387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // erase the non valid segment contains NULL. 198487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().erase(null_seg); 198587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 198687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 198787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 198887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 198987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up PT_PHDR 199087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator phdr = 199137b74a387bb3993387029859c2d9d051c41c724eStephen Hines elfSegmentTable().find(llvm::ELF::PT_PHDR, llvm::ELF::PF_R, 0x0); 199287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 199387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (phdr != elfSegmentTable().end()) { 199487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator null_seg = 199537b74a387bb3993387029859c2d9d051c41c724eStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, null_sect); 199687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (null_seg != elfSegmentTable().end()) { 199787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t offset = 0x0, phdr_size = 0x0; 1998d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) { 19995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf32_Ehdr); 20005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf32_Phdr); 200187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 20025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = sizeof(llvm::ELF::Elf64_Ehdr); 20035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao phdr_size = sizeof(llvm::ELF::Elf64_Phdr); 20045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 200587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setOffset(offset); 200687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setVaddr((*null_seg)->vaddr() + offset); 200787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setPaddr((*phdr)->vaddr()); 200887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setFilesz(elfSegmentTable().size() * phdr_size); 200987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setMemsz(elfSegmentTable().size() * phdr_size); 201087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*phdr)->setAlign(config().targets().bitclass() / 8); 201187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 201287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().erase(phdr); 20135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 20145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 20155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 20165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 201787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// getSegmentFlag - give a section flag and return the corresponding segment 201887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// flag 201937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint32_t GNULDBackend::getSegmentFlag(const uint32_t pSectionFlag) { 202087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t flag = 0x0; 202187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pSectionFlag & llvm::ELF::SHF_ALLOC) != 0x0) 202287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag |= llvm::ELF::PF_R; 202387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pSectionFlag & llvm::ELF::SHF_WRITE) != 0x0) 202487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag |= llvm::ELF::PF_W; 202587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pSectionFlag & llvm::ELF::SHF_EXECINSTR) != 0x0) 202687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag |= llvm::ELF::PF_X; 202787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return flag; 202887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 202987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 203022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output 203137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setupGNUStackInfo(Module& pModule) { 2032affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t flag = 0x0; 203322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasStackSet()) { 2034affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 1. check the command line option (-z execstack or -z noexecstack) 203522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasExecStack()) 2036affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 203737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 2038affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. check the stack info from the input objects 203922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: since we alway emit .note.GNU-stack in output now, we may be able 204022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to check this from the output .note.GNU-stack directly after section 204122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // merging is done 2042affc150dc44fab1911775a49636d0ce85333b634Zonr Chang size_t object_count = 0, stack_note_count = 0; 204322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_obj_iterator obj, objEnd = pModule.obj_end(); 204422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (obj = pModule.obj_begin(); obj != objEnd; ++obj) { 204522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++object_count; 204622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* sect = (*obj)->context()->getSection(".note.GNU-stack"); 204737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (sect != NULL) { 204822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++stack_note_count; 204922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2.1 found a stack note that is set as executable 205022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 != (llvm::ELF::SHF_EXECINSTR & sect->flag())) { 205122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao flag = llvm::ELF::SHF_EXECINSTR; 205222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 2053affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2054affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2055affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 20565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2057affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.2 there are no stack note sections in all input objects 2058affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == stack_note_count) 2059affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 20605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2061affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2.3 a special case. Use the target default to decide if the stack should 2062affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // be executable 2063affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (llvm::ELF::SHF_EXECINSTR != flag && object_count != stack_note_count) 20646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_pInfo->isDefaultExecStack()) 2065affc150dc44fab1911775a49636d0ce85333b634Zonr Chang flag = llvm::ELF::SHF_EXECINSTR; 20665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 20675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 206822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (getOutputFormat()->hasStackNote()) { 206922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getOutputFormat()->getStackNote().setFlag(flag); 207022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 207122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 207222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 207387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionOffset - helper function to set output sections' offset. 207437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setOutputSectionOffset(Module& pModule) { 207587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript& script = pModule.getScript(); 207687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t offset = 0x0; 207787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* cur = NULL; 207887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* prev = NULL; 207987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 208087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = script.sectionMap().begin(); 208187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = script.sectionMap().end(); 208287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; ++out, prev = cur) { 208387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur = (*out)->getSection(); 208487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (cur->kind() == LDFileFormat::Null) { 208587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(0x0); 208687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 208787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 208822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 208987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (prev->kind()) { 209037b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Null: 209137b74a387bb3993387029859c2d9d051c41c724eStephen Hines offset = sectionStartOffset(); 209237b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 209337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::BSS: 209437b74a387bb3993387029859c2d9d051c41c724eStephen Hines offset = prev->offset(); 209537b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 209637b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 209737b74a387bb3993387029859c2d9d051c41c724eStephen Hines offset = prev->offset() + prev->size(); 209837b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 209922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 210087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(offset, cur->align()); 210187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(offset); 210287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 210387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 210487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 210587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// setOutputSectionAddress - helper function to set output sections' address. 210637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::setOutputSectionAddress(Module& pModule) { 210787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines RpnEvaluator evaluator(pModule, *this); 210887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript& script = pModule.getScript(); 210987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t vma = 0x0, offset = 0x0; 211087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* cur = NULL; 211187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* prev = NULL; 211287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LinkerScript::AddressMap::iterator addr, addrEnd = script.addressMap().end(); 211387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::iterator seg, segEnd = elfSegmentTable().end(); 211487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::Output::dot_iterator dot; 211587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 211687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = script.sectionMap().begin(); 211787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = script.sectionMap().end(); 211887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; prev = cur, ++out) { 211987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur = (*out)->getSection(); 212087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 212187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (cur->kind() == LDFileFormat::Null) { 212287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(0x0); 212322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 212487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 212522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 212687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // process dot assignments between 2 output sections 212787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::Output::dot_iterator it = (*out)->dot_begin(), 212837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ie = (*out)->dot_end(); 212937b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 213037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 213187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*it).assign(evaluator); 213287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 213387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 213487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines seg = elfSegmentTable().find(llvm::ELF::PT_LOAD, cur); 213587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (seg != segEnd && cur == (*seg)->front()) { 213687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*seg)->isBssSegment()) 213787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = script.addressMap().find(".bss"); 213887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if ((*seg)->isDataSegment()) 213987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = script.addressMap().find(".data"); 214087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 214187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = script.addressMap().find(cur->name()); 214287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else 214387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addr = addrEnd; 214422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 214587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (addr != addrEnd) { 21466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // use address mapping in script options 214787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = addr.getEntry()->value(); 214887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if ((*out)->prolog().hasVMA()) { 214987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // use address from output section description 215087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines evaluator.eval((*out)->prolog().vma(), vma); 215187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if ((dot = (*out)->find_last_explicit_dot()) != (*out)->dot_end()) { 215287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // assign address based on `.' symbol in ldscript 215387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = (*dot).symbol().value(); 215487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(vma, cur->align()); 215587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 215687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->prolog().type() == OutputSectDesc::NOLOAD) { 215787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = prev->addr() + prev->size(); 215887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0) { 215987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (prev->kind() == LDFileFormat::Null) { 216087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Let SECTIONS starts at 0 if we have a default ldscript but don't 216187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // have any initial value (VMA or `.'). 216287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!config().options().getScriptList().empty()) 216387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = 0x0; 216487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 216587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = getSegmentStartAddr(script) + sectionStartOffset(); 216687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 216787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((prev->kind() == LDFileFormat::BSS)) 216887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = prev->addr(); 216987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 217087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = prev->addr() + prev->size(); 217187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 217287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(vma, cur->align()); 217387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().getScriptList().empty()) { 217487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (seg != segEnd && cur == (*seg)->front()) { 217587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Try to align p_vaddr at page boundary if not in script options. 217687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // To do so will add more padding in file, but can save one page 217787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // at runtime. 2178b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Avoid doing this optimization if -z relro is given, because there 2179b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // seems to be too many padding. 2180b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!config().options().hasRelro()) { 2181b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines alignAddress(vma, (*seg)->align()); 2182b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } else { 2183b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines vma += abiPageSize(); 2184b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 218587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 218687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 218787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 218887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines vma = 0x0; 218922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 21906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 219122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 219287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().hasRelro()) { 219387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // if -z relro is given, we need to adjust sections' offset again, and 219487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // let PT_GNU_RELRO end on a abi page boundary 219587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 219687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // check if current is the first non-relro section 219787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator relro_last = out - 1; 219837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (relro_last != outEnd && (*relro_last)->order() <= SHO_RELRO_LAST && 219987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->order() > SHO_RELRO_LAST) { 220087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // align the first non-relro section to page boundary 220187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(vma, abiPageSize()); 220287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 220387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // It seems that compiler think .got and .got.plt are continuous (w/o 220487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // any padding between). If .got is the last section in PT_RELRO and 220587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // it's not continuous to its next section (i.e. .got.plt), we need to 220687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // add padding in front of .got instead. 220787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FIXME: Maybe we can handle this in a more general way. 220887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& got = getOutputFormat()->getGOT(); 220987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((getSectionOrder(got) == SHO_RELRO_LAST) && 221087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (got.addr() + got.size() < vma)) { 221187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t diff = vma - got.addr() - got.size(); 221287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines got.setAddr(vma - got.size()); 221387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines got.setOffset(got.offset() + diff); 221487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 221587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 221637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of if - for relro processing 221787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 221887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setAddr(vma); 221987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 222087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (prev->kind()) { 222137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Null: 222237b74a387bb3993387029859c2d9d051c41c724eStephen Hines offset = sectionStartOffset(); 222337b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 222437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::BSS: 222537b74a387bb3993387029859c2d9d051c41c724eStephen Hines offset = prev->offset(); 222637b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 222737b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 222837b74a387bb3993387029859c2d9d051c41c724eStephen Hines offset = prev->offset() + prev->size(); 222937b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 223087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 223187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines alignAddress(offset, cur->align()); 22326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf 22336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // p_align: As "Program Loading" describes in this chapter of the 22346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // processor supplement, loadable process segments must have congruent 22356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // values for p_vaddr and p_offset, modulo the page size. 223687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FIXME: Now make all sh_addr and sh_offset are congruent, modulo the page 223787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // size. Otherwise, old objcopy (e.g., binutils 2.17) may fail with our 223887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // output! 223987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((cur->flag() & llvm::ELF::SHF_ALLOC) != 0 && 224087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (vma & (abiPageSize() - 1)) != (offset & (abiPageSize() - 1))) { 224137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t padding = abiPageSize() + (vma & (abiPageSize() - 1)) - 224287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (offset & (abiPageSize() - 1)); 224387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += padding; 224422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 224522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 224687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setOffset(offset); 224722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 224887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // process dot assignments in the output section 224987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool changed = false; 225087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* invalid = NULL; 225187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::Output::iterator in = (*out)->begin(), 225237b74a387bb3993387029859c2d9d051c41c724eStephen Hines inEnd = (*out)->end(); 225337b74a387bb3993387029859c2d9d051c41c724eStephen Hines in != inEnd; 225437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++in) { 225587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (invalid != NULL && !(*in)->dotAssignments().empty()) { 225687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines while (invalid != (*in)->dotAssignments().front().first) { 225787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* prev = invalid->getPrevNode(); 225887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid->setOffset(prev->getOffset() + prev->size()); 225987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = invalid->getNextNode(); 226087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 226187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = NULL; 226287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 226322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 226487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::Input::dot_iterator it = (*in)->dot_begin(), 226537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ie = (*in)->dot_end(); 226637b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 226737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 226887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*it).second.assign(evaluator); 226987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it).first != NULL) { 227087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t new_offset = (*it).second.symbol().value() - vma; 227187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (new_offset != (*it).first->getOffset()) { 227287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*it).first->setOffset(new_offset); 227387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = (*it).first->getNextNode(); 227487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines changed = true; 227587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 227687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 227737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each dot assignment 227837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each input description 227987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 228087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (changed) { 228187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines while (invalid != NULL) { 228287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* prev = invalid->getPrevNode(); 228387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid->setOffset(prev->getOffset() + prev->size()); 228487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = invalid->getNextNode(); 228587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 228687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 228787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->setSize(cur->getSectionData()->back().getOffset() + 228887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cur->getSectionData()->back().size()); 228922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 229037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each output section description 22915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 22925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 229387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// placeOutputSections - place output sections based on SectionMap 229437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::placeOutputSections(Module& pModule) { 229587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines typedef std::vector<LDSection*> Orphans; 229687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Orphans orphans; 229787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap& sectionMap = pModule.getScript().sectionMap(); 229887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2299d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao for (Module::iterator it = pModule.begin(), ie = pModule.end(); it != ie; 230037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 230187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool wanted = false; 230287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2303d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch ((*it)->kind()) { 230437b74a387bb3993387029859c2d9d051c41c724eStephen Hines // take NULL and StackNote directly 230537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Null: 230637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::StackNote: 230787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines wanted = true; 230837b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 230937b74a387bb3993387029859c2d9d051c41c724eStephen Hines // ignore if section size is 0 231037b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::EhFrame: 231137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (((*it)->size() != 0) || 231237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ((*it)->hasEhFrame() && 231337b74a387bb3993387029859c2d9d051c41c724eStephen Hines config().codeGenType() == LinkerConfig::Object)) 231437b74a387bb3993387029859c2d9d051c41c724eStephen Hines wanted = true; 231537b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 231637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Relocation: 231737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (((*it)->size() != 0) || 231837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ((*it)->hasRelocData() && 231937b74a387bb3993387029859c2d9d051c41c724eStephen Hines config().codeGenType() == LinkerConfig::Object)) 232037b74a387bb3993387029859c2d9d051c41c724eStephen Hines wanted = true; 232137b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 232237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::TEXT: 232337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::DATA: 232437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Target: 232537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::MetaData: 232637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::BSS: 232737b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Debug: 232837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::DebugString: 232937b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::GCCExceptTable: 233037b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Note: 233137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::NamePool: 233237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::EhFrameHdr: 233337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (((*it)->size() != 0) || 233437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ((*it)->hasSectionData() && 233537b74a387bb3993387029859c2d9d051c41c724eStephen Hines config().codeGenType() == LinkerConfig::Object)) 233637b74a387bb3993387029859c2d9d051c41c724eStephen Hines wanted = true; 233737b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 233837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Group: 233937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::Object == config().codeGenType()) { 234037b74a387bb3993387029859c2d9d051c41c724eStephen Hines // TODO: support incremental linking 234137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 234237b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 234337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Version: 234437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if ((*it)->size() != 0) { 234537b74a387bb3993387029859c2d9d051c41c724eStephen Hines wanted = true; 234637b74a387bb3993387029859c2d9d051c41c724eStephen Hines warning(diag::warn_unsupported_symbolic_versioning) << (*it)->name(); 234737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 234837b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 234937b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 235037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if ((*it)->size() != 0) { 235137b74a387bb3993387029859c2d9d051c41c724eStephen Hines error(diag::err_unsupported_section) << (*it)->name() 235237b74a387bb3993387029859c2d9d051c41c724eStephen Hines << (*it)->kind(); 235337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 235437b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 235537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 235687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 235787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (wanted) { 235887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 235987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = sectionMap.begin(); 236087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = sectionMap.end(); 236187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; ++out) { 236287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool matched = false; 236387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it)->name().compare((*out)->name()) == 0) { 236487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch ((*out)->prolog().constraint()) { 236537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case OutputSectDesc::NO_CONSTRAINT: 236637b74a387bb3993387029859c2d9d051c41c724eStephen Hines matched = true; 236737b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 236837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case OutputSectDesc::ONLY_IF_RO: 236937b74a387bb3993387029859c2d9d051c41c724eStephen Hines matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) == 0; 237037b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 237137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case OutputSectDesc::ONLY_IF_RW: 237237b74a387bb3993387029859c2d9d051c41c724eStephen Hines matched = ((*it)->flag() & llvm::ELF::SHF_WRITE) != 0; 237337b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 237437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 237587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 237687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (matched) 237787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 237887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 237937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each output section description 238087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 238187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out != outEnd) { 238287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up the section 238387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setSection(*it); 238487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setOrder(getSectionOrder(**it)); 238587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 238687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines orphans.push_back(*it); 238787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 2388d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 238937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each section in Module 239087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 239187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up sections in SectionMap but do not exist at all. 239287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t flag = 0x0; 239387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned int order = SHO_UNDEFINED; 239487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines OutputSectDesc::Type type = OutputSectDesc::LOAD; 239587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::reverse_iterator out = sectionMap.rbegin(), 239637b74a387bb3993387029859c2d9d051c41c724eStephen Hines outEnd = sectionMap.rend(); 239737b74a387bb3993387029859c2d9d051c41c724eStephen Hines out != outEnd; 239837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++out) { 239987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->hasContent() || 240087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::Null || 240187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::StackNote) { 240287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines flag = (*out)->getSection()->flag(); 240387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines order = (*out)->order(); 240487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines type = (*out)->prolog().type(); 240587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 240687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->setFlag(flag); 240787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setOrder(order); 240887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->prolog().setType(type); 240987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 241037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each output section description 241187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 241287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // place orphan sections 241387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (Orphans::iterator it = orphans.begin(), ie = orphans.end(); it != ie; 241437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 241587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t order = getSectionOrder(**it); 241687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap::iterator out, outBegin, outEnd; 241787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outBegin = sectionMap.begin(); 241887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines outEnd = sectionMap.end(); 241987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 242087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*it)->kind() == LDFileFormat::Null) 242187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out = sectionMap.insert(outBegin, *it); 242287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 242387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (out = outBegin; out != outEnd; ++out) { 242487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->order() > order) 242587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 242687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 242787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out = sectionMap.insert(out, *it); 242887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 242987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->setOrder(order); 243037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each orphan section 243187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 243287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // sort output section orders if there is no default ldscript 243387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().getScriptList().empty()) { 243437b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::stable_sort( 243537b74a387bb3993387029859c2d9d051c41c724eStephen Hines sectionMap.begin(), sectionMap.end(), SectionMap::SHOCompare()); 243687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 2437d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 243887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // when section ordering is fixed, now we can make sure dot assignments are 243987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // all set appropriately 244087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sectionMap.fixupDotSymbols(); 244187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 244287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 244387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// layout - layout method 244437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::layout(Module& pModule) { 244587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. place output sections based on SectionMap from SECTIONS command 244687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines placeOutputSections(pModule); 2447d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 244887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. update output sections in Module 244987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionMap& sectionMap = pModule.getScript().sectionMap(); 2450d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pModule.getSectionTable().clear(); 245187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (SectionMap::iterator out = sectionMap.begin(), outEnd = sectionMap.end(); 245237b74a387bb3993387029859c2d9d051c41c724eStephen Hines out != outEnd; 245337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++out) { 245487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((*out)->hasContent() || 245587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::Null || 245687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->kind() == LDFileFormat::StackNote || 245787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines config().codeGenType() == LinkerConfig::Object) { 245887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*out)->getSection()->setIndex(pModule.size()); 245987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pModule.getSectionTable().push_back((*out)->getSection()); 246087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 246137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each output section description 246287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 246387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 3. update the size of .shstrtab 246487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sizeShstrtab(pModule); 2465d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 2466d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // 4. create program headers 2467d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 24686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createProgramHdrs(pModule); 2469d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 2470d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 247187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 5. set output section address/offset 247287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object != config().codeGenType()) 247387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines setOutputSectionAddress(pModule); 247487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 247587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines setOutputSectionOffset(pModule); 2476d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 2477d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 247837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::createAndSizeEhFrameHdr(Module& pModule) { 24796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType() && 24806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // init EhFrameHdr and size the output section 248222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* format = getOutputFormat(); 248337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pEhFrameHdr = 248437b74a387bb3993387029859c2d9d051c41c724eStephen Hines new EhFrameHdr(format->getEhFrameHdr(), format->getEhFrame()); 2485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pEhFrameHdr->sizeOutput(); 2486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 248787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 248887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 24890dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 24900dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/// function pointer access 249137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::mayHaveUnsafeFunctionPointerAccess( 249237b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection& pSection) const { 24930dea6bc96bb52346737966839ac68644f7939f58Stephen Hines llvm::StringRef name(pSection.name()); 24940dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return !name.startswith(".rodata._ZTV") && 24950dea6bc96bb52346737966839ac68644f7939f58Stephen Hines !name.startswith(".data.rel.ro._ZTV") && 24960dea6bc96bb52346737966839ac68644f7939f58Stephen Hines !name.startswith(".rodata._ZTC") && 249737b74a387bb3993387029859c2d9d051c41c724eStephen Hines !name.startswith(".data.rel.ro._ZTC") && !name.startswith(".eh_frame"); 24980dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 24990dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 250087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// preLayout - Backend can do any needed modification before layout 250137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::preLayout(Module& pModule, IRBuilder& pBuilder) { 250287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // prelayout target first 250387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines doPreLayout(pBuilder); 250422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // change .tbss and .tdata section symbol from Local to LocalDyn category 250637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pTDATA != NULL) 2507f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*f_pTDATA); 250822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 250937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pTBSS != NULL) 2510f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.getSymbolTable().changeToDynamic(*f_pTBSS); 251122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 251222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // To merge input's relocation sections into output's relocation sections. 251322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 251422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are generating relocatables (-r), move input relocation sections 251522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // to corresponding output relocation sections. 251622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) { 251722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = pModule.obj_end(); 251822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = pModule.obj_begin(); input != inEnd; ++input) { 251922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 252022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 252122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the output relocation LDSection with identical name. 252222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_sect = pModule.getSection((*rs)->name()); 252337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (output_sect == NULL) { 252437b74a387bb3993387029859c2d9d051c41c724eStephen Hines output_sect = LDSection::Create( 252537b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*rs)->name(), (*rs)->kind(), (*rs)->type(), (*rs)->flag()); 252622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 252722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setAlign((*rs)->align()); 252822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule.getSectionTable().push_back(output_sect); 252922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 253022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 253122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set output relocation section link 253222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* input_link = (*rs)->getLink(); 253337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(input_link != NULL && "Illegal input relocation section."); 253422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 253522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the linked output section 253622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* output_link = pModule.getSection(input_link->name()); 253737b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(output_link != NULL); 253822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 253922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setLink(output_link); 254022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 254122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get output relcoationData, create one if not exist 254222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!output_sect->hasRelocData()) 254322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao IRBuilder::CreateRelocData(*output_sect); 254422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 254522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData* out_reloc_data = output_sect->getRelocData(); 254622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 254722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // move relocations from input's to output's RelcoationData 2548d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& out_list = 254937b74a387bb3993387029859c2d9d051c41c724eStephen Hines out_reloc_data->getRelocationList(); 2550d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao RelocData::RelocationListType& in_list = 255137b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*rs)->getRelocData()->getRelocationList(); 255222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao out_list.splice(out_list.end(), in_list); 255322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 255422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size output 255522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::ELF::SHT_REL == output_sect->type()) 255622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelEntrySize()); 255722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (llvm::ELF::SHT_RELA == output_sect->type()) 255822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao output_sect->setSize(out_reloc_data->size() * getRelaEntrySize()); 255922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 256022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unknown_reloc_section_type) << output_sect->type() 256122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << output_sect->name(); 256222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 256337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for each relocation section 256437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for each input 256537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of if 256622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 256722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up the section flag of .note.GNU-stack section 25686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setupGNUStackInfo(pModule); 25695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 25705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2571cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// postLayout - Backend can do any needed modification after layout 257237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::postLayout(Module& pModule, IRBuilder& pBuilder) { 257322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 257487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // do relaxation 25756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relax(pModule, pBuilder); 257687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up the attributes of program headers 2577f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setupProgramHdrs(pModule.getScript()); 2578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 25806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines doPostLayout(pModule, pBuilder); 25815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 25825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 258337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::postProcessing(FileOutputBuffer& pOutput) { 25846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType() && 25856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config().options().hasEhFrameHdr() && getOutputFormat()->hasEhFrame()) { 2586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // emit eh_frame_hdr 2587f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pEhFrameHdr->emitOutput<32>(pOutput); 2588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 25915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getHashBucketCount - calculate hash bucket count. 25925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols, 259337b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool pIsGNUStyle) { 259437b74a387bb3993387029859c2d9d051c41c724eStephen Hines static const unsigned int buckets[] = { 259537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, 16411, 259637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 32771, 65537, 131101, 262147 25975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao }; 25985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const unsigned buckets_count = sizeof buckets / sizeof buckets[0]; 25995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int result = 1; 26015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (unsigned i = 0; i < buckets_count; ++i) { 26025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pNumOfSymbols < buckets[i]) 26035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 26045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = buckets[i]; 26055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 26065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pIsGNUStyle && result < 2) 26085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = 2; 26095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 26115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 26125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2 261437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned GNULDBackend::getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const { 26156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t maskbitslog2 = 1; 261637b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (uint32_t x = pNumOfSymbols >> 1; x != 0; x >>= 1) 26176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++maskbitslog2; 26186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (maskbitslog2 < 3) 26206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 = 5; 26216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (((1U << (maskbitslog2 - 2)) & pNumOfSymbols) != 0) 26226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 += 3; 26236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 26246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 += 2; 26256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().targets().bitclass() == 64 && maskbitslog2 == 5) 26276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines maskbitslog2 = 6; 26286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return maskbitslog2; 26306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 26316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isDynamicSymbol 263337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol) const { 26345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 26355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol. We should not add it 26365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.binding() == ResolveInfo::Local) 26375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 26385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we are building shared object, and the visibility is external, we 26405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // need to add it. 264122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 264237b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkerConfig::Exec == config().codeGenType() || 2643d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 26445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default || 26456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected) 26465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 264722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 264822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 264922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 265022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 265122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isDynamicSymbol 265237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isDynamicSymbol(const ResolveInfo& pResolveInfo) const { 265322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If a local symbol is in the LDContext's symbol table, it's a real local 265422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol. We should not add it 265522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.binding() == ResolveInfo::Local) 265622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 265722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 265822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If we are building shared object, and the visibility is external, we 265922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // need to add it. 266022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 266137b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkerConfig::Exec == config().codeGenType() || 2662d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType()) { 266322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pResolveInfo.visibility() == ResolveInfo::Default || 26646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pResolveInfo.visibility() == ResolveInfo::Protected) 266522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 266622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2669affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 267087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table 267137b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFSegmentFactory& GNULDBackend::elfSegmentTable() { 267287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!"); 267387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pELFSegmentTable; 267487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 267587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 267687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// elfSegmentTable - return the reference of the elf segment table 267737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ELFSegmentFactory& GNULDBackend::elfSegmentTable() const { 267887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(m_pELFSegmentTable != NULL && "Do not create ELFSegmentTable!"); 267987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pELFSegmentTable; 268087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 268187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// commonPageSize - the common page size of the target machine. 268337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::commonPageSize() const { 268422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().commPageSize() > 0) 268522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return std::min(config().options().commPageSize(), abiPageSize()); 2686affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 26876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return std::min(m_pInfo->commonPageSize(), abiPageSize()); 2688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// abiPageSize - the abi page size of the target machine. 269137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t GNULDBackend::abiPageSize() const { 269222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().maxPageSize() > 0) 269322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return config().options().maxPageSize(); 2694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 26956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pInfo->abiPageSize(); 2696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isSymbolPreemtible - whether the symbol can be preemted by other 2699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// link unit 270037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym) const { 2701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.other() != ResolveInfo::Default) 2702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 270422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This is because the codeGenType of pie is DynObj. And gold linker check 270522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the "shared" option instead. 270622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 270722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 270822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 270922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj != config().codeGenType()) 271022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 271122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 271222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().Bsymbolic()) 2713affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2714affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 271522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // A local defined symbol should be non-preemptible. 271622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // This issue is found when linking libstdc++ on freebsd. A R_386_GOT32 271722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relocation refers to a local defined symbol, and we should generate a 271822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relative dynamic relocation when applying the relocation. 271922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDefine() && pSym.binding() == ResolveInfo::Local) 2720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2721affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2722affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2723affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2724affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 272522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation 27266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsDynRel(const ResolveInfo& pSym, 272722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool pSymHasPLT, 272837b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool isAbsReloc) const { 272922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // an undefined reference in the executables should be statically 273022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // resolved to 0 and no need a dynamic relocation 273137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pSym.isUndef() && !pSym.isDyn() && 273237b74a387bb3993387029859c2d9d051c41c724eStephen Hines (LinkerConfig::Exec == config().codeGenType() || 2733d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary == config().codeGenType())) 273422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 273522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // An absolute symbol can be resolved directly if it is either local 27376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // or we are linking statically. Otherwise it can still be overridden 27386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // at runtime. 27396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSym.isAbsolute() && 27406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (pSym.binding() == ResolveInfo::Local || config().isCodeStatic())) 274122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 27426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() && isAbsReloc) 274322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 274422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSymHasPLT && ResolveInfo::Function == pSym.type()) 274522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 27466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeIndep() && pSymHasPLT) 274722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 274837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pSym.isDyn() || pSym.isUndef() || isSymbolPreemptible(pSym)) 274922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 275022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 275122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 275222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 275322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2754affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsPLT - return whether the symbol needs a PLT entry 275537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::symbolNeedsPLT(const ResolveInfo& pSym) const { 275637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pSym.isUndef() && !pSym.isDyn() && 275722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkerConfig::DynObj != config().codeGenType()) 2758affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2759affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2760affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // An IndirectFunc symbol (i.e., STT_GNU_IFUNC) always needs a plt entry 2761affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() == ResolveInfo::IndirectFunc) 2762affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2763affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2764affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.type() != ResolveInfo::Function) 2765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2766affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 27676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeStatic()) 276822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 276922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 277022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().isPIE()) 2771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2772affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 277337b74a387bb3993387029859c2d9d051c41c724eStephen Hines return (pSym.isDyn() || pSym.isUndef() || isSymbolPreemptible(pSym)); 2774affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2775affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 277622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// symbolHasFinalValue - return true if the symbol's value can be decided at 277722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// link time 277837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::symbolFinalValueIsKnown(const ResolveInfo& pSym) const { 277922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the output is pic code or if not executables, symbols' value may change 278022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // at runtime 27816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: CodeIndep() || LinkerConfig::Relocatable == CodeGenType 27826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().isCodeIndep() || 2783d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::Exec != config().codeGenType() && 2784d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::Binary != config().codeGenType())) 2785affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 278622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 278722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is from dynamic object, then its value is unknown 278822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSym.isDyn()) 2789affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 279022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 279122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is not in dynamic object and is not undefined, then its value 279222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is known 279322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pSym.isUndef()) 2794affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 2795affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 279622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol is undefined and not in dynamic objects, for example, a weak 279722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // undefined symbol, then whether the symbol's final value can be known 279822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // depends on whrther we're doing static link 27996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return config().isCodeStatic(); 2800affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 2801affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2802affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation 28036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::symbolNeedsCopyReloc(const Relocation& pReloc, 280437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ResolveInfo& pSym) const { 2805affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // only the reference from dynamic executable to non-function symbol in 2806affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // the dynamic objects may need copy relocation 280737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (config().isCodeIndep() || !pSym.isDyn() || 280837b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSym.type() == ResolveInfo::Function || pSym.size() == 0) 2809affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2810affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2811affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // check if the option -z nocopyreloc is given 281222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNoCopyReloc()) 2813affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 2814affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // TODO: Is this check necessary? 2816affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if relocation target place is readonly, a copy relocation is needed 281722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t flag = pReloc.targetRef().frag()->getParent()->getSection().flag(); 281822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE)) 2819affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 28205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 28215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 28225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2823affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 282437b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol& GNULDBackend::getTDATASymbol() { 282537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(f_pTDATA != NULL); 282622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 282722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 282822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 282937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst LDSymbol& GNULDBackend::getTDATASymbol() const { 283037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(f_pTDATA != NULL); 283122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTDATA; 283222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 283322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 283437b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol& GNULDBackend::getTBSSSymbol() { 283537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(f_pTBSS != NULL); 283622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 283722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 283822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 283937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst LDSymbol& GNULDBackend::getTBSSSymbol() const { 284037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(f_pTBSS != NULL); 284122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *f_pTBSS; 284222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 284322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 284437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef GNULDBackend::getEntry(const Module& pModule) const { 284587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pModule.getScript().hasEntry()) 284687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return pModule.getScript().entry(); 284787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 284887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return getInfo().entry(); 284987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 285087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 285137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::checkAndSetHasTextRel(const LDSection& pSection) { 285222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_bHasTextRel) 285322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 285422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 285522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the target section of the dynamic relocation is ALLOCATE but is not 285622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // writable, than we should set DF_TEXTREL 285722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const uint32_t flag = pSection.flag(); 285822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (flag & llvm::ELF::SHF_WRITE) && (flag & llvm::ELF::SHF_ALLOC)) 285922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_bHasTextRel = true; 286022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 286122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 286222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 286322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 286487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// sortRelocation - sort the dynamic relocations to let dynamic linker 286587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// process relocations more efficiently 286637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid GNULDBackend::sortRelocation(LDSection& pSection) { 286787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!config().options().hasCombReloc()) 286887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 286987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 287087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(pSection.kind() == LDFileFormat::Relocation); 287187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 287287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (config().codeGenType()) { 287337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LinkerConfig::DynObj: 287437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LinkerConfig::Exec: 287537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (&pSection == &getOutputFormat()->getRelDyn() || 287637b74a387bb3993387029859c2d9d051c41c724eStephen Hines &pSection == &getOutputFormat()->getRelaDyn()) { 287737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pSection.hasRelocData()) 287837b74a387bb3993387029859c2d9d051c41c724eStephen Hines pSection.getRelocData()->sort(RelocCompare(*this)); 287937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 288037b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 288137b74a387bb3993387029859c2d9d051c41c724eStephen Hines return; 288287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 288387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 288487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2885b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesunsigned GNULDBackend::stubGroupSize() const { 2886b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const unsigned group_size = config().targets().getStubGroupSize(); 2887b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (group_size == 0) { 2888b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return m_pInfo->stubGroupSize(); 2889b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } else { 2890b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return group_size; 2891b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 2892b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 2893b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 289422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initBRIslandFactory - initialize the branch island factory for relaxation 289537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initBRIslandFactory() { 289637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pBRIslandFactory == NULL) { 2897b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pBRIslandFactory = new BranchIslandFactory(maxFwdBranchOffset(), 2898b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines maxBwdBranchOffset(), 2899b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines stubGroupSize()); 290022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 290122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 290222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 290322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 290422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// initStubFactory - initialize the stub factory for relaxation 290537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::initStubFactory() { 290637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pStubFactory == NULL) { 290722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pStubFactory = new StubFactory(); 290822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 290922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 291022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 291122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 291237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) { 291322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!mayRelax()) 291422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 291522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 291687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getBRIslandFactory()->group(pModule); 291787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 291822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool finished = true; 291922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao do { 29206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (doRelax(pModule, pBuilder, finished)) { 292187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines setOutputSectionAddress(pModule); 292222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 292322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } while (!finished); 292422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 292522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 292622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 292722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 292837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNULDBackend::DynsymCompare::needGNUHash(const LDSymbol& X) const { 29296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: in bfd and gold linker, an undefined symbol might be hashed 29306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // when the ouput is not PIC, if the symbol is referred by a non pc-relative 29316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // reloc, and its value is set to the addr of the plt entry. 29326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return !X.resolveInfo()->isUndef() && !X.isDyn(); 29336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 29346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 29356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool GNULDBackend::DynsymCompare::operator()(const LDSymbol* X, 293637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSymbol* Y) const { 29376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return !needGNUHash(*X) && needGNUHash(*Y); 29386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 29396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2940a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesbool GNULDBackend::RelocCompare::operator()(const Relocation& X, 2941a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines const Relocation& Y) const { 294287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. compare if relocation is relative 2943a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (X.symInfo() == NULL) { 2944a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (Y.symInfo() != NULL) 294587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 2946a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else if (Y.symInfo() == NULL) { 294787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 294887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 294987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. compare the symbol index 2950a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines size_t symIdxX = m_Backend.getSymbolIdx(X.symInfo()->outSymbol()); 2951a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines size_t symIdxY = m_Backend.getSymbolIdx(Y.symInfo()->outSymbol()); 295287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (symIdxX < symIdxY) 295387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 295487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (symIdxX > symIdxY) 295587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 295687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 295787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 295887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 3. compare the relocation address 2959a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (X.place() < Y.place()) 296087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 2961a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (X.place() > Y.place()) 296287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 296387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 296487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 4. compare the relocation type 2965a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (X.type() < Y.type()) 296687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 2967a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (X.type() > Y.type()) 296887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 296987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 297087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 5. compare the addend 2971a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (X.addend() < Y.addend()) 297287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 2973a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (X.addend() > Y.addend()) 297487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 297587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 297687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 297787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 297837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 297937b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 2980