X86LDBackend.cpp revision 551ae4ebd3e9d137ea668fb83ae4a55b8cfba451
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 1587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/StringRef.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFFileFormat.h> 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h> 24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h> 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Dwarf.h> 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace 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) 39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : GNULDBackend(pConfig, pInfo), 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelocator(NULL), 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT(NULL), 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT(NULL), 4467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao m_pDynamic(NULL), 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol(NULL), 466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_CopyRel(pCopyRel) 476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::Triple::ArchType arch = pConfig.targets().triple().getArch(); 4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64); 5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (arch == llvm::Triple::x86 || 5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pConfig.targets().triple().getEnvironment() == llvm::Triple::GNUX32) { 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelEntrySize = 8; 536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelaEntrySize = 12; 5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (arch == llvm::Triple::x86) 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_PointerRel = llvm::ELF::R_386_32; 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_PointerRel = llvm::ELF::R_X86_64_32; 586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelEntrySize = 16; 616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_RelaEntrySize = 24; 626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_PointerRel = llvm::ELF::R_X86_64_64; 636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend() 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 68d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pRelocator; 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pPLT; 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelPLT; 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 75d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* X86GNULDBackend::getRelocator() 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 77d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao assert(NULL != m_pRelocator); 78d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doPreLayout(IRBuilder& pBuilder) 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeStatic() && NULL == m_pDynamic) 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()) { 986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(!config().isCodeStatic() && 996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "static linkage should not result in a dynamic relocation section"); 1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setRelDynSize(); 1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .rel.plt/.rela.plt size 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelPLT->empty()) { 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(!config().isCodeStatic() && 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "static linkage should not result in a dynamic relocation section"); 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setRelPLTSize(); 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 10987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().genUnwindInfo()) 11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addEhFrameForPLT(pBuilder.getModule()); 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPostLayout(Module& pModule, 1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder& pBuilder) 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 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. 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic() 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 135551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesvoid X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Create(pFrag, 0x0), 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Create(pFrag, 0x0), 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, 1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion& pRegion) const 1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pRegion.size() && "Size of MemoryRegion is zero!"); 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* FileFormat = getOutputFormat(); 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(FileFormat && 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = 0; 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 17487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) { 17587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned char* buffer = pRegion.begin(); 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT->applyPLT0(); 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT->applyPLT1(); 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86PLT::iterator it = m_pPLT->begin(); 1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); 1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += plt0_size; 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++it; 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines PLTEntryBase* plt1 = 0; 1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86PLT::iterator ie = m_pPLT->end(); 1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines while (it != ie) { 1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines plt1 = &(llvm::cast<PLTEntryBase>(*it)); 1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines EntrySize = plt1->size(); 1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); 1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++it; 1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 19687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) { 1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += emitGOTSectionData(pRegion); 1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (FileFormat->hasGOTPLT() && 20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (&pSection == &(FileFormat->getGOTPLT()))) { 2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); 2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::unrecognized_output_sectoin) 2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << pSection.name() 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << "mclinker@googlegroups.com"; 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86PLT& X86GNULDBackend::getPLT() 2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pPLT && "PLT section not exist"); 2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86PLT& X86GNULDBackend::getPLT() const 2186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pPLT && "PLT section not exist"); 2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelDyn() 2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist"); 2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelDyn; 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelDyn() const 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist"); 2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelDyn; 2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelPLT() 2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist"); 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelPLT; 2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst OutputRelocSection& X86GNULDBackend::getRelPLT() const 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist"); 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelPLT; 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned int 2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* file_format = getOutputFormat(); 2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 25287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().options().hasNow()) 2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO; 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO_LAST; 2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 25887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) { 2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().options().hasNow()) 2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO; 2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_NON_RELRO_FIRST; 2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_PLT; 2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_UNDEFINED; 2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // same name in input 2756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = 2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_GLOBAL_OFFSET_TABLE_", 2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Object, 2796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Define, 2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Local, 2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // size 2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // value 2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Null(), // FragRef 2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Hidden); 2856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 28887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid X86GNULDBackend::addEhFrameForPLT(Module& pModule) 28987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 29087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* plt_sect = pModule.getSection(".plt"); 29187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!plt_sect || plt_sect->size() == 0u) 29287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 29387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* eh_sect = pModule.getSection(".eh_frame"); 29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!eh_sect || !eh_sect->hasEhFrame()) 29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 29887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame* eh_frame = eh_sect->getEhFrame(); 29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::FragmentListType& frag_list = 30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->getSectionData()->getFragmentList(); 30187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef cie_region = createCIERegionForPLT(); 30287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef fde_region = createFDERegionForPLT(); 30387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::CIE* cie = new EhFrame::GeneratedCIE(cie_region); 30487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::FDE* fde = new EhFrame::GeneratedFDE(fde_region, *cie); 30587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Augmentation data only contains FDE encoding. 30687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint8_t aug_data = (uint8_t)(llvm::dwarf::DW_EH_PE_pcrel | 30787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::dwarf::DW_EH_PE_sdata4); 30887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->setFDEEncode(aug_data); 30987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->setAugmentationData(std::string(1, aug_data)); 31087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 31187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::cie_iterator i = eh_frame->cie_begin(); 31287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (EhFrame::cie_iterator e = eh_frame->cie_end(); i != e; ++i) { 31387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::CIE& exist_cie = **i; 31487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (exist_cie == *cie) { 31587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Insert the FDE fragment 31687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::iterator cur_iter(exist_cie); 31787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag_list.insertAfter(cur_iter, fde); 31887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines fde->setCIE(exist_cie); 31987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 32087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Cleanup the CIE we created 32187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->clearFDEs(); 32287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete cie; 32387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 32487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 32587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (i == eh_frame->cie_end()) { 32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Newly insert 32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->addCIE(*cie); 32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->addFDE(*fde); 33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 3336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value 3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86GNULDBackend::finalizeTargetSymbols() 3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the 3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments 3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule) 3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO 3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig, 347551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo) 3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY), 3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT (NULL), 3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT (NULL) { 3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::~X86_32GNULDBackend() 3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOT; 3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOTPLT; 3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_32GNULDBackend::initRelocator() 3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == m_pRelocator) { 362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new X86_32Relocator(*this, config()); 3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::initTargetSections(Module& pModule, 368551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder& pBuilder) 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got 3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& got = file_format->getGOT(); 3746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new X86_32GOT(got); 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got.plt 3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& gotplt = file_format->getGOTPLT(); 3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT = new X86_32GOTPLT(gotplt); 379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .plt 3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& plt = file_format->getPLT(); 38287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines plt.setAlign(16u); 383551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT = new X86_32PLT(plt, *m_pGOTPLT, config()); 38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rel.plt 3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& relplt = file_format->getRelPlt(); 3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relplt.setLink(&plt); 3886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pRelPLT = new OutputRelocSection(pModule, relplt); 3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rel.dyn 3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& reldyn = file_format->getRelDyn(); 3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pRelDyn = new OutputRelocSection(pModule, reldyn); 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOT& X86_32GNULDBackend::getGOT() 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOT); 4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 4016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOT& X86_32GNULDBackend::getGOT() const 4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOT); 4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() 4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOTPLT); 4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOTPLT; 4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const 4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOTPLT); 4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOTPLT; 4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 42187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_32GNULDBackend::createCIERegionForPLT() 42287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 42387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 42487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+16] = { 42587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x14, 0, 0, 0, // length 42687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // ID 42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // version 42887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 'z', 'R', '\0', // augmentation string 42987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // code alignment factor 43087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x7c, // data alignment factor 43187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8, // return address column 43287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // augmentation data size 43387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_EH_PE_pcrel | DW_EH_PE_sdata4, // FDE encoding 43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa, 4, 4, 43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_offset + 8, 1, 43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 43787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+16); 44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_32GNULDBackend::createFDERegionForPLT() 44387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 44487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+32] = { 44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x24, 0, 0, 0, // length 44787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // offset to CIE 44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // offset to PLT 44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // size of PLT 45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, // augmentation data size 45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 8, 45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 6, 45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 12, 45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 10, 45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_expression, 45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11, 45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg4, 4, 45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg8, 0, 45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit15, 46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_and, 46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit11, 46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_ge, 46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit2, 46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_shl, 46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_plus, 46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+32); 47287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 47387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelDynSize() 4756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 4776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelDyn().setSize 4786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelDyn->numOfRelocs() * getRelEntrySize()); 4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelPLTSize() 4826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 4846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelPlt().setSize 4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelPLT->numOfRelocs() * getRelEntrySize()); 4866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) 4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt size 4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::DynObj == config().codeGenType() || 4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->hasGOT1() || 4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines NULL != m_pGOTSymbol) { 4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->finalizeSectionSize(); 4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got size 4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pGOT->empty()) 5006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT->finalizeSectionSize(); 5016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 50787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_32GOTEntry* got = 0; 5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_32GOTEntry::EntrySize; 5116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 5126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_32GOT::iterator it = m_pGOT->begin(), 5146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_32GOTEntry>((*it))); 5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 524551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const ELFFileFormat* FileFormat) const 5256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 5276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 5286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 53087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_32GOTEntry* got = 0; 5336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_32GOTEntry::EntrySize; 5346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 5356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(), 5376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 5386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_32GOTEntry>((*it))); 5396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig, 547551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo) 5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY), 5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT (NULL), 5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT (NULL) { 5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::~X86_64GNULDBackend() 5546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOT; 5566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOTPLT; 5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_64GNULDBackend::initRelocator() 5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == m_pRelocator) { 562f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new X86_64Relocator(*this, config()); 563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOT& X86_64GNULDBackend::getGOT() 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOT& X86_64GNULDBackend::getGOT() const 5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 59187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_64GNULDBackend::createCIERegionForPLT() 59287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 59387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 59487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+16] = { 59587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x14, 0, 0, 0, // length 59687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // ID 59787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // CIE version 59887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 'z', 'R', '\0', // augmentation string 59987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // code alignment factor 60087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x78, // data alignment factor 60187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 16, // return address column 60287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // augmentation data size 60387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_EH_PE_pcrel | DW_EH_PE_sdata4, // FDE encoding 60487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa, 7, 8, 60587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_offset + 16, 1, 60687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 60787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 60887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+16); 61087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 61187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 61287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_64GNULDBackend::createFDERegionForPLT() 61387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 61487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+32] = { 61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x24, 0, 0, 0, // length 61787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // ID 61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // offset to PLT 61987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // size of PLT 62087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, // augmentation data size 62187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 16, 62287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 6, 62387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 24, 62487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 10, 62587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_expression, 62687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11, 62787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg7, 8, 62887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg16, 0, 62987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit15, 63087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_and, 63187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit11, 63287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_ge, 63387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit3, 63487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_shl, 63587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_plus, 63687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 63787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 63887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 63987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 64087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 64187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+32); 64287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 64387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelDynSize() 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelaDyn().setSize 6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelDyn->numOfRelocs() * getRelaEntrySize()); 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelPLTSize() 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelaPlt().setSize 6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelPLT->numOfRelocs() * getRelaEntrySize()); 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::initTargetSections(Module& pModule, 659551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder& pBuilder) 66022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 66122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 66222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 66322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got 66422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = file_format->getGOT(); 6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new X86_64GOT(got); 66622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 66722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got.plt 66822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& gotplt = file_format->getGOTPLT(); 6696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT = new X86_64GOTPLT(gotplt); 67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 67122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .plt 67222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& plt = file_format->getPLT(); 67387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines plt.setAlign(16u); 674551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT = new X86_64PLT(plt, *m_pGOTPLT, config()); 67522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rela.plt 6776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& relplt = file_format->getRelaPlt(); 67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relplt.setLink(&plt); 679d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelPLT = new OutputRelocSection(pModule, relplt); 680d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rela.dyn 6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& reldyn = file_format->getRelaDyn(); 683d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn = new OutputRelocSection(pModule, reldyn); 684d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 68522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) 68922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 6906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt size 6916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::DynObj == config().codeGenType() || 6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->hasGOT1() || 6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines NULL != m_pGOTSymbol) { 6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->finalizeSectionSize(); 6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 69622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got size 6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pGOT->empty()) 7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT->finalizeSectionSize(); 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 70787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 7086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_64GOTEntry* got = 0; 7106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_64GOTEntry::EntrySize; 7116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 7126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_64GOT::iterator it = m_pGOT->begin(), 7146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_64GOTEntry>((*it))); 7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 7176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 7186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 723551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesuint64_t 724551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen HinesX86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 725551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const ELFFileFormat* FileFormat) const 726affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 7296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 7306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 73187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_64GOTEntry* got = 0; 7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_64GOTEntry::EntrySize; 7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(), 7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_64GOTEntry>((*it))); 7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 75287f34658dec9097d987d254a990ea7f311bfc95fStephen HinesTargetLDBackend* createX86LDBackend(const LinkerConfig& pConfig) 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 754d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSDarwin()) { 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86MachOLDBackend(createX86MachOArchiveReader, 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectReader, 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectWriter); 7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 762d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSWindows()) { 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86COFFLDBackend(createX86COFFArchiveReader, 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectReader, 7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectWriter); 7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 77087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::Triple::ArchType arch = pConfig.targets().triple().getArch(); 77187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (arch == llvm::Triple::x86) 7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new X86_32GNULDBackend(pConfig, 773551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines new X86_32GNUInfo(pConfig.targets().triple())); 77487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert (arch == llvm::Triple::x86_64); 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new X86_64GNULDBackend(pConfig, 776551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines new X86_64GNUInfo(pConfig.targets().triple())); 7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 78122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 78322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 78422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() { 7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend); 7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend); 7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 789