MipsLDBackend.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
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//===----------------------------------------------------------------------===// 9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "Mips.h" 10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "MipsGNUInfo.h" 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsELFDynamic.h" 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsLDBackend.h" 13d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "MipsRelocator.h" 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h> 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h> 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h> 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoenum { 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // The original o32 abi. 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32 = 0x00001000, 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // O32 extended to work on 64 bit architectures. 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O64 = 0x00002000, 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 32 bit mode. 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI32 = 0x00003000, 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // EABI in 64 bit mode. 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_EABI64 = 0x00004000 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld; 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// MipsGNULDBackend 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 47d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig, 48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao MipsGNUInfo* pInfo) 49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : GNULDBackend(pConfig, pInfo), 50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelocator(NULL), 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL), 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol(NULL), 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol(NULL) 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGNULDBackend::~MipsGNULDBackend() 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pRelocator; 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pGOT; 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder) 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .got 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& got = file_format->getGOT(); 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT = new MipsGOT(got); 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // initialize .rel.dyn 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& reldyn = file_format->getRelDyn(); 78d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn = new OutputRelocSection(pModule, reldyn); 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::initTargetSymbols(FragmentLinker& pLinker) 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::AsRefered, FragmentLinker::Resolve>( 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGpDispSymbol = pLinker.defineSymbol<FragmentLinker::AsRefered, FragmentLinker::Resolve>( 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_gp_disp", 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Section, 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Absolute, 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Default); 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pGpDispSymbol) { 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp); 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaobool MipsGNULDBackend::initRelocator(const FragmentLinker& pLinker) 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (NULL == m_pRelocator) { 116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelocator = new MipsRelocator(*this); 117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelocator->setFragmentLinker(pLinker); 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* MipsGNULDBackend::getRelocator() 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao assert(NULL != m_pRelocator); 125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanRelocation(Relocation& pReloc, 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker, 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule, 131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSection) 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // rsym - The relocation target symbol 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Skip relocation against _gp_disp 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != m_pGpDispSymbol) { 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pReloc.symInfo() == m_pGpDispSymbol->resolveInfo()) 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pReloc.updateAddend(); 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == (pSection.flag() & llvm::ELF::SHF_ALLOC)) 146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We test isLocal or if pInputSym is not a dynamic symbol 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn() 150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Don't put undef symbols into local entries. 15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((rsym->isLocal() || !isDynamicSymbol(*rsym) || 152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang !rsym->isDyn()) && !rsym->isUndef()) 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao scanLocalReloc(pReloc, pLinker); 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao scanGlobalReloc(pReloc, pLinker); 15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // check if we shoule issue undefined reference for the relocation target 15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // symbol 159d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull()) 16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::undefined_reference) << rsym->name(); 16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((rsym->reserved() & ReserveRel) != 0x0) { 16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set hasTextRelSection if needed 16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao checkAndSetHasTextRel(pSection); 16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGNULDBackend::flags() const 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The correct flag's set depend on command line 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // arguments and flags from input .o files. 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::EF_MIPS_ARCH_32R2 | 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_NOREORDER | 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_PIC | 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::EF_MIPS_CPIC | 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao E_MIPS_ABI_O32; 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 179affc150dc44fab1911775a49636d0ce85333b634Zonr Changuint64_t MipsGNULDBackend::defaultTextSegmentAddr() const 180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return 0x80000; 182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::abiPageSize() const 185cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (config().options().maxPageSize() > 0) 18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return config().options().maxPageSize(); 188cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao else 189cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return static_cast<uint64_t>(0x10000); 190cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 191cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doPreLayout(FragmentLinker& pLinker) 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .got size 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is must. 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->hasGOT1() || 19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao NULL != m_pGOTSymbol) { 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->finalizeSectionSize(); 20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao defineGOTSymbol(pLinker); 20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 204d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.dyn size 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pRelDyn->empty()) 207d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getRelDyn().setSize( 208d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn->numOfRelocs() * getRelEntrySize()); 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doPostLayout(Module& pModule, 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker) 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic() 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == m_pDynamic) 221d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pDynamic = new MipsELFDynamic(*this, config()); 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 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 Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert( NULL != m_pDynamic); 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection, 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSection == &(file_format->getGOT())) { 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = m_pGOT->emit(pRegion); 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry. 253affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return std::find(m_GlobalGOTSyms.begin(), 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end(); 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sizeNamePools - compute the size of regular name pools 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// In ELF executable files, regular name pools are .symtab, .strtab, 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// .dynsym, .dynstr, .hash and .shstrtab. 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::sizeNamePools(const Module& pModule, bool pIsStaticLink) 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // number of entries in symbol tables starts from 1 to hold the special entry 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21. 26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t symtab = 1; 26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t dynsym = pIsStaticLink ? 0 : 1; 26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // size of string tables starts from 1 to hold the null character in their 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // first byte 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t strtab = 1; 27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t dynstr = pIsStaticLink ? 0 : 1; 27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t shstrtab = 1; 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t hash = 0; 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 277d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // number of local symbol in the .dynsym 278d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao size_t dynsym_local_cnt = 0; 279d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// compute the size of .symtab, .dynsym and .strtab 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symbol; 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const Module::SymbolTable& symbols = pModule.getSymbolTable(); 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t str_size = 0; 28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute the size of symbols in Local and File category 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symEnd = symbols.localEnd(); 28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) { 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao str_size = (*symbol)->nameSize() + 1; 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink && isDynamicSymbol(**symbol)) { 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dynsym; 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += str_size; 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtab; 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab += str_size; 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute the size of symbols in TLS category 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = symbols.tlsEnd(); 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) { 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao str_size = (*symbol)->nameSize() + 1; 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink) { 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dynsym; 30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += str_size; 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtab; 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab += str_size; 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 311d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynsym_local_cnt = dynsym; 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute the size of the reset of symbols 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = pModule.sym_end(); 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) { 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao str_size = (*symbol)->nameSize() + 1; 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink && isDynamicSymbol(**symbol)) { 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dynsym; 31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += str_size; 32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtab; 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab += str_size; 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch(config().codeGenType()) { 32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute size of .dynstr and .hash 33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::DynObj: { 33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // soname 33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink) 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += pModule.name().size() + 1; 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /** fall through **/ 33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Exec: { 33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // add DT_NEED strings into .dynstr and .dynamic 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Rules: 33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. ignore --no-add-needed 34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. force count in --no-as-needed 34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 3. judge --as-needed 34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pIsStaticLink) { 34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --add-needed 34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*lib)->attribute()->isAddNeeded()) { 34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --no-as-needed 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!(*lib)->attribute()->isAsNeeded()) { 34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += (*lib)->name().size() + 1; 35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynamic().reserveNeedEntry(); 35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --as-needed 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*lib)->isNeeded()) { 35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynstr += (*lib)->name().size() + 1; 35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dynamic().reserveNeedEntry(); 35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // compute .hash 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Both Elf32_Word and Elf64_Word are 4 bytes 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hash = (2 + getHashBucketCount(dynsym, false) + dynsym) * 36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sizeof(llvm::ELF::Elf32_Word); 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set size 367d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym)); 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym)); 37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getDynStrTab().setSize(dynstr); 37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getHashTab().setSize(hash); 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 374d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // set .dynsym sh_info to one greater than the symbol table 375d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // index of the last local symbol 376d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getDynSymTab().setInfo(dynsym_local_cnt); 37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /* fall through */ 37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LinkerConfig::Object: { 380d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (config().targets().is32Bits()) 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym)); 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym)); 38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getStrTab().setSize(strtab); 385d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 386d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // set .symtab sh_info to one greater than the symbol table 387d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // index of the last local symbol 388d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getSymTab().setInfo(symbols.numOfLocals() + 1); 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: { 39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::fatal_illegal_codegen_type) << pModule.name(); 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of switch 39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @} 39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// reserve fixed entries in the .dynamic section. 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkerConfig::Exec == config().codeGenType()) { 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Because some entries in .dynamic section need information of .dynsym, 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // entries until we get the size of the sections mentioned above 405d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynamic().reserveEntries(*file_format); 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getDynamic().setSize(dynamic().numOfBytes()); 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @} 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// compute the size of .shstrtab section. 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @{ 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_iterator sect, sectEnd = pModule.end(); 41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sect = pModule.begin(); sect != sectEnd; ++sect) { 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // StackNote sections will always be in output! 41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 != (*sect)->size() || LDFileFormat::StackNote == (*sect)->kind()) { 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shstrtab += ((*sect)->name().size() + 1); 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shstrtab += (strlen(".shstrtab") + 1); 42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_format->getShStrTab().setSize(shstrtab); 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @} 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// emitSymbol32 - emit an ELF32 symbol 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym, 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx) 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: check the endian between host and target 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out symbol 43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != pSymbol.type() || 43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pSymbol == m_pGpDispSymbol) { 43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = pStrtabsize; 43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((pStrtab + pStrtabsize), pSymbol.name()); 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_name = 0; 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_value = pSymbol.value(); 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_size = getSymbolSize(pSymbol); 44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_info = getSymbolInfo(pSymbol); 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_other = pSymbol.visibility(); 44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pSym.st_shndx = getSymbolShndx(pSymbol); 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the size of these tables should be computed before layout 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// layout should computes the start offset of these tables 45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::emitDynNamePools(const Module& pModule, 45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryArea& pOutput) 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!file_format->hasDynSymTab() || 45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynStrTab() || 45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasHashTab() || 45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao !file_format->hasDynamic()) 46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& symtab_sect = file_format->getDynSymTab(); 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& strtab_sect = file_format->getDynStrTab(); 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& hash_sect = file_format->getHashTab(); 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& dyn_sect = file_format->getDynamic(); 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(), 46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtab_sect.size()); 46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(), 47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab_sect.size()); 47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* hash_region = pOutput.request(hash_sect.offset(), 47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hash_sect.size()); 47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* dyn_region = pOutput.request(dyn_sect.offset(), 47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dyn_sect.size()); 47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up symtab_region 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::Elf32_Sym* symtab32 = NULL; 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start(); 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_name = 0; 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_value = 0; 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_size = 0; 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_info = 0; 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_other = 0; 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symtab32[0].st_shndx = 0; 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up strtab_region 4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = (char*)strtab_region->start(); 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strtab[0] = '\0'; 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool sym_exist = false; 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType::entry_type* entry = 0; 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add index 0 symbol into SymIndexMap 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = m_pSymIndexMap->insert(NULL, sym_exist); 4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(0); 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symtabIdx = 1; 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t strtabsize = 1; 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit of .dynsym, and .dynstr except GOT entries 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symbol; 50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const Module::SymbolTable& symbols = pModule.getSymbolTable(); 50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit symbol in File and Local category if it's dynamic symbol 50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_sym_iterator symEnd = symbols.localEnd(); 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) { 50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isDynamicSymbol(**symbol)) 50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isGlobalGOTSymbol(**symbol)) 51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // maintain output's symbol and index map 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(symtabIdx); 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sum up counters 52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtabIdx; 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit symbols in TLS category, all symbols in TLS category shold be emitited 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // directly, except GOT entries 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = symbols.tlsEnd(); 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) { 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (isGlobalGOTSymbol(**symbol)) 53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // maintain output's symbol and index map 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(symtabIdx); 53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sum up counters 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++symtabIdx; 54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // emit the reset of the symbols if the symbol is dynamic symbol 54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symEnd = pModule.sym_end(); 54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) { 54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isDynamicSymbol(**symbol)) 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isGlobalGOTSymbol(**symbol)) 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao continue; 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // maintain output's symbol and index map 55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(symtabIdx); 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 56122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol) 56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit global GOT 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(), 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_end = m_GlobalGOTSyms.end(); 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol != symbol_end; ++symbol) { 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Make sure this golbal GOT entry is a dynamic symbol. 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // If not, something is wrong earlier when putting this symbol into 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // global GOT. 57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isDynamicSymbol(**symbol)) 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::mips_got_symbol) << (*symbol)->name(); 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 57622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize, 57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao symtabIdx); 57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // maintain output's symbol and index map 57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry = m_pSymIndexMap->insert(*symbol, sym_exist); 58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao entry->setValue(symtabIdx); 5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // sum up counters 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++symtabIdx; 58422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section != (*symbol)->type()) 58522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*symbol)->nameSize() + 1; 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit DT_NEED 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // add DT_NEED strings into .dynstr 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Rules: 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. ignore --no-add-needed 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. force count in --no-as-needed 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 3. judge --as-needed 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynamic::iterator dt_need = dynamic().needBegin(); 59522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::const_lib_iterator lib, libEnd = pModule.lib_end(); 59622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (lib = pModule.lib_begin(); lib != libEnd; ++lib) { 59722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --add-needed 59822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*lib)->attribute()->isAddNeeded()) { 59922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --no-as-needed 60022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!(*lib)->attribute()->isAsNeeded()) { 60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((strtab + strtabsize), (*lib)->name().c_str()); 60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*lib)->name().size() + 1; 60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dt_need; 60522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 60622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // --as-needed 60722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if ((*lib)->isNeeded()) { 60822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((strtab + strtabsize), (*lib)->name().c_str()); 60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize); 61022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += (*lib)->name().size() + 1; 61122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++dt_need; 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // for 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit soname 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize value of ELF .dynamic section 61822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) 619affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dynamic().applySoname(strtabsize); 620d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao dynamic().applyEntries(*file_format); 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dynamic().emit(dyn_sect, *dyn_region); 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 62322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strcpy((strtab + strtabsize), pModule.name().c_str()); 62422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtabsize += pModule.name().size() + 1; 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit hash table 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: this verion only emit SVR4 hash section. 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Please add GNU new hash section 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // both 32 and 64 bits hash table use 32-bit entry 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up hash_region 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* word_array = (uint32_t*)hash_region->start(); 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nbucket = word_array[0]; 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t& nchain = word_array[1]; 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nbucket = getHashBucketCount(symtabIdx, false); 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao nchain = symtabIdx; 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* bucket = (word_array + 2); 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* chain = (bucket + nbucket); 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // initialize bucket 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bzero((void*)bucket, nbucket); 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao StringHash<ELF> hash_func; 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) { 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef name(strtab + symtab32[sym_idx].st_name); 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t bucket_pos = hash_func(name) % nbucket; 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao chain[sym_idx] = bucket[bucket_pos]; 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bucket[bucket_pos] = sym_idx; 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT() 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn() 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 6775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 6785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 68122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 68322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (&pSectHdr == &file_format->getGOT()) 6865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 6875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 6895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 69222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::finalizeTargetSymbols(FragmentLinker& pLinker) 6935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 694cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL != m_pGpDispSymbol) 69522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGpDispSymbol->setValue(m_pGOT->addr() + 0x7FF0); 696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 6975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding 70022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is called at pre-layout stage. 7015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214 7025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol 70322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) 7045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 70522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymbolCategory& symbol_list = pModule.getSymbolTable(); 7065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) 7085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 7095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 710affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 7115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: If the order of common symbols is defined, then sort common symbols 7135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // std::sort(com_sym, com_end, some kind of order); 7145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 71522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get corresponding BSS LDSection 71622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 71722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& bss_sect = file_format->getBSS(); 71822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& tbss_sect = file_format->getTBSS(); 7195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 720cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 72122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_sect_data = NULL; 72222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect.hasSectionData()) 72322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = bss_sect.getSectionData(); 72422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 72522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 72622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 72722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* tbss_sect_data = NULL; 72822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (tbss_sect.hasSectionData()) 72922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = tbss_sect.getSectionData(); 73022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 73122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 7325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 733affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 73422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t bss_offset = bss_sect.size(); 73522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tbss_offset = tbss_sect.size(); 7365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all local common symbols 7385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.localEnd(); 739affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 7405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 7415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 7425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 7435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 7445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 7455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 7465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 7475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 748cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 74922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 750affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 751affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 752affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 75322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 75422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 75522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 756affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 757affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 758affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 75922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 76022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 76122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 762affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 7635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all global common symbols 7675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 7685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 7695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 7705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 7715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 7725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 7735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 7745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 775cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 77622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 777affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 778affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 779affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 78022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 78122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 78222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 783affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 784affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 785affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 78622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 78722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 78822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 789affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 7905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 79222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect.setSize(bss_offset); 79322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect.setSize(tbss_offset); 7945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_list.changeCommonsToGlobal(); 7955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 7965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanLocalReloc(Relocation& pReloc, 79922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker) 8005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 8025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 8045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 8055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 8065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 80822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType()) { 8095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: (simon) The gold linker does not create an entry in .rel.dyn 8105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // section if the symbol section flags contains SHF_EXECINSTR. 8115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 1. Find the reason of this condition. 8125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // 2. Check this condition here. 813d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn->reserveEntry(); 8145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 815affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 816affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry (as if it needs an entry). 817affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Actually we don't allocate an GOT entry. 818affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 8195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 8225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 8235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 8245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 8255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 8265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 8275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 8285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 8295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 8305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 8315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 8325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 8335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 8345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 8355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 8365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 8375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 8385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 8395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 8405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 8415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 8425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 8435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 8445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 8455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 8465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 8485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 849affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // For got16 section based relocations, we need to reserve got entries. 850affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (rsym->type() == ResolveInfo::Section) { 851affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->reserveLocalEntry(); 852affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry 853affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 854affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 855affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 856affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 8575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 8585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveLocalEntry(); 8595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 860affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a local GOT entry 861affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setLocal(rsym); 8625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 8655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 8665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 8675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 8695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 8705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 8715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 8725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 8735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD32: 8755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 8765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 8775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 8785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 8795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 8805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 8815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 8825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 8835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 8845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 8855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 8865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 8875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 8885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 889affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unknown_relocation) << (int)pReloc.type() 890affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 8915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 8925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 8935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc, 89522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker) 8965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo* rsym = pReloc.symInfo(); 8985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pReloc.type()){ 9005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_NONE: 9015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_A: 9025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_INSERT_B: 9035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_DELETE: 9045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPMOD64: 9055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL64: 9065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL16: 9075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_ADD_IMMEDIATE: 9085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PJUMP: 9095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_RELGOT: 9105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL64: 9115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_32: 9135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_64: 9145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HI16: 9155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LO16: 91622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (symbolNeedsDynRel(pLinker, *rsym, false, true)) { 917d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn->reserveEntry(); 9185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveRel); 919affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 920affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a global GOT entry (as if it needs an entry). 921affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Actually we don't allocate an GOT entry. 922affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setGlobal(rsym); 9235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 9245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT16: 9265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL16: 9275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_DISP: 9285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_HI16: 9295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_HI16: 9305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_LO16: 9315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_CALL_LO16: 9325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_PAGE: 9335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GOT_OFST: 9345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) { 9355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT->reserveGlobalEntry(); 9365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rsym->setReserved(rsym->reserved() | ReserveGot); 9375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GlobalGOTSyms.push_back(rsym->outSymbol()); 938affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Remeber this rsym is a global GOT entry 939affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pGOT->setGlobal(rsym); 9405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 9415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_LITERAL: 9435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL32: 944affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::invalid_global_relocation) << (int)pReloc.type() 945affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 9465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GPREL16: 9485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_26: 9505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_PC16: 9515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_16: 9535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT5: 9545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SHIFT6: 9555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SUB: 9565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHER: 9575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_HIGHEST: 9585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_SCN_DISP: 9595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL32: 9615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GD: 9625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_LDM: 9635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_HI16: 9645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_DTPREL_LO16: 9655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_GOTTPREL: 9665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL32: 9675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_HI16: 9685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_TLS_TPREL_LO16: 9695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_REL32: 9715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JALR: 9735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_COPY: 9755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_GLOB_DAT: 9765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case llvm::ELF::R_MIPS_JUMP_SLOT: 977affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::dynamic_relocation) << (int)pReloc.type(); 9785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 9795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 980affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unknown_relocation) << (int)pReloc.type() 981affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pReloc.symInfo()->name(); 9825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 9835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 9845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 98522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::defineGOTSymbol(FragmentLinker& pLinker) 9865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 98722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ 988affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ( m_pGOTSymbol != NULL ) { 98922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Unresolve>( 9905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 9915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 9925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 9935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 9945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 9955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 99722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOT->begin()), 0x0), 9985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 9995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 100122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>( 10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 10045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 10075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 10085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 100922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOT->begin()), 0x0), 10105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 10115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 10125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 101422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the 101522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments 101622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid MipsGNULDBackend::doCreateProgramHdrs(Module& pModule, 101722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const FragmentLinker& pLinker) 10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 101922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO 10205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 10235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 10245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget, 102622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LinkerConfig& pConfig) 10275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1028d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSDarwin()) { 10295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 10305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1031d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().triple().isOSWindows()) { 10325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 10335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1034d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return new MipsGNULDBackend(pConfig, new MipsGNUInfo(pConfig.targets().triple())); 10355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 103722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 10385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 103922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 104022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeMipsLDBackend() { 10415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Register the linker backend 10425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 104322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createMipsLDBackend); 10445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 104522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1046