X86LDBackend.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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" 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86RelocationFactory.h" 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h> 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h> 22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h> 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// X86GNULDBackend 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoX86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig) 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : GNULDBackend(pConfig), 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelocFactory(NULL), 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT(NULL), 39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT(NULL), 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT(NULL), 4267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao m_pDynamic(NULL), 4367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao m_pGOTSymbol(NULL) { 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend() 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelocFactory; 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pGOT; 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pPLT; 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pGOTPLT; 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelPLT; 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* X86GNULDBackend::getRelocFactory() 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelocFactory); 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pRelocFactory; 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const FragmentLinker& pLinker) 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelocFactory) { 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory = new X86RelocationFactory(1024, *this); 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelocFactory->setFragmentLinker(pLinker); 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPreLayout(FragmentLinker& pLinker) 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .got.plt size 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // when building shared object, the .got section is must 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTPLT->hasGOT1() || 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao NULL != m_pGOTSymbol) { 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTPLT->finalizeSectionSize(); 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao defineGOTSymbol(pLinker); 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .got size 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pGOT->empty()) 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->finalizeSectionSize(); 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .plt size 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pPLT->hasPLT1()) 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT->finalizeSectionSize(); 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.dyn size 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pRelDyn->empty()) 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->finalizeSectionSize(); 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.plt size 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pRelPLT->empty()) 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelPLT->finalizeSectionSize(); 99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doPostLayout(Module& pModule, 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker) 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic() 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic = new X86ELFDynamic(*this); 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::defineGOTSymbol(FragmentLinker& pLinker) 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ 128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Unresolve>( 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>( 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 154affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::addCopyReloc(ResolveInfo& pSym) 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation& rel_entry = *m_pRelDyn->consumeEntry(); 157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.setType(llvm::ELF::R_386_COPY); 158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pSym.outSymbol()->hasFragRef()); 159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); 160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.setSymInfo(&pSym); 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// defineSymbolforCopyReloc 16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// For a symbol needing copy relocation, define a copy symbol in the BSS 16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// section and all other reference to this symbol should refer to this 16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// copy. 16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @note This is executed at `scan relocation' stage. 16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(FragmentLinker& pLinker, 169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ResolveInfo& pSym) 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 171affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // get or create corresponding BSS LDSection 172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* bss_sect_hdr = NULL; 17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::ThreadLocal == pSym.type()) 17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_hdr = &file_format->getTBSS(); 17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_hdr = &file_format->getBSS(); 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != bss_sect_hdr); 18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_section = NULL; 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect_hdr->hasSectionData()) 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_section = bss_sect_hdr->getSectionData(); 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_section = IRBuilder::CreateSectionData(*bss_sect_hdr); 186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Determine the alignment by the symbol value 188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: here we use the largest alignment 189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t addralign = bitclass() / 8; 190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate space in BSS for the copy symbol 192cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, pSym.size()); 19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t size = ObjectBuilder::AppendFragment(*frag, 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_section, 19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao addralign); 196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_hdr->setSize(bss_sect_hdr->size() + size); 197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // change symbol binding to Global if it's a weak symbol 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); 200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (binding == ResolveInfo::Weak) 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang binding = ResolveInfo::Global; 202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Define the copy symbol in the bss section and resolve it 20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* cpy_sym = 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>( 206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.name(), 207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (ResolveInfo::Type)pSym.type(), 209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang binding, 211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.size(), // size 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*frag, 0x0), 214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (ResolveInfo::Visibility)pSym.other()); 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *cpy_sym; 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc, 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker, 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule, 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& pSection) 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()){ 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_16: 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_8: 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If buiding PIC object (shared library or PIC executable), 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // a dynamic relocations with RELATIVE type to this location is needed. 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Reserve an entry in .rel.dyn 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pLinker.isOutputPIC()) { 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set Rel bit 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: A GOT section is needed 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_GOT32: 24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Symbol needs GOT entry, reserve entry in .got 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // return if we already create GOT for this symbol 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->reserved() & (ReserveGOT | GOTRel)) 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check STT_GNU_IFUNC symbol 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(); 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If building shared object or the symbol is undefined, a dynamic 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // relocation is needed to relocate this GOT entry. Reserve an 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // entry in .rel.dyn 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOTRel bit 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOT bit 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGOT); 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_PC16: 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_PC8: 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_GD: { 27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: no linker optimization for TLS relocation 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->reserved() & GOTRel) 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(2); 27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reserve an rel entry 27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOTRel bit 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define the section symbol for .tdata or .tbss 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the target symbol of the created dynamic relocation should be the 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // section symbol of the section which this symbol defined. so we 28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // need to define that section symbol here 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* sym_sect = 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &rsym->outSymbol()->fragRef()->frag()->getParent()->getSection(); 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (&file_format->getTData() == sym_sect) { 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == f_pTDATA) 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTDATA = pModule.getSectionSymbolSet().get(*sym_sect); 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (&file_format->getTBSS() == sym_sect || rsym->isCommon()) { 29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == f_pTBSS) 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao f_pTBSS = pModule.getSectionSymbolSet().get(*sym_sect); 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao error(diag::invalid_tls) << rsym->name() << sym_sect->name(); 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LDM: 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getTLSModuleID(); 30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LDO_32: 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_IE: 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setHasStaticTLS(); 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if buildint shared object, a RELATIVE dynamic relocation is needed 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->reserved() & GOTRel) 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reserve got and dyn relocation entries for tp-relative offset 31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(); 32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOTRel bit 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_GOTIE: 32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setHasStaticTLS(); 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->reserved() & GOTRel) 32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reserve got and dyn relocation entries for tp-relative offset 33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(); 33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOTRel bit 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LE: 33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LE_32: 34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setHasStaticTLS(); 34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if buildint shared object, a dynamic relocation is needed 34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the target symbol of the dynamic relocation is rsym, so we need to 34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit it into .dynsym 34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != rsym->outSymbol()); 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->addSymbolToDynSym(*rsym->outSymbol()); 34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unsupported_relocation) << (int)pReloc.type() 354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc, 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker, 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule, 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection& pSection) 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()) { 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_16: 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_8: 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Absolute relocation type, symbol may needs PLT entry or 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // dynamic relocation entry 37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolNeedsPLT(pLinker, *rsym)) { 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create plt for this symbol if it does not have one 375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!(rsym->reserved() & ReservePLT)){ 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTPLT->reserve(); 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT), 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao true)) { 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) { 393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 394affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addCopyReloc(*cpy_sym.resolveInfo()); 395affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 396affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 397affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set Rel bit 398affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReserveRel); 399affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: { 40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: A GOT section is needed 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PLT32: 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A PLT entry is needed when building shared library 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create plt for this symbol 413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->reserved() & ReservePLT) 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if the symbol's value can be decided at link time, then no need plt 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolFinalValueIsKnown(pLinker, *rsym)) 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if symbol is defined in the ouput file and it's not 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // preemptible, no need plt 422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isDefine() && !rsym->isDyn() && 42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !isSymbolPreemptible(*rsym)) { 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTPLT->reserve(); 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOT32: 4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs GOT entry, reserve entry in .got 4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create GOT for this symbol 441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->reserved() & (ReserveGOT | GOTRel)) 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(); 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If building shared object or the symbol is undefined, a dynamic 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // relocation is needed to relocate this GOT entry. Reserve an 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entry in .rel.dyn 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao config().codeGenType() || rsym->isUndef() || rsym->isDyn()) { 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOTRel bit 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOT bit 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGOT); 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_PC16: 46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_PC8: 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolNeedsPLT(pLinker, *rsym) && 46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkerConfig::DynObj != config().codeGenType()) { 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create plt for this symbol if it does not have one 465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!(rsym->reserved() & ReservePLT)){ 466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Symbol needs PLT entry, we need to reserve a PLT entry 467affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // and the corresponding GOT and dynamic relocation entry 468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // in .got and .rel.plt. (GOT entry will be reserved simultaneously 469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when calling X86PLT->reserveEntry()) 470affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pPLT->reserveEntry(); 47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTPLT->reserve(); 472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pRelPLT->reserveEntry(*m_pRelocFactory); 473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set PLT bit 474affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReservePLT); 475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolNeedsDynRel(pLinker, *rsym, (rsym->reserved() & ReservePLT), 47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao false)) { 480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pRelDyn->reserveEntry(*m_pRelocFactory); 48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolNeedsCopyReloc(pLinker, pReloc, *rsym)) { 483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addCopyReloc(*cpy_sym.resolveInfo()); 485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set Rel bit 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReserveRel); 489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_GD: { 49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: no linker optimization for TLS relocation 49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->reserved() & GOTRel) 49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 49722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reserve two pairs of got entry and dynamic relocation 49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(2); 49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory, 2); 50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOTRel bit 50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LDM: 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getTLSModuleID(); 50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LDO_32: 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_IE: 51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setHasStaticTLS(); 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if buildint shared object, a RELATIVE dynamic relocation is needed 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->reserved() & GOTRel) 52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reserve got and dyn relocation entries for tp-relative offset 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(); 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOTRel bit 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_GOTIE: 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setHasStaticTLS(); 53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->reserved() & GOTRel) 53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // reserve got and dyn relocation entries for tp-relative offset 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(); 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set GOTRel bit 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LE: 54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::R_386_TLS_LE_32: 54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao setHasStaticTLS(); 54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if buildint shared object, a dynamic relocation is needed 54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: { 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unsupported_relocation) << (int)pReloc.type() 551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc, 55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker, 55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule, 560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSection) 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == config().codeGenType()) 56322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != rsym && 56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao "ResolveInfo of relocation not set while scanRelocation"); 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pReloc.updateAddend(); 57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (pSection.flag() & llvm::ELF::SHF_ALLOC)) 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Scan relocation type to determine if the GOT/PLT/Dynamic Relocation 5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entries should be created. 57522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->isLocal()) // rsym is local 57622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao scanLocalReloc(pReloc, pLinker, pModule, pSection); 57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else // rsym is external 57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao scanGlobalReloc(pReloc, pLinker, pModule, pSection); 57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // check if we shoule issue undefined reference for the relocation target 58122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol 58222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak()) 58322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::undefined_reference) << rsym->name(); 58422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 58522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((rsym->reserved() & ReserveRel) != 0x0) { 58622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set hasTextRelSection if needed 58722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao checkAndSetHasTextRel(pSection); 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 59622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* FileFormat = getOutputFormat(); 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(FileFormat && 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int EntrySize = 0; 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t RegionSize = 0; 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(FileFormat->getPLT())) { 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned char* buffer = pRegion.getBuffer(); 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT0(); 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT1(); 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator it = m_pPLT->begin(); 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize(); 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size); 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += plt0_size; 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT1* plt1 = 0; 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator ie = m_pPLT->end(); 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (it != ie) { 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1 = &(llvm::cast<X86PLT1>(*it)); 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = plt1->getEntrySize(); 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer + RegionSize, plt1->getContent(), EntrySize); 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (&pSection == &(FileFormat->getGOT())) { 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 63322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao GOT::Entry* got = 0; 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = m_pGOT->getEntrySize(); 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (X86GOT::iterator it = m_pGOT->begin(), 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 63822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao got = &(llvm::cast<GOT::Entry>((*it))); 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *buffer = static_cast<uint32_t>(got->getContent()); 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 644affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else if (&pSection == &(FileFormat->getGOTPLT())) { 645affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(m_pGOTPLT && "emitSectionData failed, m_pGOTPLT is NULL!"); 646affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 64722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 648affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 649affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 650affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 65122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao GOT::Entry* got = 0; 652affc150dc44fab1911775a49636d0ce85333b634Zonr Chang EntrySize = m_pGOTPLT->getEntrySize(); 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (X86GOTPLT::iterator it = m_pGOTPLT->begin(), 655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 65622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao got = &(llvm::cast<GOT::Entry>((*it))); 657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *buffer = static_cast<uint32_t>(got->getContent()); 658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang RegionSize += EntrySize; 659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return RegionSize; 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 66922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EM_386; 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT() 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 687affc150dc44fab1911775a49636d0ce85333b634Zonr ChangX86GOTPLT& X86GNULDBackend::getGOTPLT() 688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 693affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst X86GOTPLT& X86GNULDBackend::getGOTPLT() const 694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT() 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn() 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 72322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// Create a GOT entry for the TLS module index 72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGOT::Entry& X86GNULDBackend::getTLSModuleID() 72522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao static GOT::Entry* got_entry = NULL; 72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != got_entry) 72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *got_entry; 72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM 73122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->reserve(2); 73222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao got_entry = m_pGOT->consume(); 73322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->consume()->setContent(0x0); 73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 73622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* rel_entry = m_pRelDyn->consumeEntry(); 73722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rel_entry->setType(llvm::ELF::R_386_TLS_DTPMOD32); 73822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rel_entry->targetRef().assign(*got_entry, 0x0); 73922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao rel_entry->setSymInfo(NULL); 74022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 74122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *got_entry; 74222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 74322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT() 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 75722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 75922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 761affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == &file_format->getGOT()) { 76222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNow()) 763affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO_LAST; 765affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 767affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == &file_format->getGOTPLT()) { 76822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().hasNow()) 769affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NON_RELRO_FIRST; 771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getPLT()) 7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_PLT; 7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const 7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 32; 7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 78422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder) 78522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 78622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 78822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got 78922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = file_format->getGOT(); 79022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT = new X86GOT(got); 79122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 79222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got.plt 79322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& gotplt = file_format->getGOTPLT(); 79422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTPLT = new X86GOTPLT(gotplt); 79522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 79622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .plt 79722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& plt = file_format->getPLT(); 79822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pPLT = new X86PLT(plt, 79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *m_pGOTPLT, 80022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao config()); 80122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 80222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .rel.plt 80322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& relplt = file_format->getRelPlt(); 80422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relplt.setLink(&plt); 80522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelPLT = new OutputRelocSection(pModule, 80622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao relplt, 80722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getRelEntrySize()); 80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .rel.dyn 80922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 81022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pRelDyn = new OutputRelocSection(pModule, 81122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reldyn, 81222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao getRelEntrySize()); 81322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 81622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::initTargetSymbols(FragmentLinker& pLinker) 81722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 81822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 81922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 82022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // same name in input 82122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTSymbol = 82222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::AsRefered, 82322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker::Resolve>("_GLOBAL_OFFSET_TABLE_", 82422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao false, 82522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Object, 82622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Define, 82722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Local, 82822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // size 82922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 0x0, // value 83022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 83122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Hidden); 83222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 83522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// finalizeSymbol - finalize the symbol value 83622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool X86GNULDBackend::finalizeTargetSymbols(FragmentLinker& pLinker) 8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 83822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 84122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the 84222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments 84322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid X86GNULDBackend::doCreateProgramHdrs(Module& pModule, 84422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const FragmentLinker& pLinker) 845affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 84622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO 8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget, 85522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LinkerConfig& pConfig) 8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 85722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pConfig.triple().isOSDarwin()) { 8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86MachOLDBackend(createX86MachOArchiveReader, 8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectReader, 8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectWriter); 8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 86522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pConfig.triple().isOSWindows()) { 8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86COFFLDBackend(createX86COFFArchiveReader, 8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectReader, 8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectWriter); 8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 87322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return new X86GNULDBackend(pConfig); 8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 87822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 88022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 88122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeX86LDBackend() { 8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend); 8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 885