X86LDBackend.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDOutput.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCRegionFragment.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::X86GNULDBackend() 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_pRelocFactory(NULL), 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT(NULL), 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT(NULL), 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL) { 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::~X86GNULDBackend() 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelocFactory) 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelocFactory; 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGOT) 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pGOT; 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pPLT) 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pPLT; 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL !=m_pRelDyn) 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelDyn; 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelPLT) 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelPLT; 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pDynamic) 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pDynamic; 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* X86GNULDBackend::getRelocFactory() 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelocFactory); 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pRelocFactory; 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker) 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelocFactory) { 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory = new X86RelocationFactory(1024, *this); 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory->setLayout(pLinker.getLayout()); 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPreLayout(const Output& pOutput, 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is needed 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pOutput.type() == Output::DynObj && (NULL == m_pGOT)) 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::doPostLayout(const Output& pOutput, 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit program headers 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitProgramHdrs(pLinker.getLDInfo().output()); 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86ELFDynamic& X86GNULDBackend::dynamic() 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic = new X86ELFDynamic(*this); 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86ELFDynamic& X86GNULDBackend::dynamic() const 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput) 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get .got LDSection and create MCSectionData 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& got = file_format->getGOT(); 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got)); 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( m_pGOTSymbol != NULL ) { 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>( 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker, 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& plt = file_format->getPLT(); 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& relplt = file_format->getRelPlt(); 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and X86PLT 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOT, pOutput); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set info of .rel.plt to .plt 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao relplt.setLink(&plt); 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and X86RelDynSection 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT = new OutputRelocSection(relplt, 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(relplt), 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::createX86RelDyn(MCLinker& pLinker, 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get .rel.dyn LDSection and create MCSectionData 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and X86RelDynSection 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn = new OutputRelocSection(reldyn, 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(reldyn), 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFFileFormat* X86GNULDBackend::getOutputFormat(const Output& pOutput) const 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pOutput.type()) { 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::DynObj: 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return getDynObjFileFormat(); 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Exec: 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return getExecFileFormat(); 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: We do not support building .o now 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Object: 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") + 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pOutput.type())); 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::isSymbolNeedsPLT(const ResolveInfo& pSym, 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) const 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return((Output::DynObj == pOutput.type()) 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &&(ResolveInfo::Function == pSym.type()) 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &&(pSym.isDyn() || pSym.isUndef() || 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao isSymbolPreemptible(pSym, pLDInfo, pOutput)) 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ); 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::isSymbolNeedsDynRel(const ResolveInfo& pSym, 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput, 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool isAbsReloc) const 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.isUndef() && (pOutput.type()==Output::Exec)) 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.isAbsolute()) 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pOutput.type()==Output::DynObj && isAbsReloc) 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.isDyn() || pSym.isUndef()) 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym, 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) const 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.other() != ResolveInfo::Default) 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pOutput.type() != Output::DynObj) 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pLDInfo.options().Bsymbolic()) 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::updateAddend(Relocation& pReloc, 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout) const 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Update value keep in addend if we meet a section symbol 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pReloc.symInfo()->type() == ResolveInfo::Section) { 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.setAddend(pLayout.getOutputOffset( 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *pInputSym.fragRef()) + pReloc.addend()); 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanLocalReloc(Relocation& pReloc, 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao updateAddend(pReloc, pInputSym, pLinker.getLayout()); 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()){ 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If buiding PIC object (shared library or PIC executable), 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // a dynamic relocations with RELATIVE type to this location is needed. 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Reserve an entry in .rel.dyn 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(Output::DynObj == pOutput.type()) { 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pRelDyn) 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set Rel bit 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A GOT section is needed 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pGOT) 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("unexpected reloc ") + 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine((int) pReloc.type()) + 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(" in object file")); 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanGlobalReloc(Relocation& pReloc, 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pReloc.type()) { 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_32: 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Absolute relocation type, symbol may needs PLT entry or 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // dynamic relocation entry 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(isSymbolNeedsPLT(*rsym, pLDInfo, pOutput)) { 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create plt for this symbol if it does not have one 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(!(rsym->reserved() & ReservePLT)){ 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Create .got section if it dosen't exist 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pGOT) 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .plt and .rel.plt if not exist 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pPLT) 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86PLTandRelPLT(pLinker, pOutput); 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(isSymbolNeedsDynRel(*rsym, pOutput, true)) { 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pRelDyn) 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set Rel bit 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTOFF: 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOTPC: { 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A GOT section is needed 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pGOT) 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PLT32: 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A PLT entry is needed when building shared library 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create plt for this symbol 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & ReservePLT) 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if symbol is defined in the ouput file and it's not 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // preemptible, no need plt 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->isDefine() && !rsym->isDyn() && 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) { 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Create .got section if it dosen't exist 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pGOT) 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .plt and .rel.plt if not exist 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pPLT) 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86PLTandRelPLT(pLinker, pOutput); 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs PLT entry, we need to reserve a PLT entry 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // and the corresponding GOT and dynamic relocation entry 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // in .got and .rel.plt. (GOT entry will be reserved simultaneously 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when calling X86PLT->reserveEntry()) 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->reserveEntry(); 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelPLT->reserveEntry(*m_pRelocFactory); 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set PLT bit 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReservePLT); 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_GOT32: 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Symbol needs GOT entry, reserve entry in .got 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // return if we already create GOT for this symbol 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->reserved() & (ReserveGOT | GOTRel)) 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pGOT) 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveEntry(); 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If building shared object or the symbol is undefined, a dynamic 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // relocation is needed to relocate this GOT entry. Reserve an 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entry in .rel.dyn 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) { 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create .rel.dyn section if not exist 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pRelDyn) 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86RelDyn(pLinker, pOutput); 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOTRel bit 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | GOTRel); 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set GOT bit 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGOT); 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_386_PC32: 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We allow R_386_PC32 only if it isn't preemptible. Otherwise 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // we will generate writable text section in output. 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!isSymbolPreemptible(*rsym, pLDInfo, pOutput)) 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: { 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Unexpected reloc ") + 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine((int) pReloc.type()) + 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(" in object file")); 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end switch 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::scanRelocation(Relocation& pReloc, 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // entries should be created. 4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Below judgements concern only .so is generated as output 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: Below judgements concren nothing about TLS related relocation 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got section 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // is needed 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL == m_pGOT && NULL != m_pGOTSymbol) { 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym == m_pGOTSymbol->resolveInfo()) { 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86GOT(pLinker, pOutput); 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym is local 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(rsym->isLocal()) 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym is external 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput); 4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t X86GNULDBackend::emitSectionData(const Output& pOutput, 4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* FileFormat = getOutputFormat(pOutput); 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(FileFormat && 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int EntrySize = 0; 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t RegionSize = 0; 4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(FileFormat->getPLT())) { 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned char* buffer = pRegion.getBuffer(); 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT0(); 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pPLT->applyPLT1(); 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator it = m_pPLT->begin(); 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize(); 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size); 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += plt0_size; 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT1* plt1 = 0; 4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao X86PLT::iterator ie = m_pPLT->end(); 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (it != ie) { 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1 = &(llvm::cast<X86PLT1>(*it)); 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = plt1->getEntrySize(); 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer + RegionSize, plt1->getContent(), EntrySize); 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (&pSection == &(FileFormat->getGOT())) { 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->applyGOT0(FileFormat->getDynamic().addr()); 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry* got = 0; 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntrySize = m_pGOT->getEntrySize(); 4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (X86GOT::iterator it = m_pGOT->begin(), 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got = &(llvm::cast<GOTEntry>((*it))); 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *buffer = static_cast<uint32_t>(got->getContent()); 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RegionSize += EntrySize; 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("unsupported section name " 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao + pSection.name() + " !"); 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return RegionSize; 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t X86GNULDBackend::machine() const 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EM_386; 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GOT& X86GNULDBackend::getGOT() 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86GOT& X86GNULDBackend::getGOT() const 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86PLT& X86GNULDBackend::getPLT() 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst X86PLT& X86GNULDBackend::getPLT() const 5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pPLT && "PLT section not exist"); 5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pPLT; 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelDyn() 5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelDyn() const 5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& X86GNULDBackend::getRelPLT() 5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& X86GNULDBackend::getRelPLT() const 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelPLT; 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::getTargetSectionOrder(const Output& pOutput, 5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSectHdr) const 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: if command line option, "-z now", is given, we can let the order of 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // .got and .got.plt be the same as RELRO sections 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getGOT()) 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_RELRO_LAST; 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getGOTPLT()) 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_NON_RELRO_FIRST; 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getPLT()) 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_PLT; 5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int X86GNULDBackend::bitclass() const 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 32; 5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSections(MCLinker& pLinker) 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid X86GNULDBackend::initTargetSymbols(MCLinker& pLinker) 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, // FragRef 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// If the symbol's reserved field is not zero, MCLinker will call back this 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// function to ask the final value of the symbol 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool X86GNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sections. 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoX86GNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // SymbolCategory contains all symbols that must emit to the output files. 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We are not like Google gold linker, we don't remember symbols before symbol 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // resolution. All symbols in SymbolCategory are already resolved. Therefore, we 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // don't need to care about some symbols may be changed its category due to symbol 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // resolution. 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory& symbol_list = pLinker.getOutputSymbols(); 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // addralign := max value of all common symbols 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t addralign = 0x0; 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Due to the visibility, some common symbols may be forcefully local. 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd(); 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((*com_sym)->value() > addralign) 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao addralign = (*com_sym)->value(); 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // global common symbols. 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((*com_sym)->value() > addralign) 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao addralign = (*com_sym)->value(); 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: If the order of common symbols is defined, then sort common symbols 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // com_sym = symbol_list.commonBegin(); 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // std::sort(com_sym, com_end, some kind of order); 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get or create corresponding BSS LDSection 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* bss_sect_hdr = NULL; 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr( 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ".tbss", 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss", 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get or create corresponding BSS MCSectionData 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != bss_sect_hdr); 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr); 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all common symbols 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t offset = bss_sect_hdr->size(); 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all local common symbols 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.localEnd(); 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size()); 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t size = pLinker.getLayout().appendFragment(*frag, 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_section, 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->value()); 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset += size; 6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all global common symbols 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size()); 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t size = pLinker.getLayout().appendFragment(*frag, 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_section, 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->value()); 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset += size; 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_sect_hdr->setSize(offset); 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_list.changeCommonsToGlobal(); 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createX86LDBackend - the help funtion to create corresponding X86LDBackend 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoTargetLDBackend* createX86LDBackend(const llvm::Target& pTarget, 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const std::string& pTriple) 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Triple theTriple(pTriple); 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSDarwin()) { 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86MachOLDBackend(createX86MachOArchiveReader, 7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectReader, 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86MachOObjectWriter); 7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSWindows()) { 7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** 7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86COFFLDBackend(createX86COFFArchiveReader, 7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectReader, 7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createX86COFFObjectWriter); 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao **/ 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new X86GNULDBackend(); 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//============================= 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeX86LDBackend() { 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend); 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 753