X86LDBackend.cpp revision affc150dc44fab1911775a49636d0ce85333b634
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> 16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/SectionMap.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDOutput.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCRegionFragment.h> 21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h> 22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h> 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::X86GNULDBackend() 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_pRelocFactory(NULL), 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT(NULL), 33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT(NULL), 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT(NULL), 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL) { 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend() 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelocFactory) 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelocFactory; 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGOT) 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pGOT; 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pPLT) 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pPLT; 47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != m_pGOTPLT) 48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang delete m_pGOTPLT; 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL !=m_pRelDyn) 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelDyn; 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelPLT) 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelPLT; 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pDynamic) 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-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 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker) 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelocFactory) { 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory = new X86RelocationFactory(1024, *this); 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory->setLayout(pLinker.getLayout()); 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPreLayout(const Output& pOutput, 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is needed 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Output::DynObj == pOutput.type() && (NULL == m_pGOTPLT)) { 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPostLayout(const Output& pOutput, 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic() 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic = new X86ELFDynamic(*this); 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput) 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get .got LDSection and create MCSectionData 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& got = file_format->getGOT(); 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got)); 113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 115affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::createX86GOTPLT(MCLinker& pLinker, const Output& pOutput) 116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // get .got.plt LDSection and create MCSectionData 118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFFileFormat* file_format = getOutputFormat(pOutput); 119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection& gotplt = file_format->getGOTPLT(); 121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT = new X86GOTPLT(gotplt, pLinker.getOrCreateSectData(gotplt)); 122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // define symbol _GLOBAL_OFFSET_TABLE_ when .got.plt create 124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pGOTSymbol != NULL) { 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>( 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()), 134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0), 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLinker.getLayout().getFragmentRef(*(m_pGOTPLT->begin()), 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0), 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker, 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& plt = file_format->getPLT(); 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& relplt = file_format->getRelPlt(); 159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(m_pGOTPLT != NULL); 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and X86PLT 161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOTPLT, pOutput); 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set info of .rel.plt to .plt 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao relplt.setLink(&plt); 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and X86RelDynSection 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT = new OutputRelocSection(relplt, 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(relplt), 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86RelDyn(MCLinker& pLinker, 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get .rel.dyn LDSection and create MCSectionData 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and X86RelDynSection 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn = new OutputRelocSection(reldyn, 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(reldyn), 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 184affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::addCopyReloc(ResolveInfo& pSym) 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bool exist; 187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Relocation& rel_entry = *m_pRelDyn->getEntry(pSym, false, exist); 188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.setType(llvm::ELF::R_386_COPY); 189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pSym.outSymbol()->hasFragRef()); 190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); 191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rel_entry.setSymInfo(&pSym); 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 194affc150dc44fab1911775a49636d0ce85333b634Zonr ChangLDSymbol& X86GNULDBackend::defineSymbolforCopyReloc(MCLinker& pLinker, 195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ResolveInfo& pSym) 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // For a symbol needing copy relocation, define a copy symbol in the BSS 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // section and all other reference to this symbol should refer to this 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // copy. 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // get or create corresponding BSS LDSection 202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* bss_sect_hdr = NULL; 203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == pSym.type()) { 204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr( 205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".tbss", 206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss", 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // get or create corresponding BSS MCSectionData 218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != bss_sect_hdr); 219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData( 220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *bss_sect_hdr); 221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Determine the alignment by the symbol value 223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: here we use the largest alignment 224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t addralign = bitclass() / 8; 225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate space in BSS for the copy symbol 227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, pSym.size()); 228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t size = pLinker.getLayout().appendFragment(*frag, 229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_section, 230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addralign); 231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_hdr->setSize(bss_sect_hdr->size() + size); 232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // change symbol binding to Global if it's a weak symbol 234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); 235affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (binding == ResolveInfo::Weak) 236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang binding = ResolveInfo::Global; 237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Define the copy symbol in the bss section and resolve it 239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* cpy_sym = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.name(), 241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang false, 242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (ResolveInfo::Type)pSym.type(), 243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo::Define, 244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang binding, 245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSym.size(), // size 246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 0x0, // value 247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLinker.getLayout().getFragmentRef(*frag, 0x0), 248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (ResolveInfo::Visibility)pSym.other()); 249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *cpy_sym; 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::updateAddend(Relocation& pReloc, 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout) const 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Update value keep in addend if we meet a section symbol 258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pReloc.symInfo()->type() == ResolveInfo::Section) { 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.setAddend(pLayout.getOutputOffset( 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *pInputSym.fragRef()) + pReloc.addend()); 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc, 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao updateAddend(pReloc, pInputSym, pLinker.getLayout()); 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()){ 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If buiding PIC object (shared library or PIC executable), 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // a dynamic relocations with RELATIVE type to this location is needed. 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Reserve an entry in .rel.dyn 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isOutputPIC(pOutput, pLDInfo)) { 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set Rel bit 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A GOT section is needed 294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unsupported_relocation) << (int)pReloc.type() 303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc, 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()) { 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Absolute relocation type, symbol may needs PLT entry or 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // dynamic relocation entry 321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsPLT(*rsym, pLDInfo, pOutput)) { 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create plt for this symbol if it does not have one 323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!(rsym->reserved() & ReservePLT)){ 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Create .got section if it dosen't exist 325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT) 326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .plt and .rel.plt if not exist 328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pPLT) 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86PLTandRelPLT(pLinker, pOutput); 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), 342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLDInfo, pOutput, true)) { 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 348affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo, 349affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput)) { 350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addCopyReloc(*cpy_sym.resolveInfo()); 352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set Rel bit 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReserveRel); 356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: { 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A GOT section is needed 363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PLT32: 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A PLT entry is needed when building shared library 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create plt for this symbol 372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->reserved() & ReservePLT) 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if symbol is defined in the ouput file and it's not 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // preemptible, no need plt 377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isDefine() && !rsym->isDyn() && 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) { 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Create .got section if it dosen't exist 383affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT) 384affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .plt and .rel.plt if not exist 386affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pPLT) 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86PLTandRelPLT(pLinker, pOutput); 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOT32: 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs GOT entry, reserve entry in .got 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create GOT for this symbol 401affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->reserved() & (ReserveGOT | GOTRel)) 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveEntry(); 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If building shared object or the symbol is undefined, a dynamic 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // relocation is needed to relocate this GOT entry. Reserve an 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entry in .rel.dyn 409affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) { 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 411affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOTRel bit 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOT bit 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGOT); 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsPLT(*rsym, pLDInfo, pOutput) && 425affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput.type() != Output::DynObj) { 426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create plt for this symbol if it does not have one 427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!(rsym->reserved() & ReservePLT)){ 428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Create .got section if it dosen't exist 429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT) 430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create .plt and .rel.plt if not exist 432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pPLT) 433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86PLTandRelPLT(pLinker, pOutput); 434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Symbol needs PLT entry, we need to reserve a PLT entry 435affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // and the corresponding GOT and dynamic relocation entry 436affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // in .got and .rel.plt. (GOT entry will be reserved simultaneously 437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // when calling X86PLT->reserveEntry()) 438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pPLT->reserveEntry(); 439affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pRelPLT->reserveEntry(*m_pRelocFactory); 440affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set PLT bit 441affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReservePLT); 442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 445affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), 446affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pLDInfo, pOutput, false)) { 447affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 448affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create .rel.dyn section if not exist 449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pRelDyn) 450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86RelDyn(pLinker, pOutput); 451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pRelDyn->reserveEntry(*m_pRelocFactory); 452affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsCopyReloc(pLinker.getLayout(), pReloc, *rsym, pLDInfo, 453affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput)) { 454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol& cpy_sym = defineSymbolforCopyReloc(pLinker, *rsym); 455affc150dc44fab1911775a49636d0ce85333b634Zonr Chang addCopyReloc(*cpy_sym.resolveInfo()); 456affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 457affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 458affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set Rel bit 459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang rsym->setReserved(rsym->reserved() | ReserveRel); 460affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 462affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: { 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unsupported_relocation) << (int)pReloc.type() 465affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc, 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 475affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Output& pOutput, 476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSection) 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != pSection.getLink()); 483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) { 484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isLocal()) { 485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang updateAddend(pReloc, pInputSym, pLinker.getLayout()); 486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entries should be created. 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Below judgements concern only .so is generated as output 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Below judgements concren nothing about TLS related relocation 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got.plt 496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // section is needed 497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOTPLT && NULL != m_pGOTSymbol) { 498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym == m_pGOTSymbol->resolveInfo()) { 499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createX86GOTPLT(pLinker, pOutput); 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym is local 504affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isLocal()) 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym is external 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput); 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const Output& pOutput, 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Layout& pLayout, 5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* FileFormat = getOutputFormat(pOutput); 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(FileFormat && 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int EntrySize = 0; 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t RegionSize = 0; 5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(FileFormat->getPLT())) { 5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned char* buffer = pRegion.getBuffer(); 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT0(); 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT1(); 5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator it = m_pPLT->begin(); 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize(); 5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size); 5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += plt0_size; 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT1* plt1 = 0; 5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator ie = m_pPLT->end(); 5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (it != ie) { 5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1 = &(llvm::cast<X86PLT1>(*it)); 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = plt1->getEntrySize(); 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer + RegionSize, plt1->getContent(), EntrySize); 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (&pSection == &(FileFormat->getGOT())) { 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry* got = 0; 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = m_pGOT->getEntrySize(); 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (X86GOT::iterator it = m_pGOT->begin(), 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got = &(llvm::cast<GOTEntry>((*it))); 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *buffer = static_cast<uint32_t>(got->getContent()); 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else if (&pSection == &(FileFormat->getGOTPLT())) { 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(m_pGOTPLT && "emitSectionData failed, m_pGOTPLT is NULL!"); 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang GOTEntry* got = 0; 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang EntrySize = m_pGOTPLT->getEntrySize(); 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (X86GOTPLT::iterator it = m_pGOTPLT->begin(), 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang got = &(llvm::cast<GOTEntry>((*it))); 582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *buffer = static_cast<uint32_t>(got->getContent()); 583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang RegionSize += EntrySize; 584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 587affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return RegionSize; 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const 5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EM_386; 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT() 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 611affc150dc44fab1911775a49636d0ce85333b634Zonr ChangX86GOTPLT& X86GNULDBackend::getGOTPLT() 612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 614affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 615affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 617affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst X86GOTPLT& X86GNULDBackend::getGOTPLT() const 618affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != m_pGOTPLT); 620affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return *m_pGOTPLT; 621affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT() 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn() 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT() 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const Output& pOutput, 661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSectHdr, 662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const MCLDInfo& pInfo) const 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 664affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* file_format = getOutputFormat(pOutput); 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 666affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == &file_format->getGOT()) { 667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pInfo.options().hasNow()) 668affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO_LAST; 670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 672affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (&pSectHdr == &file_format->getGOTPLT()) { 673affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pInfo.options().hasNow()) 674affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return SHO_RELRO; 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NON_RELRO_FIRST; 676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getPLT()) 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_PLT; 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 32; 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSections(MCLinker& pLinker) 6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 698affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid X86GNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput) 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, // FragRef 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 715affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool X86GNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput) 716affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget, 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const std::string& pTriple) 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Triple theTriple(pTriple); 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSDarwin()) { 7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86MachOLDBackend(createX86MachOArchiveReader, 7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectReader, 7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectWriter); 7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSWindows()) { 7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86COFFLDBackend(createX86COFFArchiveReader, 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectReader, 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectWriter); 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86GNULDBackend(); 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//============================= 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeX86LDBackend() { 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend); 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 756