MipsLDBackend.cpp revision affc150dc44fab1911775a49636d0ce85333b634
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsLDBackend.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 <llvm/ADT/Triple.h> 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "Mips.h" 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsELFDynamic.h" 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsLDBackend.h" 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsRelocationFactory.h" 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum { 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // The original o32 abi. 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32 = 0x00001000, 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // O32 extended to work on 64 bit architectures. 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O64 = 0x00002000, 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 32 bit mode. 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI32 = 0x00003000, 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 64 bit mode. 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI64 = 0x00004000 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend() 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_pRelocFactory(NULL), 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL), 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol(NULL), 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol(NULL) 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend() 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelocFactory) 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelocFactory; 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGOT) 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pGOT; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelDyn) 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelDyn; 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pDynamic) 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pDynamic; 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Nothing to do because we do not support 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // any MIPS specific sections now. 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(MCLinker& pLinker) 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Set up .dynamic 71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFFileFormat* file_format = NULL; 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang switch(pLinker.getLDInfo().output().type()) { 73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case Output::DynObj: 74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format = getDynObjFileFormat(); 75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case Output::Exec: 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format = getExecFileFormat(); 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case Output::Object: 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // TODO: not support yet 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang file_format->getDynamic().setFlag(llvm::ELF::SHF_ALLOC); 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 87affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput) 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, // FragRef 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_gp_disp", 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Section, 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Absolute, 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, // FragRef 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Default); 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGpDispSymbol) { 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp); 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker) 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelocFactory) { 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory = new MipsRelocationFactory(1024, *this); 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory->setLayout(pLinker.getLayout()); 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* MipsGNULDBackend::getRelocFactory() 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelocFactory); 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pRelocFactory; 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanRelocation(Relocation& pReloc, 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Output& pOutput, 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSection) 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != pSection.getLink()); 145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) { 146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isLocal()) { 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang updateAddend(pReloc, pInputSym, pLinker.getLayout()); 148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // that a .got section is needed. 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT && NULL != m_pGOTSymbol) { 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (rsym == m_pGOTSymbol->resolveInfo()) { 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Skip relocation against _gp_disp 161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (strcmp("_gp_disp", pInputSym.name()) == 0) 162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We test isLocal or if pInputSym is not a dynamic symbol 165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn() 166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Don't put undef symbols into local entries. 167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ((rsym->isLocal() || !isDynamicSymbol(pInputSym, pOutput) || 168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang !rsym->isDyn()) && !rsym->isUndef()) 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t MipsGNULDBackend::machine() const 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EM_MIPS; 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::OSABI() const 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::ELFOSABI_NONE; 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::ABIVersion() const 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::flags() const 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The correct flag's set depend on command line 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // arguments and flags from input .o files. 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EF_MIPS_ARCH_32R2 | 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_NOREORDER | 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_PIC | 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_CPIC | 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32; 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isLittleEndian() const 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Now we support little endian (mipsel) target only. 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int MipsGNULDBackend::bitclass() const 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 32; 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 211affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t MipsGNULDBackend::defaultTextSegmentAddr() const 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return 0x80000; 214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(const Output& pOutput, 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is must. 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pOutput.type() == Output::DynObj && NULL == m_pGOT) { 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(const Output& pOutput, 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic() 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic = new MipsELFDynamic(*this); 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput, 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Layout& pLayout, 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* file_format = getOutputFormat(pOutput); 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(file_format->getGOT())) { 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pGOT->emit(pRegion); 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry. 272affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return std::find(m_GlobalGOTSyms.begin(), 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end(); 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitDynamicSymbol - emit dynamic symbol. 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32, 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Output& pOutput, 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol& pSymbol, 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab, 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize, 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx) 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // maintain output's symbol and index map 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(&pSymbol, sym_exist); 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(symtabIdx); 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: check the endian between host and target 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out symbol 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_name = strtabsize; 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_value = pSymbol.value(); 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_size = getSymbolSize(pSymbol); 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_info = getSymbolInfo(pSymbol); 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_other = pSymbol.visibility(); 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_shndx = getSymbolShndx(pSymbol, pLayout); 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out string 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), pSymbol.name()); 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(Output& pOutput, 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory& pSymbols, 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo) 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pOutput.hasMemArea()); 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& hash_sect = file_format->getHashTab(); 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& dyn_sect = file_format->getDynamic(); 3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(), 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab_sect.size()); 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(), 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab_sect.size()); 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(), 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao hash_sect.size()); 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(), 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dyn_sect.size()); 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_name = 0; 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_value = 0; 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_size = 0; 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_info = 0; 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_other = 0; 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_shndx = 0; 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab[0] = '\0'; 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add index 0 symbol into SymIndexMap 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(NULL, sym_exist); 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(0); 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx = 1; 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit of .dynsym, and .dynstr except GOT entries 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (SymbolCategory::iterator symbol = pSymbols.begin(), 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym_end = pSymbols.end(); symbol != sym_end; ++symbol) { 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!isDynamicSymbol(**symbol, pOutput)) 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isGlobalGOTSymbol(**symbol)) 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize, symtabIdx); 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit global GOT 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(), 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_end = m_GlobalGOTSyms.end(); 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol != symbol_end; ++symbol) { 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Make sure this golbal GOT entry is a dynamic symbol. 378affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // If not, something is wrong earlier when putting this symbol into 379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // global GOT. 380affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!isDynamicSymbol(**symbol, pOutput)) 381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::mips_got_symbol) << (*symbol)->name(); 382affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize, symtabIdx); 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Rules: 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. ignore --no-add-needed 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. force count in --no-as-needed 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 3. judge --as-needed 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end(); 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) { 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Input::DynObj == (*input)->type()) { 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --add-needed 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((*input)->attribute()->isAddNeeded()) { 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --no-as-needed 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(*input)->attribute()->isAsNeeded()) { 4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), (*input)->name().c_str()); 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*input)->name().size() + 1; 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++dt_need; 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --as-needed 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if ((*input)->isNeeded()) { 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), (*input)->name().c_str()); 4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*input)->name().size() + 1; 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++dt_need; 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // for 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit soname 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Output::DynObj == pOutput.type()) 424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dynamic().applySoname(strtabsize); 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().applyEntries(pLDInfo, *file_format); 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().emit(dyn_sect, *dyn_region); 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), pOutput.name().c_str()); 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += pOutput.name().size() + 1; 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit hash table 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: this verion only emit SVR4 hash section. 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Please add GNU new hash section 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* word_array = (uint32_t*)hash_region->start(); 4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nchain = word_array[1]; 4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nbucket = getHashBucketCount(symtabIdx, false); 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nchain = symtabIdx; 4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* chain = (bucket + nbucket); 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bzero((void*)bucket, nbucket); 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao StringHash<ELF> hash_func; 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) { 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef name(strtab + symtab32[sym_idx].st_name); 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t bucket_pos = hash_func(name) % nbucket; 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao chain[sym_idx] = bucket[bucket_pos]; 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bucket[bucket_pos] = sym_idx; 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT() 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn() 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const Output& pOutput, 487affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSectHdr, 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const MCLDInfo& pInfo) const 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 490affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* file_format = getOutputFormat(pOutput); 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getGOT()) 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 499affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput) 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0); 502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sections. 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory& symbol_list = pLinker.getOutputSymbols(); 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: If the order of common symbols is defined, then sort common symbols 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // std::sort(com_sym, com_end, some kind of order); 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get or create corresponding BSS LDSection 523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* bss_sect = &pLinker.getOrCreateOutputSectHdr(".bss", 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* tbss_sect = &pLinker.getOrCreateOutputSectHdr( 529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".tbss", 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: .sbss amd .lbss currently unused. 535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* 536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* sbss_sect = &pLinker.getOrCreateOutputSectHdr( 537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".sbss", 538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC | 541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_MIPS_GPREL); 542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* lbss_sect = &pLinker.getOrCreateOutputSectHdr( 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".lbss", 545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 547affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC | 548affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_MIPS_LOCAL); 549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang */ 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != bss_sect && NULL != tbss_sect); 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get or create corresponding BSS MCSectionData 554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::MCSectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect); 555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::MCSectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect); 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t bss_offset = bss_sect->size(); 559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t tbss_offset = tbss_sect->size(); 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all local common symbols 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.localEnd(); 563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size()); 5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_offset += pLinker.getLayout().appendFragment(*frag, 578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_sect_data, 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 582affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 583affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_offset += pLinker.getLayout().appendFragment(*frag, 584affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_data, 585affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 586affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all global common symbols 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size()); 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_offset += pLinker.getLayout().appendFragment(*frag, 605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_sect_data, 606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_offset += pLinker.getLayout().appendFragment(*frag, 611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_data, 612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 613affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect->setSize(bss_offset); 617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_sect->setSize(tbss_offset); 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_list.changeCommonsToGlobal(); 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::updateAddend(Relocation& pReloc, 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout) const 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Update value keep in addend if we meet a section symbol 627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pReloc.symInfo()->type() == ResolveInfo::Section) { 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.setAddend(pLayout.getOutputOffset( 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *pInputSym.fragRef()) + pReloc.addend()); 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc, 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao updateAddend(pReloc, pInputSym, pLinker.getLayout()); 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Output::DynObj == pOutput.type()) { 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The gold linker does not create an entry in .rel.dyn 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // section if the symbol section flags contains SHF_EXECINSTR. 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. Find the reason of this condition. 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. Check this condition here. 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelDyn) 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createRelDyn(pLinker, pOutput); 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 659affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry (as if it needs an entry). 660affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Actually we don't allocate an GOT entry. 661affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 662affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createGOT(pLinker, pOutput); 663affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT) 6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // For got16 section based relocations, we need to reserve got entries. 698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->type() == ResolveInfo::Section) { 699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->reserveLocalEntry(); 700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry 701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveLocalEntry(); 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 708affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry 709affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD32: 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 737affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unknown_relocation) << (int)pReloc.type() 738affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc, 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 767affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsDynRel(*rsym, false, pLDInfo, pOutput, true)) { 7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelDyn) 7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createRelDyn(pLinker, pOutput); 7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 773affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 774affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a global GOT entry (as if it needs an entry). 775affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Actually we don't allocate an GOT entry. 776affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 777affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createGOT(pLinker, pOutput); 778affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setGlobal(rsym); 7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 7895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT) 7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 7925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveGlobalEntry(); 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.push_back(rsym->outSymbol()); 797affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a global GOT entry 798affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setGlobal(rsym); 7995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 803affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::invalid_global_relocation) << (int)pReloc.type() 804affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 836affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::dynamic_relocation) << (int)pReloc.type(); 8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 839affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unknown_relocation) << (int)pReloc.type() 840affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput) 8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& got = file_format->getGOT(); 8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got)); 8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ( m_pGOTSymbol != NULL ) { 8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>( 8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput) 8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get .rel.dyn LDSection and create MCSectionData 8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and ARMRelDynSection 8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn = new OutputRelocSection(reldyn, 8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(reldyn), 8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget, 8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const std::string& pTriple) 8955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Triple theTriple(pTriple); 8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSDarwin()) { 8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSWindows()) { 9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new MipsGNULDBackend(); 9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 9075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//============================= 9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeMipsLDBackend() { 9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::createMipsLDBackend); 9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 915