15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- X86LDBackend.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//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86.h" 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86ELFDynamic.h" 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86LDBackend.h" 12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "X86Relocator.h" 13d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "X86GNUInfo.h" 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/RegionFragment.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/TargetRegistry.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/StringRef.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 26cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Dwarf.h> 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// X86GNULDBackend 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig, 37551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo, 38551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines Relocation::Type pCopyRel) 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines : GNULDBackend(pConfig, pInfo), 4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelocator(NULL), 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLT(NULL), 4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelDyn(NULL), 4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelPLT(NULL), 4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pDynamic(NULL), 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol(NULL), 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_CopyRel(pCopyRel) { 4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::Triple::ArchType arch = pConfig.targets().triple().getArch(); 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64); 4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (arch == llvm::Triple::x86 || 5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pConfig.targets().triple().getEnvironment() == llvm::Triple::GNUX32) { 516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelEntrySize = 8; 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelaEntrySize = 12; 5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (arch == llvm::Triple::x86) 546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_PointerRel = llvm::ELF::R_386_32; 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_PointerRel = llvm::ELF::R_X86_64_32; 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelEntrySize = 16; 596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelaEntrySize = 24; 606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_PointerRel = llvm::ELF::R_X86_64_64; 616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6437b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86GNULDBackend::~X86GNULDBackend() { 65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pRelocator; 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pPLT; 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelPLT; 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst Relocator* X86GNULDBackend::getRelocator() const { 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 740dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return m_pRelocator; 750dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 7737b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocator* X86GNULDBackend::getRelocator() { 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 79d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86GNULDBackend::doPreLayout(IRBuilder& pBuilder) { 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!config().isCodeStatic() && m_pDynamic == NULL) 856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new X86ELFDynamic(*this, config()); 866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt and .got sizes 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // when building shared object, the .got section is must 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setGOTSectionSize(pBuilder); 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .plt size 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pPLT->hasPLT1()) 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT->finalizeSectionSize(); 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .rel.dyn/.rela.dyn size 976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelDyn->empty()) { 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setRelDynSize(); 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .rel.plt/.rela.plt size 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelPLT->empty()) { 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setRelPLTSize(); 1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().genUnwindInfo()) 11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addEhFrameForPLT(pBuilder.getModule()); 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86GNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) { 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 12137b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86ELFDynamic& X86GNULDBackend::dynamic() { 12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 12837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst X86ELFDynamic& X86GNULDBackend::dynamic() const { 12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) { 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ 135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 13737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(pFrag, 0x0), 14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 14737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 14837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(pFrag, 0x0), 15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, 15937b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pRegion.size() && "Size of MemoryRegion is zero!"); 1616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* FileFormat = getOutputFormat(); 1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(FileFormat && 1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = 0; 1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 16987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) { 17087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned char* buffer = pRegion.begin(); 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT->applyPLT0(); 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT->applyPLT1(); 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86PLT::iterator it = m_pPLT->begin(); 1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += plt0_size; 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++it; 1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines PLTEntryBase* plt1 = 0; 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86PLT::iterator ie = m_pPLT->end(); 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines while (it != ie) { 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines plt1 = &(llvm::cast<PLTEntryBase>(*it)); 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines EntrySize = plt1->size(); 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); 1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++it; 1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 19037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) { 1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += emitGOTSectionData(pRegion); 19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (FileFormat->hasGOTPLT() && 19337b74a387bb3993387029859c2d9d051c41c724eStephen Hines (&pSection == &(FileFormat->getGOTPLT()))) { 1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); 19537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines fatal(diag::unrecognized_output_sectoin) << pSection.name() 19737b74a387bb3993387029859c2d9d051c41c724eStephen Hines << "mclinker@googlegroups.com"; 1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 20237b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86PLT& X86GNULDBackend::getPLT() { 20337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 20737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst X86PLT& X86GNULDBackend::getPLT() const { 20837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 21237b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& X86GNULDBackend::getRelDyn() { 21337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelDyn != NULL && ".rel.dyn/.rela.dyn section not exist"); 2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelDyn; 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 21737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelDyn() const { 21837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelDyn != NULL && ".rel.dyn/.rela.dyn section not exist"); 2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelDyn; 2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 22237b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& X86GNULDBackend::getRelPLT() { 22337b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelPLT != NULL && ".rel.plt/.rela.plt section not exist"); 2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelPLT; 2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 22737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelPLT() const { 22837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelPLT != NULL && ".rel.plt/.rela.plt section not exist"); 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelPLT; 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int X86GNULDBackend::getTargetSectionOrder( 23337b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection& pSectHdr) const { 2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* file_format = getOutputFormat(); 2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().options().hasNow()) 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO; 2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO_LAST; 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) { 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().options().hasNow()) 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO; 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_NON_RELRO_FIRST; 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_PLT; 2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_UNDEFINED; 2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 25437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) { 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // same name in input 2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = 25937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 26237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 26337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 26437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 26537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 26637b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 26737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 27137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86GNULDBackend::addEhFrameForPLT(Module& pModule) { 27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* plt_sect = pModule.getSection(".plt"); 27387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!plt_sect || plt_sect->size() == 0u) 27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 27687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* eh_sect = pModule.getSection(".eh_frame"); 27787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!eh_sect || !eh_sect->hasEhFrame()) 27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 27987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 28087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame* eh_frame = eh_sect->getEhFrame(); 28187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::FragmentListType& frag_list = 28287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->getSectionData()->getFragmentList(); 28387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef cie_region = createCIERegionForPLT(); 28487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef fde_region = createFDERegionForPLT(); 28587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::CIE* cie = new EhFrame::GeneratedCIE(cie_region); 28687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::FDE* fde = new EhFrame::GeneratedFDE(fde_region, *cie); 28787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Augmentation data only contains FDE encoding. 28837b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t aug_data = 28937b74a387bb3993387029859c2d9d051c41c724eStephen Hines (uint8_t)(llvm::dwarf::DW_EH_PE_pcrel | llvm::dwarf::DW_EH_PE_sdata4); 29087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->setFDEEncode(aug_data); 29187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->setAugmentationData(std::string(1, aug_data)); 29287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 29387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::cie_iterator i = eh_frame->cie_begin(); 29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (EhFrame::cie_iterator e = eh_frame->cie_end(); i != e; ++i) { 29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::CIE& exist_cie = **i; 29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (exist_cie == *cie) { 29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Insert the FDE fragment 29887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::iterator cur_iter(exist_cie); 29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag_list.insertAfter(cur_iter, fde); 30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines fde->setCIE(exist_cie); 30187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 30287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Cleanup the CIE we created 30387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->clearFDEs(); 30487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete cie; 30587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 30687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 30787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 30887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (i == eh_frame->cie_end()) { 30987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Newly insert 31087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->addCIE(*cie); 31187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->addFDE(*fde); 31287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 31387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 31487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value 31637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool X86GNULDBackend::finalizeTargetSymbols() { 3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 3186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the 3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments 32237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule) { 3236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO 3246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig, 327551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo) 32837b74a387bb3993387029859c2d9d051c41c724eStephen Hines : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY), 32937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOT(NULL), 33037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTPLT(NULL) { 3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 33337b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86_32GNULDBackend::~X86_32GNULDBackend() { 3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOT; 3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOTPLT; 3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 33837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool X86_32GNULDBackend::initRelocator() { 33937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pRelocator == NULL) { 340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new X86_32Relocator(*this, config()); 3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::initTargetSections(Module& pModule, 34637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got 3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& got = file_format->getGOT(); 3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new X86_32GOT(got); 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got.plt 3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& gotplt = file_format->getGOTPLT(); 3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT = new X86_32GOTPLT(gotplt); 356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .plt 3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& plt = file_format->getPLT(); 35987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines plt.setAlign(16u); 360551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT = new X86_32PLT(plt, *m_pGOTPLT, config()); 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rel.plt 3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& relplt = file_format->getRelPlt(); 3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relplt.setLink(&plt); 3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pRelPLT = new OutputRelocSection(pModule, relplt); 3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rel.dyn 3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& reldyn = file_format->getRelDyn(); 3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pRelDyn = new OutputRelocSection(pModule, reldyn); 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 37337b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86_32GOT& X86_32GNULDBackend::getGOT() { 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 37837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst X86_32GOT& X86_32GNULDBackend::getGOT() const { 37937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 38337b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() { 38437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOTPLT; 3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 38837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const { 38937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOTPLT; 3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 39337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef X86_32GNULDBackend::createCIERegionForPLT() { 39437b74a387bb3993387029859c2d9d051c41c724eStephen Hines static const uint8_t data[4 + 4 + 16] = { 39537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x14, 0, 0, 0, // length 39637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // ID 39737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1, // version 39837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 'z', 'R', '\0', // augmentation string 39937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1, // code alignment factor 40037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x7c, // data alignment factor 40137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 8, // return address column 40237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1, // augmentation data size 40337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_EH_PE_pcrel 40437b74a387bb3993387029859c2d9d051c41c724eStephen Hines | llvm::dwarf::DW_EH_PE_sdata4, // FDE encoding 40537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa, 4, 4, 40637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_offset + 8, 1, 40737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 40837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop 40987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 41037b74a387bb3993387029859c2d9d051c41c724eStephen Hines return llvm::StringRef((const char*)data, 4 + 4 + 16); 41137b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 41237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 41337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef X86_32GNULDBackend::createFDERegionForPLT() { 41437b74a387bb3993387029859c2d9d051c41c724eStephen Hines static const uint8_t data[4 + 4 + 32] = { 41537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x24, 0, 0, 0, // length 41637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // offset to CIE 41737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // offset to PLT 41837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // size of PLT 41937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, // augmentation data size 42037b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa_offset, 8, 42137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_advance_loc + 6, 42237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa_offset, 12, 42337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_advance_loc + 10, 42437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa_expression, 42537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 11, 42637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_breg4, 4, 42737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_breg8, 0, 42837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_lit15, 42937b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_and, 43037b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_lit11, 43137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_ge, 43237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_lit2, 43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_shl, 43437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_plus, 43537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 43637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 43737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 43837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop 43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 44037b74a387bb3993387029859c2d9d051c41c724eStephen Hines return llvm::StringRef((const char*)data, 4 + 4 + 32); 44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 44337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86_32GNULDBackend::setRelDynSize() { 4446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 44537b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelDyn().setSize(m_pRelDyn->numOfRelocs() * 44637b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelEntrySize()); 4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 44937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86_32GNULDBackend::setRelPLTSize() { 4506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 45137b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelPlt().setSize(m_pRelPLT->numOfRelocs() * 45237b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelEntrySize()); 4536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 45537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) { 4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt size 45737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == config().codeGenType() || m_pGOTPLT->hasGOT1() || 45837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol != NULL) { 4596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->finalizeSectionSize(); 4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got size 4646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pGOT->empty()) 4656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT->finalizeSectionSize(); 4666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 46837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const { 4696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_32GOTEntry* got = 0; 4746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_32GOTEntry::EntrySize; 4756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 47737b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (X86_32GOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie; 47837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++buffer) { 4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_32GOTEntry>((*it))); 4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 4816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 48737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t X86_32GNULDBackend::emitGOTPLTSectionData( 48837b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion, 48937b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFFileFormat* FileFormat) const { 4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 49487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_32GOTEntry* got = 0; 4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_32GOTEntry::EntrySize; 4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 50037b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end(); 50137b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 50237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++buffer) { 5036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_32GOTEntry>((*it))); 5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 5096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig, 512551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo) 51337b74a387bb3993387029859c2d9d051c41c724eStephen Hines : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY), 51437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOT(NULL), 51537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTPLT(NULL) { 5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 51837b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86_64GNULDBackend::~X86_64GNULDBackend() { 5196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOT; 5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOTPLT; 5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 52337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool X86_64GNULDBackend::initRelocator() { 52437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pRelocator == NULL) { 525f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new X86_64Relocator(*this, config()); 526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53037b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86_64GOT& X86_64GNULDBackend::getGOT() { 53137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 53537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst X86_64GOT& X86_64GNULDBackend::getGOT() const { 53637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 54037b74a387bb3993387029859c2d9d051c41c724eStephen HinesX86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() { 54137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 54537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const { 54637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 55037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef X86_64GNULDBackend::createCIERegionForPLT() { 55137b74a387bb3993387029859c2d9d051c41c724eStephen Hines static const uint8_t data[4 + 4 + 16] = { 55237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x14, 0, 0, 0, // length 55337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // ID 55437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1, // CIE version 55537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 'z', 'R', '\0', // augmentation string 55637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1, // code alignment factor 55737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x78, // data alignment factor 55837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 16, // return address column 55937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1, // augmentation data size 56037b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_EH_PE_pcrel 56137b74a387bb3993387029859c2d9d051c41c724eStephen Hines | llvm::dwarf::DW_EH_PE_sdata4, // FDE encoding 56237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa, 7, 8, 56337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_offset + 16, 1, 56437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 56537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop 56687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 56737b74a387bb3993387029859c2d9d051c41c724eStephen Hines return llvm::StringRef((const char*)data, 4 + 4 + 16); 56837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 56937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 57037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef X86_64GNULDBackend::createFDERegionForPLT() { 57137b74a387bb3993387029859c2d9d051c41c724eStephen Hines static const uint8_t data[4 + 4 + 32] = { 57237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x24, 0, 0, 0, // length 57337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // ID 57437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // offset to PLT 57537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, 0, 0, 0, // size of PLT 57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0, // augmentation data size 57737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa_offset, 16, 57837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_advance_loc + 6, 57937b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa_offset, 24, 58037b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_advance_loc + 10, 58137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_def_cfa_expression, 58237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 11, 58337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_breg7, 8, 58437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_breg16, 0, 58537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_lit15, 58637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_and, 58737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_lit11, 58837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_ge, 58937b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_lit3, 59037b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_shl, 59137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_OP_plus, 59237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 59337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 59437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop, 59537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::dwarf::DW_CFA_nop 59687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 59737b74a387bb3993387029859c2d9d051c41c724eStephen Hines return llvm::StringRef((const char*)data, 4 + 4 + 32); 59887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 59987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 60037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86_64GNULDBackend::setRelDynSize() { 6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 60237b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelaDyn().setSize(m_pRelDyn->numOfRelocs() * 60337b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelaEntrySize()); 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 60637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86_64GNULDBackend::setRelPLTSize() { 6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 60837b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelaPlt().setSize(m_pRelPLT->numOfRelocs() * 60937b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelaEntrySize()); 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::initTargetSections(Module& pModule, 61337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 61422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 61522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 61622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got 61722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = file_format->getGOT(); 6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new X86_64GOT(got); 61922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 62022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got.plt 62122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& gotplt = file_format->getGOTPLT(); 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT = new X86_64GOTPLT(gotplt); 62322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 62422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .plt 62522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& plt = file_format->getPLT(); 62687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines plt.setAlign(16u); 627551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT = new X86_64PLT(plt, *m_pGOTPLT, config()); 62822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rela.plt 6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& relplt = file_format->getRelaPlt(); 63122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relplt.setLink(&plt); 632d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelPLT = new OutputRelocSection(pModule, relplt); 633d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rela.dyn 6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& reldyn = file_format->getRelaDyn(); 636d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn = new OutputRelocSection(pModule, reldyn); 63722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 64037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) { 6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt size 64237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == config().codeGenType() || m_pGOTPLT->hasGOT1() || 64337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol != NULL) { 6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->finalizeSectionSize(); 6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 64622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got size 6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pGOT->empty()) 6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT->finalizeSectionSize(); 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 65337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const { 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 65687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_64GOTEntry* got = 0; 6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_64GOTEntry::EntrySize; 6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 66237b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (X86_64GOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie; 66337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++buffer) { 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_64GOTEntry>((*it))); 6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 6666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 6676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 67237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t X86_64GNULDBackend::emitGOTPLTSectionData( 67337b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion, 67437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFFileFormat* FileFormat) const { 6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 6766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 6776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 6786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 67987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 6806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_64GOTEntry* got = 0; 6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_64GOTEntry::EntrySize; 6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 6846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 68537b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end(); 68637b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 68737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++buffer) { 6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_64GOTEntry>((*it))); 6896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 6906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 6916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 69937b74a387bb3993387029859c2d9d051c41c724eStephen HinesTargetLDBackend* createX86LDBackend(const LinkerConfig& pConfig) { 700d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSDarwin()) { 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86MachOLDBackend(createX86MachOArchiveReader, 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectReader, 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectWriter); 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 708d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSWindows()) { 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86COFFLDBackend(createX86COFFArchiveReader, 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectReader, 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectWriter); 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 71687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::Triple::ArchType arch = pConfig.targets().triple().getArch(); 71787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (arch == llvm::Triple::x86) 71837b74a387bb3993387029859c2d9d051c41c724eStephen Hines return new X86_32GNULDBackend( 71937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pConfig, new X86_32GNUInfo(pConfig.targets().triple())); 72037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(arch == llvm::Triple::x86_64); 7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new X86_64GNULDBackend(pConfig, 722551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines new X86_64GNUInfo(pConfig.targets().triple())); 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 72537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() { 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 73237b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheX86_32Target, 73337b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createX86LDBackend); 73437b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheX86_64Target, 73537b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createX86LDBackend); 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 737