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 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86.h" 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86ELFDynamic.h" 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86LDBackend.h" 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "X86RelocationFactory.h" 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/SectionMap.h> 19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h> 20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/RegionFragment.h> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDOutput.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h> 24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h> 25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::X86GNULDBackend() 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_pRelocFactory(NULL), 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT(NULL), 36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT(NULL), 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT(NULL), 3967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao m_pDynamic(NULL), 4067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao m_pGOTSymbol(NULL) { 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend() 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelocFactory) 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelocFactory; 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGOT) 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pGOT; 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pPLT) 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pPLT; 51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != m_pGOTPLT) 52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang delete m_pGOTPLT; 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL !=m_pRelDyn) 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelDyn; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelPLT) 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelPLT; 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pDynamic) 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pDynamic; 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* X86GNULDBackend::getRelocFactory() 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelocFactory); 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pRelocFactory; 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker) 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelocFactory) { 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory = new X86RelocationFactory(1024, *this); 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory->setLayout(pLinker.getLayout()); 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPreLayout(const Output& pOutput, 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is needed 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Output::DynObj == pOutput.type() && (NULL == m_pGOTPLT)) { 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPostLayout(const Output& pOutput, 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic() 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic = new X86ELFDynamic(*this); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput) 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 112cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get .got LDSection and create SectionData 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& got = file_format->getGOT(); 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got)); 117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 119affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::createX86GOTPLT(MCLinker& pLinker, const Output& pOutput) 120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get .got.plt LDSection and create SectionData 122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFFileFormat* file_format = getOutputFormat(pOutput); 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection& gotplt = file_format->getGOTPLT(); 125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT = new X86GOTPLT(gotplt, pLinker.getOrCreateSectData(gotplt)); 126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // define symbol _GLOBAL_OFFSET_TABLE_ when .got.plt create 128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.defineSymbol<MCLinker::Force, MCLinker::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 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()), 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0), 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()), 151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0), 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker, 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& plt = file_format->getPLT(); 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& relplt = file_format->getRelPlt(); 163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(m_pGOTPLT != NULL); 164cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // create SectionData and X86PLT 165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOTPLT, pOutput); 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set info of .rel.plt to .plt 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao relplt.setLink(&plt); 169cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // create SectionData and X86RelDynSection 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT = new OutputRelocSection(relplt, 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(relplt), 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86RelDyn(MCLinker& pLinker, 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get .rel.dyn LDSection and create SectionData 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 182cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // create SectionData and X86RelDynSection 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn = new OutputRelocSection(reldyn, 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(reldyn), 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 188affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::addCopyReloc(ResolveInfo& pSym) 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bool exist; 191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Relocation& rel_entry = *m_pRelDyn->getEntry(pSym, false, exist); 192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.setType(llvm::ELF::R_386_COPY); 193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pSym.outSymbol()->hasFragRef()); 194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); 195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.setSymInfo(&pSym); 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 198affc150dc44fab1911775a49636d0ce85333b634Zonr ChangLDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(MCLinker& pLinker, 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ResolveInfo& pSym) 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // For a symbol needing copy relocation, define a copy symbol in the BSS 202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // section and all other reference to this symbol should refer to this 203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // copy. 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // get or create corresponding BSS LDSection 206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* bss_sect_hdr = NULL; 207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == pSym.type()) { 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr( 209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".tbss", 210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss", 216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 221cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != bss_sect_hdr); 223cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SectionData& bss_section = pLinker.getOrCreateSectData( 224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *bss_sect_hdr); 225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Determine the alignment by the symbol value 227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: here we use the largest alignment 228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t addralign = bitclass() / 8; 229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate space in BSS for the copy symbol 231cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, pSym.size()); 232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t size = pLinker.getLayout().appendFragment(*frag, 233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_section, 234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addralign); 235affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_hdr->setSize(bss_sect_hdr->size() + size); 236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // change symbol binding to Global if it's a weak symbol 238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); 239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (binding == ResolveInfo::Weak) 240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang binding = ResolveInfo::Global; 241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Define the copy symbol in the bss section and resolve it 243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* cpy_sym = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.name(), 245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, 246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (ResolveInfo::Type)pSym.type(), 247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang binding, 249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.size(), // size 250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLinker.getLayout().getFragmentRef(*frag, 0x0), 252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (ResolveInfo::Visibility)pSym.other()); 253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *cpy_sym; 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::updateAddend(Relocation& pReloc, 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout) const 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Update value keep in addend if we meet a section symbol 262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pReloc.symInfo()->type() == ResolveInfo::Section) { 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.setAddend(pLayout.getOutputOffset( 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *pInputSym.fragRef()) + pReloc.addend()); 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc, 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao updateAddend(pReloc, pInputSym, pLinker.getLayout()); 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()){ 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If buiding PIC object (shared library or PIC executable), 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // a dynamic relocations with RELATIVE type to this location is needed. 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Reserve an entry in .rel.dyn 285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isOutputPIC(pOutput, pLDInfo)) { 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set Rel bit 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A GOT section is needed 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unsupported_relocation) << (int)pReloc.type() 307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc, 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()) { 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Absolute relocation type, symbol may needs PLT entry or 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // dynamic relocation entry 325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsPLT(*rsym, pLDInfo, pOutput)) { 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create plt for this symbol if it does not have one 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!(rsym->reserved() & ReservePLT)){ 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Create .got section if it dosen't exist 329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT) 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .plt and .rel.plt if not exist 332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pPLT) 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86PLTandRelPLT(pLinker, pOutput); 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), 346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLDInfo, pOutput, true)) { 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo, 353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput)) { 354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addCopyReloc(*cpy_sym.resolveInfo()); 356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 358affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set Rel bit 359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReserveRel); 360affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: { 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A GOT section is needed 367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PLT32: 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A PLT entry is needed when building shared library 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create plt for this symbol 376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->reserved() & ReservePLT) 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if symbol is defined in the ouput file and it's not 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // preemptible, no need plt 381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isDefine() && !rsym->isDyn() && 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) { 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Create .got section if it dosen't exist 387affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT) 388affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .plt and .rel.plt if not exist 390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pPLT) 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86PLTandRelPLT(pLinker, pOutput); 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOT32: 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs GOT entry, reserve entry in .got 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create GOT for this symbol 405affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->reserved() & (ReserveGOT | GOTRel)) 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 407affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveEntry(); 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If building shared object or the symbol is undefined, a dynamic 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // relocation is needed to relocate this GOT entry. Reserve an 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entry in .rel.dyn 413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) { 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 415affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOTRel bit 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOT bit 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGOT); 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsPLT(*rsym, pLDInfo, pOutput) && 429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput.type() != Output::DynObj) { 430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create plt for this symbol if it does not have one 431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!(rsym->reserved() & ReservePLT)){ 432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Create .got section if it dosen't exist 433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT) 434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create .plt and .rel.plt if not exist 436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pPLT) 437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86PLTandRelPLT(pLinker, pOutput); 438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Symbol needs PLT entry, we need to reserve a PLT entry 439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // and the corresponding GOT and dynamic relocation entry 440affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // in .got and .rel.plt. (GOT entry will be reserved simultaneously 441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when calling X86PLT->reserveEntry()) 442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pPLT->reserveEntry(); 443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pRelPLT->reserveEntry(*m_pRelocFactory); 444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set PLT bit 445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReservePLT); 446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), 450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLDInfo, pOutput, false)) { 451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create .rel.dyn section if not exist 453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86RelDyn(pLinker, pOutput); 455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pRelDyn->reserveEntry(*m_pRelocFactory); 456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo, 457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput)) { 458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addCopyReloc(*cpy_sym.resolveInfo()); 460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set Rel bit 463affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReserveRel); 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 466affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: { 468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unsupported_relocation) << (int)pReloc.type() 469affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc, 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Output& pOutput, 480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSection) 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != pSection.getLink()); 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) { 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isLocal()) { 489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang updateAddend(pReloc, pInputSym, pLinker.getLayout()); 490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 491affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 492affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entries should be created. 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Below judgements concern only .so is generated as output 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Below judgements concren nothing about TLS related relocation 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got.plt 500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // section is needed 501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT && NULL != m_pGOTSymbol) { 502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym == m_pGOTSymbol->resolveInfo()) { 503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym is local 508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isLocal()) 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym is external 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput); 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const Output& pOutput, 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Layout& pLayout, 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* FileFormat = getOutputFormat(pOutput); 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(FileFormat && 5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int EntrySize = 0; 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t RegionSize = 0; 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(FileFormat->getPLT())) { 5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned char* buffer = pRegion.getBuffer(); 5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT0(); 5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT1(); 5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator it = m_pPLT->begin(); 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize(); 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size); 5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += plt0_size; 5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT1* plt1 = 0; 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator ie = m_pPLT->end(); 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (it != ie) { 5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1 = &(llvm::cast<X86PLT1>(*it)); 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = plt1->getEntrySize(); 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer + RegionSize, plt1->getContent(), EntrySize); 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (&pSection == &(FileFormat->getGOT())) { 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry* got = 0; 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = m_pGOT->getEntrySize(); 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (X86GOT::iterator it = m_pGOT->begin(), 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got = &(llvm::cast<GOTEntry>((*it))); 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *buffer = static_cast<uint32_t>(got->getContent()); 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else if (&pSection == &(FileFormat->getGOTPLT())) { 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(m_pGOTPLT && "emitSectionData failed, m_pGOTPLT is NULL!"); 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang GOTEntry* got = 0; 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang EntrySize = m_pGOTPLT->getEntrySize(); 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (X86GOTPLT::iterator it = m_pGOTPLT->begin(), 584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang got = &(llvm::cast<GOTEntry>((*it))); 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *buffer = static_cast<uint32_t>(got->getContent()); 587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang RegionSize += EntrySize; 588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return RegionSize; 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const 5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EM_386; 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT() 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 615affc150dc44fab1911775a49636d0ce85333b634Zonr ChangX86GOTPLT& X86GNULDBackend::getGOTPLT() 616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 621affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst X86GOTPLT& X86GNULDBackend::getGOTPLT() const 622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 623affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 624affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 625affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 626affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT() 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn() 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT() 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const Output& pOutput, 665affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSectHdr, 666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const MCLDInfo& pInfo) const 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* file_format = getOutputFormat(pOutput); 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == &file_format->getGOT()) { 671affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pInfo.options().hasNow()) 672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO_LAST; 674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == &file_format->getGOTPLT()) { 677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pInfo.options().hasNow()) 678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NON_RELRO_FIRST; 680affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getPLT()) 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_PLT; 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 32; 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSections(MCLinker& pLinker) 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 702affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput) 7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, // FragRef 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 719affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool X86GNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput) 720affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget, 7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const std::string& pTriple) 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Triple theTriple(pTriple); 7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSDarwin()) { 7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86MachOLDBackend(createX86MachOArchiveReader, 7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectReader, 7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectWriter); 7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSWindows()) { 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86COFFLDBackend(createX86COFFArchiveReader, 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectReader, 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectWriter); 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86GNULDBackend(); 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//============================= 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeX86LDBackend() { 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend); 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 760