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 75a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesconst Relocator* X86GNULDBackend::getRelocator() const 76a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines{ 77a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines assert(NULL != m_pRelocator); 78a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines return m_pRelocator; 79a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines} 80a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 81d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* X86GNULDBackend::getRelocator() 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 83d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao assert(NULL != m_pRelocator); 84d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doPreLayout(IRBuilder& pBuilder) 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeStatic() && NULL == m_pDynamic) 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new X86ELFDynamic(*this, config()); 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt and .got sizes 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // when building shared object, the .got section is must 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setGOTSectionSize(pBuilder); 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .plt size 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pPLT->hasPLT1()) 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT->finalizeSectionSize(); 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .rel.dyn/.rela.dyn size 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelDyn->empty()) { 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(!config().isCodeStatic() && 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "static linkage should not result in a dynamic relocation section"); 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setRelDynSize(); 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .rel.plt/.rela.plt size 1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelPLT->empty()) { 1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(!config().isCodeStatic() && 1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "static linkage should not result in a dynamic relocation section"); 1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setRelPLTSize(); 1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().options().genUnwindInfo()) 11787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines addEhFrameForPLT(pBuilder.getModule()); 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPostLayout(Module& pModule, 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder& pBuilder) 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic() 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 141551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesvoid X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ 144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Create(pFrag, 0x0), 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Create(pFrag, 0x0), 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion& pRegion) const 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pRegion.size() && "Size of MemoryRegion is zero!"); 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* FileFormat = getOutputFormat(); 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(FileFormat && 1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = 0; 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 18087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) { 18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned char* buffer = pRegion.begin(); 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT->applyPLT0(); 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT->applyPLT1(); 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86PLT::iterator it = m_pPLT->begin(); 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); 1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); 1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += plt0_size; 1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++it; 1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines PLTEntryBase* plt1 = 0; 1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86PLT::iterator ie = m_pPLT->end(); 1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines while (it != ie) { 1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines plt1 = &(llvm::cast<PLTEntryBase>(*it)); 1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines EntrySize = plt1->size(); 1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); 1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++it; 2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) { 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += emitGOTSectionData(pRegion); 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (FileFormat->hasGOTPLT() && 20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (&pSection == &(FileFormat->getGOTPLT()))) { 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::unrecognized_output_sectoin) 2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << pSection.name() 2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << "mclinker@googlegroups.com"; 2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86PLT& X86GNULDBackend::getPLT() 2186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pPLT && "PLT section not exist"); 2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86PLT& X86GNULDBackend::getPLT() const 2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pPLT && "PLT section not exist"); 2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelDyn() 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 Hinesconst OutputRelocSection& X86GNULDBackend::getRelDyn() const 2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pRelDyn && ".rel.dyn/.rela.dyn section not exist"); 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelDyn; 2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesOutputRelocSection& X86GNULDBackend::getRelPLT() 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 Hinesconst OutputRelocSection& X86GNULDBackend::getRelPLT() const 2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pRelPLT && ".rel.plt/.rela.plt section not exist"); 2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pRelPLT; 2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned int 2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* file_format = getOutputFormat(); 2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 25887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().options().hasNow()) 2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO; 2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO_LAST; 2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) { 2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (config().options().hasNow()) 2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_RELRO; 2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_NON_RELRO_FIRST; 2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 27087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_PLT; 2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_UNDEFINED; 2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 2796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // same name in input 2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = 2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "_GLOBAL_OFFSET_TABLE_", 2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Object, 2856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Define, 2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Local, 2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // size 2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0x0, // value 2896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines FragmentRef::Null(), // FragRef 2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Hidden); 2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid X86GNULDBackend::addEhFrameForPLT(Module& pModule) 29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* plt_sect = pModule.getSection(".plt"); 29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!plt_sect || plt_sect->size() == 0u) 29887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* eh_sect = pModule.getSection(".eh_frame"); 30187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!eh_sect || !eh_sect->hasEhFrame()) 30287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 30387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 30487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame* eh_frame = eh_sect->getEhFrame(); 30587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::FragmentListType& frag_list = 30687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->getSectionData()->getFragmentList(); 30787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef cie_region = createCIERegionForPLT(); 30887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef fde_region = createFDERegionForPLT(); 30987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::CIE* cie = new EhFrame::GeneratedCIE(cie_region); 31087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::FDE* fde = new EhFrame::GeneratedFDE(fde_region, *cie); 31187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Augmentation data only contains FDE encoding. 31287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint8_t aug_data = (uint8_t)(llvm::dwarf::DW_EH_PE_pcrel | 31387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::dwarf::DW_EH_PE_sdata4); 31487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->setFDEEncode(aug_data); 31587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->setAugmentationData(std::string(1, aug_data)); 31687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 31787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::cie_iterator i = eh_frame->cie_begin(); 31887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (EhFrame::cie_iterator e = eh_frame->cie_end(); i != e; ++i) { 31987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::CIE& exist_cie = **i; 32087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (exist_cie == *cie) { 32187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Insert the FDE fragment 32287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::iterator cur_iter(exist_cie); 32387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag_list.insertAfter(cur_iter, fde); 32487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines fde->setCIE(exist_cie); 32587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Cleanup the CIE we created 32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines cie->clearFDEs(); 32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete cie; 32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (i == eh_frame->cie_end()) { 33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Newly insert 33487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->addCIE(*cie); 33587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines eh_frame->addFDE(*fde); 33687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 33787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 33887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value 3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86GNULDBackend::finalizeTargetSymbols() 3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the 3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments 3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule) 3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO 3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig, 353551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo) 3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY), 3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT (NULL), 3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT (NULL) { 3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GNULDBackend::~X86_32GNULDBackend() 3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOT; 3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOTPLT; 3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_32GNULDBackend::initRelocator() 3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == m_pRelocator) { 368f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new X86_32Relocator(*this, config()); 3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::initTargetSections(Module& pModule, 374551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder& pBuilder) 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got 3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& got = file_format->getGOT(); 3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new X86_32GOT(got); 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got.plt 3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& gotplt = file_format->getGOTPLT(); 3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT = new X86_32GOTPLT(gotplt); 385affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .plt 3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& plt = file_format->getPLT(); 38887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines plt.setAlign(16u); 389551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT = new X86_32PLT(plt, *m_pGOTPLT, config()); 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rel.plt 3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& relplt = file_format->getRelPlt(); 3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relplt.setLink(&plt); 3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pRelPLT = new OutputRelocSection(pModule, relplt); 3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rel.dyn 3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& reldyn = file_format->getRelDyn(); 3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pRelDyn = new OutputRelocSection(pModule, reldyn); 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOT& X86_32GNULDBackend::getGOT() 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOT); 4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOT& X86_32GNULDBackend::getGOT() const 4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOT); 4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() 4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOTPLT); 4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOTPLT; 4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_32GOTPLT& X86_32GNULDBackend::getGOTPLT() const 4226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOTPLT); 4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOTPLT; 4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_32GNULDBackend::createCIERegionForPLT() 42887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 42987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 43087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+16] = { 43187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x14, 0, 0, 0, // length 43287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // ID 43387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // version 43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 'z', 'R', '\0', // augmentation string 43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // code alignment factor 43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x7c, // data alignment factor 43787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8, // return address column 43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // augmentation data size 43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_EH_PE_pcrel | DW_EH_PE_sdata4, // FDE encoding 44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa, 4, 4, 44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_offset + 8, 1, 44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 44387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 44487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+16); 44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 44787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_32GNULDBackend::createFDERegionForPLT() 44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+32] = { 45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x24, 0, 0, 0, // length 45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // offset to CIE 45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // offset to PLT 45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // size of PLT 45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, // augmentation data size 45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 8, 45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 6, 45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 12, 46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 10, 46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_expression, 46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11, 46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg4, 4, 46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg8, 0, 46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit15, 46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_and, 46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit11, 46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_ge, 46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit2, 47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_shl, 47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_plus, 47287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 47387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 47487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 47587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 47687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 47787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+32); 47887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 47987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelDynSize() 4816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 4836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelDyn().setSize 4846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelDyn->numOfRelocs() * getRelEntrySize()); 4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setRelPLTSize() 4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelPlt().setSize 4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelPLT->numOfRelocs() * getRelEntrySize()); 4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_32GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) 4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt size 4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::DynObj == config().codeGenType() || 4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->hasGOT1() || 4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines NULL != m_pGOTSymbol) { 5006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->finalizeSectionSize(); 5016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got size 5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pGOT->empty()) 5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT->finalizeSectionSize(); 5076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 51387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_32GOTEntry* got = 0; 5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_32GOTEntry::EntrySize; 5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_32GOT::iterator it = m_pGOT->begin(), 5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_32GOTEntry>((*it))); 5226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 5236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 5276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 530551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const ELFFileFormat* FileFormat) const 5316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 5336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 5346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 53687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_32GOTEntry* got = 0; 5396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_32GOTEntry::EntrySize; 5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_32GOTPLT::iterator it = m_pGOTPLT->begin(), 5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_32GOTEntry>((*it))); 5456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 5466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 5476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig, 553551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines GNUInfo* pInfo) 5546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY), 5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT (NULL), 5566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT (NULL) { 5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GNULDBackend::~X86_64GNULDBackend() 5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOT; 5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOTPLT; 5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool X86_64GNULDBackend::initRelocator() 5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == m_pRelocator) { 568f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new X86_64Relocator(*this, config()); 569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOT& X86_64GNULDBackend::getGOT() 5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOT& X86_64GNULDBackend::getGOT() const 5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesX86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst X86_64GOTPLT& X86_64GNULDBackend::getGOTPLT() const 592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 59787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_64GNULDBackend::createCIERegionForPLT() 59887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 59987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 60087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+16] = { 60187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x14, 0, 0, 0, // length 60287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // ID 60387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // CIE version 60487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 'z', 'R', '\0', // augmentation string 60587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // code alignment factor 60687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x78, // data alignment factor 60787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 16, // return address column 60887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1, // augmentation data size 60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_EH_PE_pcrel | DW_EH_PE_sdata4, // FDE encoding 61087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa, 7, 8, 61187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_offset + 16, 1, 61287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 61387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 61487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+16); 61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 61787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesllvm::StringRef X86_64GNULDBackend::createFDERegionForPLT() 61987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 62087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines using namespace llvm::dwarf; 62187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines static const uint8_t data[4+4+32] = { 62287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x24, 0, 0, 0, // length 62387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // ID 62487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // offset to PLT 62587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, 0, 0, 0, // size of PLT 62687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0, // augmentation data size 62787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 16, 62887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 6, 62987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_offset, 24, 63087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_advance_loc + 10, 63187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_def_cfa_expression, 63287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11, 63387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg7, 8, 63487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_breg16, 0, 63587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit15, 63687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_and, 63787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit11, 63887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_ge, 63987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_lit3, 64087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_shl, 64187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_OP_plus, 64287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 64387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 64487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop, 64587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines DW_CFA_nop 64687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 64787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return llvm::StringRef((const char*)data, 4+4+32); 64887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 64987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelDynSize() 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelaDyn().setSize 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelDyn->numOfRelocs() * getRelaEntrySize()); 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setRelPLTSize() 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines file_format->getRelaPlt().setSize 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (m_pRelPLT->numOfRelocs() * getRelaEntrySize()); 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::initTargetSections(Module& pModule, 665551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder& pBuilder) 66622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 66722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 66822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 66922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got 67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = file_format->getGOT(); 6716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new X86_64GOT(got); 67222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 67322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got.plt 67422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& gotplt = file_format->getGOTPLT(); 6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT = new X86_64GOTPLT(gotplt); 67622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 67722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .plt 67822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& plt = file_format->getPLT(); 67987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines plt.setAlign(16u); 680551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines m_pPLT = new X86_64PLT(plt, *m_pGOTPLT, config()); 68122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rela.plt 6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& relplt = file_format->getRelaPlt(); 68422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relplt.setLink(&plt); 685d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelPLT = new OutputRelocSection(pModule, relplt); 686d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 6876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .rela.dyn 6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& reldyn = file_format->getRelaDyn(); 689d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn = new OutputRelocSection(pModule, reldyn); 690d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 69122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid X86_64GNULDBackend::setGOTSectionSize(IRBuilder& pBuilder) 69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got.plt size 6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::DynObj == config().codeGenType() || 6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->hasGOT1() || 6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines NULL != m_pGOTSymbol) { 7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->finalizeSectionSize(); 7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 70222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set .got size 7056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pGOT->empty()) 7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT->finalizeSectionSize(); 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 7126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 71387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 7146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_64GOTEntry* got = 0; 7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_64GOTEntry::EntrySize; 7176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 7186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_64GOT::iterator it = m_pGOT->begin(), 7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_64GOTEntry>((*it))); 7226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 7236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 7246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 729551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesuint64_t 730551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen HinesX86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 731551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const ELFFileFormat* FileFormat) const 732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 73787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines X86_64GOTEntry* got = 0; 7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int EntrySize = X86_64GOTEntry::EntrySize; 7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t RegionSize = 0; 7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(), 7446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines got = &(llvm::cast<X86_64GOTEntry>((*it))); 7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines RegionSize += EntrySize; 7486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return RegionSize; 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 75887f34658dec9097d987d254a990ea7f311bfc95fStephen HinesTargetLDBackend* createX86LDBackend(const LinkerConfig& pConfig) 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 760d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSDarwin()) { 7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86MachOLDBackend(createX86MachOArchiveReader, 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectReader, 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectWriter); 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 768d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSWindows()) { 7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86COFFLDBackend(createX86COFFArchiveReader, 7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectReader, 7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectWriter); 7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 77687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::Triple::ArchType arch = pConfig.targets().triple().getArch(); 77787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (arch == llvm::Triple::x86) 7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new X86_32GNULDBackend(pConfig, 779551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines new X86_32GNUInfo(pConfig.targets().triple())); 78087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert (arch == llvm::Triple::x86_64); 7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new X86_64GNULDBackend(pConfig, 782551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines new X86_64GNUInfo(pConfig.targets().triple())); 7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 79022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() { 7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_32Target, createX86LDBackend); 7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(TheX86_64Target, createX86LDBackend); 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 795