MipsLDBackend.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "Mips.h" 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsELFDynamic.h" 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsLDBackend.h" 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsRelocationFactory.h" 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum { 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // The original o32 abi. 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32 = 0x00001000, 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // O32 extended to work on 64 bit architectures. 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O64 = 0x00002000, 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 32 bit mode. 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI32 = 0x00003000, 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 64 bit mode. 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI64 = 0x00004000 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend() 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_pRelocFactory(NULL), 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL), 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol(NULL), 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol(NULL) 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend() 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelocFactory) 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelocFactory; 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGOT) 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pGOT; 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pRelDyn) 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pRelDyn; 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pDynamic) 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pDynamic; 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap) 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Nothing to do because we do not support 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // any MIPS specific sections now. 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(MCLinker& pLinker) 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Nothing to do because we do not support 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // any MIPS specific sections now. 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker) 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, 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // that a .got section is needed. 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT && NULL != m_pGOTSymbol) { 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (rsym == m_pGOTSymbol->resolveInfo()) { 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (rsym->isLocal()) 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput); 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint32_t MipsGNULDBackend::machine() const 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EM_MIPS; 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::OSABI() const 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::ELFOSABI_NONE; 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint8_t MipsGNULDBackend::ABIVersion() const 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::flags() const 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The correct flag's set depend on command line 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // arguments and flags from input .o files. 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EF_MIPS_ARCH_32R2 | 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_NOREORDER | 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_PIC | 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_CPIC | 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32; 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isLittleEndian() const 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Now we support little endian (mipsel) target only. 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int MipsGNULDBackend::bitclass() const 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 32; 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(const Output& pOutput, 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is must. 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pOutput.type() == Output::DynObj && NULL == m_pGOT) { 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(const Output& pOutput, 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker) 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit program headers 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitProgramHdrs(pLinker.getLDInfo().output()); 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic() 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic = new MipsELFDynamic(*this); 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput, 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pInfo, 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(file_format->getGOT())) { 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pGOT->emit(pRegion); 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Unable to emit section `") + 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pSection.name() + 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.\n")); 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isGOTSymbol - return true if the symbol is the GOT entry. 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isGOTSymbol(const LDSymbol& pSymbol) const 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return std::find(m_LocalGOTSyms.begin(), 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LocalGOTSyms.end(), &pSymbol) != m_LocalGOTSyms.end() || 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::find(m_GlobalGOTSyms.begin(), 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end(); 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitDynamicSymbol - emit dynamic symbol. 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32, 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Output& pOutput, 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol& pSymbol, 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab, 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize, 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx) 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // maintain output's symbol and index map 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(&pSymbol, sym_exist); 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(symtabIdx); 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: check the endian between host and target 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out symbol 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_name = strtabsize; 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_value = pSymbol.value(); 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_size = getSymbolSize(pSymbol); 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_info = getSymbolInfo(pSymbol); 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_other = pSymbol.visibility(); 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym32.st_shndx = getSymbolShndx(pSymbol, pLayout); 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out string 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), pSymbol.name()); 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(Output& pOutput, 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory& pSymbols, 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo) 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pOutput.hasMemArea()); 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& hash_sect = file_format->getHashTab(); 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& dyn_sect = file_format->getDynamic(); 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(), 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab_sect.size()); 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(), 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab_sect.size()); 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(), 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao hash_sect.size()); 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(), 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dyn_sect.size()); 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_name = 0; 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_value = 0; 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_size = 0; 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_info = 0; 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_other = 0; 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_shndx = 0; 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab[0] = '\0'; 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add index 0 symbol into SymIndexMap 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(NULL, sym_exist); 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(0); 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx = 1; 3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit of .dynsym, and .dynstr except GOT entries 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (SymbolCategory::iterator symbol = pSymbols.begin(), 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sym_end = pSymbols.end(); symbol != sym_end; ++symbol) { 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!isDynamicSymbol(**symbol, pOutput)) 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (isGOTSymbol(**symbol)) 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize, symtabIdx); 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit global GOT 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(), 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_end = m_GlobalGOTSyms.end(); 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol != symbol_end; ++symbol) { 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab, 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize, symtabIdx); 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Rules: 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. ignore --no-add-needed 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. force count in --no-as-needed 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 3. judge --as-needed 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end(); 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) { 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Input::DynObj == (*input)->type()) { 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --add-needed 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((*input)->attribute()->isAddNeeded()) { 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --no-as-needed 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(*input)->attribute()->isAsNeeded()) { 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), (*input)->name().c_str()); 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*input)->name().size() + 1; 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++dt_need; 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // --as-needed 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if ((*input)->isNeeded()) { 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), (*input)->name().c_str()); 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += (*input)->name().size() + 1; 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++dt_need; 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // for 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit soname 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().applySoname(strtabsize); 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().applyEntries(pLDInfo, *file_format); 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().emit(dyn_sect, *dyn_region); 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((strtab + strtabsize), pOutput.name().c_str()); 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtabsize += pOutput.name().size() + 1; 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit hash table 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: this verion only emit SVR4 hash section. 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Please add GNU new hash section 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* word_array = (uint32_t*)hash_region->start(); 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nchain = word_array[1]; 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nbucket = getHashBucketCount(symtabIdx, false); 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nchain = symtabIdx; 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* chain = (bucket + nbucket); 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bzero((void*)bucket, nbucket); 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao StringHash<ELF> hash_func; 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) { 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef name(strtab + symtab32[sym_idx].st_name); 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t bucket_pos = hash_func(name) % nbucket; 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao chain[sym_idx] = bucket[bucket_pos]; 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bucket[bucket_pos] = sym_idx; 4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT() 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn() 4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const 4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const Output& pOutput, 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSectHdr) const 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getGOT()) 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// If the symbol's reserved field is not zero, MCLinker will call back this 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// function to ask the final value of the symbol 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSymbol == m_pGpDispSymbol) { 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0); 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// sections. 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // SymbolCategory contains all symbols that must emit to the output files. 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We are not like Google gold linker, we don't remember symbols before symbol 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // resolution. All symbols in SymbolCategory are already resolved. Therefore, we 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // don't need to care about some symbols may be changed its category due to symbol 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // resolution. 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory& symbol_list = pLinker.getOutputSymbols(); 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // addralign := max value of all common symbols 4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t addralign = 0x0; 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Due to the visibility, some common symbols may be forcefully local. 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd(); 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((*com_sym)->value() > addralign) 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao addralign = (*com_sym)->value(); 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // global common symbols. 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((*com_sym)->value() > addralign) 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao addralign = (*com_sym)->value(); 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: If the order of common symbols is defined, then sort common symbols 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // com_sym = symbol_list.commonBegin(); 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // std::sort(com_sym, com_end, some kind of order); 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get or create corresponding BSS LDSection 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* bss_sect_hdr = NULL; 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr( 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ".tbss", 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss", 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::BSS, 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_NOBITS, 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC); 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get or create corresponding BSS MCSectionData 5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != bss_sect_hdr); 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr); 5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all common symbols 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t offset = bss_sect_hdr->size(); 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all local common symbols 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.localEnd(); 5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao alignAddress(offset, (*com_sym)->value()); 5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section); 5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset += (*com_sym)->size(); 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all global common symbols 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao alignAddress(offset, (*com_sym)->value()); 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section); 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0)); 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset += (*com_sym)->size(); 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bss_sect_hdr->setSize(offset); 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_list.changeCommonsToGlobal(); 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::updateAddend(Relocation& pReloc, 5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout) const 5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Update value keep in addend if we meet a section symbol 5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pReloc.symInfo()->type() == ResolveInfo::Section) { 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.setAddend(pLayout.getOutputOffset( 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *pInputSym.fragRef()) + pReloc.addend()); 5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc, 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao updateAddend(pReloc, pInputSym, pLinker.getLayout()); 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (Output::DynObj == pOutput.type()) { 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The gold linker does not create an entry in .rel.dyn 5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // section if the symbol section flags contains SHF_EXECINSTR. 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. Find the reason of this condition. 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. Check this condition here. 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelDyn) 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createRelDyn(pLinker, pOutput); 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT) 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveLocalEntry(); 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LocalGOTSyms.push_back(rsym->outSymbol()); 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD32: 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Unknown relocation ") + 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pReloc.type()) + 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("for the local symbol `") + 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.symInfo()->name() + 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.")); 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc, 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pInputSym, 6815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLinker& pLinker, 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const MCLDInfo& pLDInfo, 6835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 6925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 6945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 6955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 6965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 7035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (isSymbolNeedsDynRel(*rsym, pOutput)) { 7055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pRelDyn) 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createRelDyn(pLinker, pOutput); 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn->reserveEntry(*m_pRelocFactory); 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 7105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 7185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 7205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 7215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pGOT) 7225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao createGOT(pLinker, pOutput); 7235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 7255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveGlobalEntry(); 7265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 7275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.push_back(rsym->outSymbol()); 7285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 7315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Relocation ") + 7335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pReloc.type()) + 7345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(" is not defined for the " 7355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "global symbol `") + 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.symInfo()->name() + 7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.")); 7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 7485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 7495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 7505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 7515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 7535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 7545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 7555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 7565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 7575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 7585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 7595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 7605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 7615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Relocation ") + 7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pReloc.type()) + 7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("for the global symbol `") + 7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.symInfo()->name() + 7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("' should only be seen " 7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "by the dynamic linker")); 7755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 7765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 7775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Unknown relocation ") + 7785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pReloc.type()) + 7795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("for the global symbol `") + 7805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pReloc.symInfo()->name() + 7815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine("'.")); 7825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isSymbolNeedsPLT(ResolveInfo& pSym, 7865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) const 7875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return (Output::DynObj == pOutput.type() && 7895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Function == pSym.type() && 7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (pSym.isDyn() || pSym.isUndef())); 7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MipsGNULDBackend::isSymbolNeedsDynRel(ResolveInfo& pSym, 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) const 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.isUndef() && Output::Exec == pOutput.type()) 7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 7985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.isAbsolute()) 7995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(Output::DynObj == pOutput.type()) 8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pSym.isDyn() || pSym.isUndef()) 8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 8045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput) 8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& got = file_format->getGOT(); 8135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got)); 8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ when .got create 8165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( m_pGOTSymbol != NULL ) { 8175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>( 8185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>( 8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0), 8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput) 8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(pOutput); 8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get .rel.dyn LDSection and create MCSectionData 8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create MCSectionData and ARMRelDynSection 8495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn = new OutputRelocSection(reldyn, 8505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pLinker.getOrCreateSectData(reldyn), 8515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8); 8525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFFileFormat* MipsGNULDBackend::getOutputFormat(const Output& pOutput) const 8555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pOutput.type()) { 8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::DynObj: 8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return getDynObjFileFormat(); 8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Exec: 8605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return getExecFileFormat(); 8615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Object: 8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") + 8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(pOutput.type())); 8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget, 8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const std::string& pTriple) 8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Triple theTriple(pTriple); 8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSDarwin()) { 8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (theTriple.isOSWindows()) { 8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return new MipsGNULDBackend(); 8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//============================= 8895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 8905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoextern "C" void LLVMInitializeMipsLDBackend() { 8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::createMipsLDBackend); 8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 895