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 10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "Mips.h" 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsELFDynamic.h" 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsLDBackend.h" 13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsRelocationFactory.h" 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h> 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum { 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // The original o32 abi. 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32 = 0x00001000, 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // O32 extended to work on 64 bit architectures. 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O64 = 0x00002000, 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 32 bit mode. 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI32 = 0x00003000, 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 64 bit mode. 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI64 = 0x00004000 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend() 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_pRelocFactory(NULL), 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL), 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol(NULL), 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol(NULL) 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend() 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelocFactory) 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelocFactory; 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGOT) 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pGOT; 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelDyn) 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelDyn; 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pDynamic) 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pDynamic; 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Nothing to do because we do not support 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // any MIPS specific sections now. 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(MCLinker& pLinker) 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 73affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput) 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, // FragRef 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>( 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_gp_disp", 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Section, 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Absolute, 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, // FragRef 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Default); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGpDispSymbol) { 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp); 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker) 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelocFactory) { 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory = new MipsRelocationFactory(1024, *this); 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelocFactory->setLayout(pLinker.getLayout()); 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocationFactory* MipsGNULDBackend::getRelocFactory() 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelocFactory); 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pRelocFactory; 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanRelocation(Relocation& pReloc, 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Output& pOutput, 124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSection) 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != pSection.getLink()); 131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) { 132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->isLocal()) { 133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang updateAddend(pReloc, pInputSym, pLinker.getLayout()); 134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // that a .got section is needed. 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT && NULL != m_pGOTSymbol) { 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (rsym == m_pGOTSymbol->resolveInfo()) { 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Skip relocation against _gp_disp 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (strcmp("_gp_disp", pInputSym.name()) == 0) 148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We test isLocal or if pInputSym is not a dynamic symbol 151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn() 152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Don't put undef symbols into local entries. 153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ((rsym->isLocal() || !isDynamicSymbol(pInputSym, pOutput) || 154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang !rsym->isDyn()) && !rsym->isUndef()) 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t MipsGNULDBackend::machine() const 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EM_MIPS; 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::OSABI() const 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::ELFOSABI_NONE; 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::ABIVersion() const 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::flags() const 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The correct flag's set depend on command line 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // arguments and flags from input .o files. 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EF_MIPS_ARCH_32R2 | 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_NOREORDER | 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_PIC | 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_CPIC | 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32; 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isLittleEndian() const 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Now we support little endian (mipsel) target only. 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int MipsGNULDBackend::bitclass() const 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 32; 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 197affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t MipsGNULDBackend::defaultTextSegmentAddr() const 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return 0x80000; 200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 202cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaouint64_t MipsGNULDBackend::abiPageSize(const MCLDInfo& pInfo) const 203cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 204cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (pInfo.options().maxPageSize() > 0) 205cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return pInfo.options().maxPageSize(); 206cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao else 207cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return static_cast<uint64_t>(0x10000); 208cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 209cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(const Output& pOutput, 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is must. 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pOutput.type() == Output::DynObj && NULL == m_pGOT) { 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(const Output& pOutput, 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic() 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic = new MipsELFDynamic(*this); 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput, 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const Layout& pLayout, 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* file_format = getOutputFormat(pOutput); 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(file_format->getGOT())) { 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pGOT->emit(pRegion); 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry. 266affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return std::find(m_GlobalGOTSyms.begin(), 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end(); 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitDynamicSymbol - emit dynamic symbol. 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32, 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Output& pOutput, 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol& pSymbol, 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab, 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize, 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx) 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // maintain output's symbol and index map 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(&pSymbol, sym_exist); 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(symtabIdx); 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: check the endian between host and target 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out symbol 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_name = strtabsize; 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_value = pSymbol.value(); 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_size = getSymbolSize(pSymbol); 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_info = getSymbolInfo(pSymbol); 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_other = pSymbol.visibility(); 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_shndx = getSymbolShndx(pSymbol, pLayout); 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out string 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), pSymbol.name()); 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(Output& pOutput, 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory& pSymbols, 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo) 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pOutput.hasMemArea()); 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& hash_sect = file_format->getHashTab(); 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& dyn_sect = file_format->getDynamic(); 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(), 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab_sect.size()); 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(), 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab_sect.size()); 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(), 3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao hash_sect.size()); 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(), 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dyn_sect.size()); 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_name = 0; 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_value = 0; 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_size = 0; 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_info = 0; 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_other = 0; 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_shndx = 0; 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab[0] = '\0'; 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add index 0 symbol into SymIndexMap 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(NULL, sym_exist); 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(0); 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx = 1; 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit of .dynsym, and .dynstr except GOT entries 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (SymbolCategory::iterator symbol = pSymbols.begin(), 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym_end = pSymbols.end(); symbol != sym_end; ++symbol) { 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!isDynamicSymbol(**symbol, pOutput)) 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isGlobalGOTSymbol(**symbol)) 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize, symtabIdx); 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit global GOT 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(), 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_end = m_GlobalGOTSyms.end(); 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol != symbol_end; ++symbol) { 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Make sure this golbal GOT entry is a dynamic symbol. 372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // If not, something is wrong earlier when putting this symbol into 373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // global GOT. 374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!isDynamicSymbol(**symbol, pOutput)) 375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::mips_got_symbol) << (*symbol)->name(); 376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize, symtabIdx); 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Rules: 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. ignore --no-add-needed 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. force count in --no-as-needed 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 3. judge --as-needed 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end(); 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) { 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Input::DynObj == (*input)->type()) { 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --add-needed 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((*input)->attribute()->isAddNeeded()) { 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --no-as-needed 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(*input)->attribute()->isAsNeeded()) { 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), (*input)->name().c_str()); 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*input)->name().size() + 1; 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++dt_need; 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --as-needed 4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if ((*input)->isNeeded()) { 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), (*input)->name().c_str()); 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*input)->name().size() + 1; 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++dt_need; 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // for 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit soname 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Output::DynObj == pOutput.type()) 418affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dynamic().applySoname(strtabsize); 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().applyEntries(pLDInfo, *file_format); 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().emit(dyn_sect, *dyn_region); 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), pOutput.name().c_str()); 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += pOutput.name().size() + 1; 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit hash table 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: this verion only emit SVR4 hash section. 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Please add GNU new hash section 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* word_array = (uint32_t*)hash_region->start(); 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nchain = word_array[1]; 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nbucket = getHashBucketCount(symtabIdx, false); 4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nchain = symtabIdx; 4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* chain = (bucket + nbucket); 4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bzero((void*)bucket, nbucket); 4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao StringHash<ELF> hash_func; 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) { 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef name(strtab + symtab32[sym_idx].st_name); 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t bucket_pos = hash_func(name) % nbucket; 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao chain[sym_idx] = bucket[bucket_pos]; 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bucket[bucket_pos] = sym_idx; 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT() 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn() 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const Output& pOutput, 481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSectHdr, 482affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const MCLDInfo& pInfo) const 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const ELFFileFormat* file_format = getOutputFormat(pOutput); 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getGOT()) 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 493affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput) 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 495cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL != m_pGpDispSymbol) 496cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0); 497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sections. 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory& symbol_list = pLinker.getOutputSymbols(); 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: If the order of common symbols is defined, then sort common symbols 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // std::sort(com_sym, com_end, some kind of order); 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get or create corresponding BSS LDSection 518affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* bss_sect = &pLinker.getOrCreateOutputSectHdr(".bss", 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 522affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 523affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* tbss_sect = &pLinker.getOrCreateOutputSectHdr( 524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".tbss", 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 529affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: .sbss amd .lbss currently unused. 530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* 531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* sbss_sect = &pLinker.getOrCreateOutputSectHdr( 532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".sbss", 533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC | 536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_MIPS_GPREL); 537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* lbss_sect = &pLinker.getOrCreateOutputSectHdr( 539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ".lbss", 540affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDFileFormat::BSS, 541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_NOBITS, 542affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC | 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_MIPS_LOCAL); 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang */ 545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != bss_sect && NULL != tbss_sect); 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 548cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 549cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect); 550cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect); 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t bss_offset = bss_sect->size(); 554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t tbss_offset = tbss_sect->size(); 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all local common symbols 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.localEnd(); 558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 567cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 568cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0)); 569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_offset += pLinker.getLayout().appendFragment(*frag, 573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_sect_data, 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_offset += pLinker.getLayout().appendFragment(*frag, 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_data, 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all global common symbols 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 594cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 595cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0)); 596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_offset += pLinker.getLayout().appendFragment(*frag, 600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_sect_data, 601affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 602affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 603affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 605affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_offset += pLinker.getLayout().appendFragment(*frag, 606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect_data, 607affc150dc44fab1911775a49636d0ce85333b634Zonr Chang (*com_sym)->value()); 608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bss_sect->setSize(bss_offset); 612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang tbss_sect->setSize(tbss_offset); 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_list.changeCommonsToGlobal(); 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::updateAddend(Relocation& pReloc, 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout) const 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Update value keep in addend if we meet a section symbol 622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pReloc.symInfo()->type() == ResolveInfo::Section) { 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.setAddend(pLayout.getOutputOffset( 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *pInputSym.fragRef()) + pReloc.addend()); 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc, 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao updateAddend(pReloc, pInputSym, pLinker.getLayout()); 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Output::DynObj == pOutput.type()) { 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The gold linker does not create an entry in .rel.dyn 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // section if the symbol section flags contains SHF_EXECINSTR. 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. Find the reason of this condition. 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. Check this condition here. 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelDyn) 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createRelDyn(pLinker, pOutput); 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 653affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry (as if it needs an entry). 655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Actually we don't allocate an GOT entry. 656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 657affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createGOT(pLinker, pOutput); 658affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT) 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // For got16 section based relocations, we need to reserve got entries. 693affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->type() == ResolveInfo::Section) { 694affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->reserveLocalEntry(); 695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry 696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveLocalEntry(); 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 703affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry 704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD32: 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 732affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unknown_relocation) << (int)pReloc.type() 733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc, 7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 762affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (symbolNeedsDynRel(*rsym, false, pLDInfo, pOutput, true)) { 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelDyn) 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createRelDyn(pLinker, pOutput); 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 768affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 769affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a global GOT entry (as if it needs an entry). 770affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Actually we don't allocate an GOT entry. 771affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pGOT) 772affc150dc44fab1911775a49636d0ce85333b634Zonr Chang createGOT(pLinker, pOutput); 773affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setGlobal(rsym); 7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT) 7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 7895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveGlobalEntry(); 7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.push_back(rsym->outSymbol()); 792affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a global GOT entry 793affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setGlobal(rsym); 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 798affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::invalid_global_relocation) << (int)pReloc.type() 799affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 8045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 8085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 831affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::dynamic_relocation) << (int)pReloc.type(); 8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 834affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unknown_relocation) << (int)pReloc.type() 835affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput) 8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& got = file_format->getGOT(); 8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got)); 8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 847affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ( m_pGOTSymbol != NULL ) { 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>( 8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput) 8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 877cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get .rel.dyn LDSection and create SectionData 8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 879cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // create SectionData and ARMRelDynSection 8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn = new OutputRelocSection(reldyn, 8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(reldyn), 8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget, 8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const std::string& pTriple) 8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Triple theTriple(pTriple); 8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSDarwin()) { 8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSWindows()) { 8965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new MipsGNULDBackend(); 8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//============================= 9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 9055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeMipsLDBackend() { 9065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 9075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::createMipsLDBackend); 9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 910