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" 1287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include "MipsLA25Stub.h" 13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include "MipsLDBackend.h" 14d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include "MipsRelocator.h" 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Casting.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 1987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Host.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/BranchIslandFactory.h> 2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/LDContext.h> 2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/StubFactory.h> 2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFFileFormat.h> 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h> 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 32affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/TargetRegistry.h> 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/OutputRelocSection.h> 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld; 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// MipsGNULDBackend 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 42d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig, 43d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao MipsGNUInfo* pInfo) 44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : GNULDBackend(pConfig, pInfo), 45d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelocator(NULL), 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOT(NULL), 4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT(NULL), 4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT(NULL), 4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pInfo(*pInfo), 5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelPlt(NULL), 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pRelDyn(NULL), 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pDynamic(NULL), 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pGOTSymbol(NULL), 5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLTSymbol(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; 6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pPLT; 6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pRelPlt; 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::needsLA25Stub(Relocation::Type pType, 6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const mcld::ResolveInfo* pSym) 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().isCodeIndep()) 7287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::R_MIPS_26 != pType) 7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pSym->isLocal()) 7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::addNonPICBranchSym(ResolveInfo* rsym) 8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_HasNonPICBranchSyms.insert(rsym); 8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::hasNonPICBranch(const ResolveInfo* rsym) const 8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_HasNonPICBranchSyms.count(rsym); 9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::initTargetSections(Module& pModule, 9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ObjectBuilder& pBuilder) 9587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 9687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object == config().codeGenType()) 9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 9887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFFileFormat* file_format = getOutputFormat(); 10087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 10187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .rel.plt 10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& relplt = file_format->getRelPlt(); 10387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelPlt = new OutputRelocSection(pModule, relplt); 10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 10587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .rel.dyn 10687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& reldyn = file_format->getRelDyn(); 10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelDyn = new OutputRelocSection(pModule, reldyn); 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid MipsGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Define the symbol _PROCEDURE_LINKAGE_TABLE_ if there is a symbol with the 12587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // same name in input 12687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLTSymbol = 12787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 12887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines "_PROCEDURE_LINKAGE_TABLE_", 12987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Object, 13087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Define, 13187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Local, 13287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x0, // size 13387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x0, // value 13487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FragmentRef::Null(), // FragRef 13587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Hidden); 13687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGpDispSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_gp_disp", 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Section, 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Absolute, 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Null(), // FragRef 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Default); 146a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>( 147a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines "_gp", 148a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines ResolveInfo::NoType, 149a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines ResolveInfo::Define, 150a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines ResolveInfo::Absolute, 151a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 0x0, // size 152a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 0x0, // value 153a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines FragmentRef::Null(), // FragRef 154a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines ResolveInfo::Default); 155a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines} 156a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 157a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesconst Relocator* MipsGNULDBackend::getRelocator() const 158a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines{ 159a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines assert(NULL != m_pRelocator); 160a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines return m_pRelocator; 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 163d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocator* MipsGNULDBackend::getRelocator() 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 165d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao assert(NULL != m_pRelocator); 166d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid MipsGNULDBackend::doPreLayout(IRBuilder& pBuilder) 170cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeStatic() && NULL == m_pDynamic) 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new MipsELFDynamic(*this, config()); 174cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .got size 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is must. 17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::DynObj == config().codeGenType() || 17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->hasGOT1() || 18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao NULL != m_pGOTSymbol) { 181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOT->finalizeScanning(*m_pRelDyn); 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->finalizeSectionSize(); 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder); 18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 18787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_pGOTPLT->hasGOT1()) { 18887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT->finalizeSectionSize(); 18987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 19087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines defineGOTPLTSymbol(pBuilder); 19187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 19287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 19387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_pPLT->hasPLT1()) 19487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT->finalizeSectionSize(); 19587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 196d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 19787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set .rel.plt size 19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_pRelPlt->empty()) { 20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(!config().isCodeStatic() && 20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines "static linkage should not result in a dynamic relocation section"); 20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines file_format->getRelPlt().setSize( 20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelPlt->numOfRelocs() * getRelEntrySize()); 20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.dyn size 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelDyn->empty()) { 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(!config().isCodeStatic() && 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines "static linkage should not result in a dynamic relocation section"); 210d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao file_format->getRelDyn().setSize( 211d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pRelDyn->numOfRelocs() * getRelEntrySize()); 2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid MipsGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const ELFFileFormat *format = getOutputFormat(); 21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (format->hasGOTPLT()) { 22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(m_pGOTPLT && "doPostLayout failed, m_pGOTPLT is NULL!"); 22287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT->applyAllGOTPLT(m_pPLT->addr()); 22387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 22487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (format->hasPLT()) { 22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(m_pPLT && "doPostLayout failed, m_pPLT is NULL!"); 22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT->applyAllPLT(*m_pGOTPLT); 22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 22987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pInfo.setABIVersion(m_pPLT && m_pPLT->hasPLT1() ? 1 : 0); 23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FIXME: (simon) We need to iterate all input sections 23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // check that flags are consistent and merge them properly. 23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t picFlags = llvm::ELF::EF_MIPS_CPIC; 23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().targets().triple().isArch64Bit()) { 23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines picFlags |= llvm::ELF::EF_MIPS_PIC; 23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::DynObj == config().codeGenType()) 24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines picFlags |= llvm::ELF::EF_MIPS_PIC; 24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pInfo.setPICFlags(picFlags); 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsELFDynamic& MipsGNULDBackend::dynamic() 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsELFDynamic& MipsGNULDBackend::dynamic() const 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection, 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { 27087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_pGOT->emit(pRegion); 27187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 27387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { 27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_pPLT->emit(pRegion); 27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 27687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 27787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) { 27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_pGOTPLT->emit(pRegion); 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::unrecognized_output_sectoin) 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pSection.name() 283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "mclinker@googlegroups.com"; 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 287f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 289f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ResolveInfo::Section != pSym.type() || 290f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGpDispSymbol == &pSym; 291f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 293f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace { 294f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines struct DynsymGOTCompare 295f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { 296f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const MipsGOT& m_pGOT; 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 298f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines DynsymGOTCompare(const MipsGOT& pGOT) 299f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines : m_pGOT(pGOT) 300f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 303f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool operator()(const LDSymbol* X, const LDSymbol* Y) const 304f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { 305f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_pGOT.dynSymOrderCompare(X, Y); 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 307f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines }; 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 310f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGNULDBackend::orderSymbolTable(Module& pModule) 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 312f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (GeneralOptions::GNU == config().options().getHashStyle() || 313f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GeneralOptions::Both == config().options().getHashStyle()) { 314f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // The MIPS ABI and .gnu.hash require .dynsym to be sorted 315f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // in different ways. The MIPS ABI requires a mapping between 316f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // the GOT and the symbol table. At the same time .gnu.hash 317f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // needs symbols to be grouped by hash code. 318f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::errs() << ".gnu.hash is incompatible with the MIPS ABI\n"; 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 321f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 323f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(), 324f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines DynsymGOTCompare(*m_pGOT)); 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace llvm { 32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace ELF { 32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// SHT_MIPS_OPTIONS section's block descriptor. 33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstruct Elf_Options { 33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned char kind; // Determines interpretation of variable 33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // part of descriptor. See ODK_xxx enumeration. 33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned char size; // Byte size of descriptor, including this header. 33487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf64_Half section; // Section header index of section affected, 33587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // or 0 for global options. 33687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf64_Word info; // Kind-specific information. 33787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 33887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 33987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Type of SHT_MIPS_OPTIONS section's block. 34087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesenum { 34187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_NULL = 0, // Undefined. 34287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_REGINFO = 1, // Register usage and GP value. 34387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_EXCEPTIONS = 2, // Exception processing information. 34487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_PAD = 3, // Section padding information. 34587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_HWPATCH = 4, // Hardware workarounds performed. 34687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_FILL = 5, // Fill value used by the linker. 34787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_TAGS = 6, // Reserved space for desktop tools. 34887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_HWAND = 7, // Hardware workarounds, AND bits when merging. 34987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_HWOR = 8, // Hardware workarounds, OR bits when merging. 35087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_GP_GROUP = 9, // GP group to use for text/data sections. 35187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ODK_IDENT = 10 // ID information. 35287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 35387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 35487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 32 bit ABI. 35587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstruct Elf32_RegInfo { 35687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf32_Word ri_gprmask; // Mask of general purpose registers used. 35787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used. 35887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf32_Addr ri_gp_value; // GP register value for this object file. 35987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 36087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 36187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 64 bit ABI. 36287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstruct Elf64_RegInfo { 36387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf32_Word ri_gprmask; // Mask of general purpose registers used. 36487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf32_Word ri_pad; // Padding. 36587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used. 36687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Elf64_Addr ri_gp_value; // GP register value for this object file. 36787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 36887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 36987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 37087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 37187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 37287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readSection(Input& pInput, SectionData& pSD) 37387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 37487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef name(pSD.getSection().name()); 37587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 37687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (name.startswith(".sdata")) { 37787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t offset = pInput.fileOffset() + pSD.getSection().offset(); 37887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t size = pSD.getSection().size(); 37987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 38087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 38187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 38287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 38387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 38487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 38587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pSD.getSection().type() == llvm::ELF::SHT_MIPS_OPTIONS) { 38687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 38787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t size = pSD.getSection().size(); 38887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 38987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef region = pInput.memArea()->request(offset, size); 39087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (region.size() > 0) { 39187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf_Options* optb = 39287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin()); 39387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf_Options* opte = 39487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin() + size); 39587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 39687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (const llvm::ELF::Elf_Options* opt = optb; opt < opte; opt += opt->size) { 39787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (opt->kind) { 39887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: 39987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Nothing to do. 40087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 40187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case llvm::ELF::ODK_REGINFO: 40287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().targets().triple().isArch32Bit()) { 40387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf32_RegInfo* reg = 40487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reinterpret_cast<const llvm::ELF::Elf32_RegInfo*>(opt + 1); 40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GP0Map[&pInput] = reg->ri_gp_value; 40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 40787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 40887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf64_RegInfo* reg = 40987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reinterpret_cast<const llvm::ELF::Elf64_RegInfo*>(opt + 1); 41087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GP0Map[&pInput] = reg->ri_gp_value; 41187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 41287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 41387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 41487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 41587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 41687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 41787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 41887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 41987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 42087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return GNULDBackend::readSection(pInput, pSD); 42187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 42287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT& MipsGNULDBackend::getGOT() 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst MipsGOT& MipsGNULDBackend::getGOT() const 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pGOT); 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 43587f34658dec9097d987d254a990ea7f311bfc95fStephen HinesMipsPLT& MipsGNULDBackend::getPLT() 43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 43787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != m_pPLT); 43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pPLT; 43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesconst MipsPLT& MipsGNULDBackend::getPLT() const 44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 44387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != m_pPLT); 44487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pPLT; 44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 44787f34658dec9097d987d254a990ea7f311bfc95fStephen HinesMipsGOTPLT& MipsGNULDBackend::getGOTPLT() 44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != m_pGOTPLT); 45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pGOTPLT; 45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesconst MipsGOTPLT& MipsGNULDBackend::getGOTPLT() const 45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != m_pGOTPLT); 45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pGOTPLT; 45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 45987f34658dec9097d987d254a990ea7f311bfc95fStephen HinesOutputRelocSection& MipsGNULDBackend::getRelPLT() 46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != m_pRelPlt); 46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pRelPlt; 46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesconst OutputRelocSection& MipsGNULDBackend::getRelPLT() const 46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != m_pRelPlt); 46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pRelPlt; 46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoOutputRelocSection& MipsGNULDBackend::getRelDyn() 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pRelDyn); 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaounsigned int 48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 48887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) 48987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return SHO_DATA; 49087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 49187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 49487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 49587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return SHO_PLT; 49687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 5016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool MipsGNULDBackend::finalizeTargetSymbols() 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 503cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL != m_pGpDispSymbol) 504f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGpDispSymbol->setValue(m_pGOT->getGPDispAddress()); 505f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 506affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is called at pre-layout stage. 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @refer Google gold linker: common.cc: 214 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol 51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymbolCategory& symbol_list = pModule.getSymbolTable(); 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (symbol_list.emptyCommons() && symbol_list.emptyFiles() && 5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symbol_list.emptyLocals() && symbol_list.emptyLocalDyns()) 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 521affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: If the order of common symbols is defined, then sort common symbols 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // std::sort(com_sym, com_end, some kind of order); 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get corresponding BSS LDSection 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& bss_sect = file_format->getBSS(); 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& tbss_sect = file_format->getTBSS(); 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 531cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_sect_data = NULL; 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect.hasSectionData()) 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = bss_sect.getSectionData(); 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* tbss_sect_data = NULL; 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (tbss_sect.hasSectionData()) 54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = tbss_sect.getSectionData(); 54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t bss_offset = bss_sect.size(); 54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tbss_offset = tbss_sect.size(); 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all local common symbols 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.localEnd(); 550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 559cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 56322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 56422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 56522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 566551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 56787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 57122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 574551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 57587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all global common symbols 5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 589cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 59322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_offset += ObjectBuilder::AppendFragment(*frag, 59422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *tbss_sect_data, 59522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 596551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 59787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: how to identify small and large common symbols? 600affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_offset += ObjectBuilder::AppendFragment(*frag, 60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *bss_sect_data, 60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*com_sym)->value()); 604551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 60587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 606affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect.setSize(bss_offset); 61022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect.setSize(tbss_offset); 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_list.changeCommonsToGlobal(); 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesuint64_t MipsGNULDBackend::getGP0(const Input& pInput) const 61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 61787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_GP0Map.lookup(&pInput); 61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 61987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 622f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // If we do not reserve any GOT entries, we do not need to re-define GOT 623f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // symbol. 624f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pGOT->hasGOT1()) 625f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return; 626f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 62722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ 628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ( m_pGOTSymbol != NULL ) { 6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 63622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOT->begin()), 0x0), 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "_GLOBAL_OFFSET_TABLE_", 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Object, 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Define, 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Local, 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // size 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0, // value 64722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef::Create(*(m_pGOT->begin()), 0x0), 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Hidden); 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 65287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder) 65387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 65487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // define symbol _PROCEDURE_LINKAGE_TABLE_ 65587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ( m_pPLTSymbol != NULL ) { 65687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 65787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines "_PROCEDURE_LINKAGE_TABLE_", 65887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Object, 65987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Define, 66087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Local, 66187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x0, // size 66287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x0, // value 66387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FragmentRef::Create(*(m_pPLT->begin()), 0x0), 66487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Hidden); 66587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 66687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 66787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 66887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines "_PROCEDURE_LINKAGE_TABLE_", 66987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Object, 67087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Define, 67187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Local, 67287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x0, // size 67387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 0x0, // value 67487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FragmentRef::Create(*(m_pPLT->begin()), 0x0), 67587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ResolveInfo::Hidden); 67687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 67787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 67887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 67922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the 68022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments 6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid MipsGNULDBackend::doCreateProgramHdrs(Module& pModule) 6825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 68322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO 6845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 68687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel) 68787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 68887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t sym_value = 0x0; 68987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 69087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSymbol* symbol = pRel.symInfo()->outSymbol(); 69187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (symbol->hasFragRef()) { 69287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t value = symbol->fragRef()->getOutputOffset(); 69387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); 69487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sym_value = addr + value; 69587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 69687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 69787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Stub* stub = 69887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getStubFactory()->create(pRel, sym_value, pBuilder, *getBRIslandFactory()); 69987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 70087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (NULL == stub) 70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 70287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 70387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != stub->symInfo()); 70487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // increase the size of .symtab and .strtab 70587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& symtab = getOutputFormat()->getSymTab(); 70687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& strtab = getOutputFormat()->getStrTab(); 70787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 70887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 70987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 71087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 71187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 71287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 71387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, 71487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool& pFinished) 71587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 71687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 71787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 71887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool isRelaxed = false; 71987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 72087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (Module::obj_iterator input = pModule.obj_begin(); 72187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines input != pModule.obj_end(); ++input) { 72287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDContext* context = (*input)->context(); 72387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 72487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (LDContext::sect_iterator rs = context->relocSectBegin(); 72587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines rs != context->relocSectEnd(); ++rs) { 72687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* sec = *rs; 72787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 72887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData()) 72987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 73087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 73187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (RelocData::iterator reloc = sec->getRelocData()->begin(); 73287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines reloc != sec->getRelocData()->end(); ++reloc) { 73387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::R_MIPS_26 != reloc->type()) 73487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 73587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 73687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc))) 73787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines isRelaxed = true; 73887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 73987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 74087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 74187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 74287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData* textData = getOutputFormat()->getText().getSectionData(); 74387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 74487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // find the first fragment w/ invalid offset due to stub insertion 74587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* invalid = NULL; 74687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pFinished = true; 74787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(), 74887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ie = getBRIslandFactory()->end(); 74987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ii != ie; ++ii) 75087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines { 75187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines BranchIsland& island = *ii; 75287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (island.end() == textData->end()) 75387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 75487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 75587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* exit = island.end(); 75687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((island.offset() + island.size()) > exit->getOffset()) { 75787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = exit; 75887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pFinished = false; 75987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 76087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 76187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 76287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 76387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // reset the offset of invalid fragments 76487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines while (NULL != invalid) { 76587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid->setOffset(invalid->getPrevNode()->getOffset() + 76687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid->getPrevNode()->size()); 76787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines invalid = invalid->getNextNode(); 76887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 76987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // reset the size of .text 77187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (isRelaxed) 77287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getOutputFormat()->getText().setSize(textData->back().getOffset() + 77387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines textData->back().size()); 77487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return isRelaxed; 77687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 77787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::initTargetStubs() 77987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 78087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (NULL == getStubFactory()) 78187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 78287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 78387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getStubFactory()->addPrototype(new MipsLA25Stub(*this)); 78487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 78587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 78687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 78787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel, 78887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 78987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 79087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset) const 79187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 79287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset); 79387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 79487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 79587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel, 79687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 79787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 79887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset, 79987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t& pAddend) const 80087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 80187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 80287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 80387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 80487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel, 80587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 80687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 80787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t& pOffset) const 80887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 80987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 81087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 81187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 81287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = pRel.r_info; 81387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 81487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 81587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 81687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = mcld::bswap64(pRel.r_info); 81787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 81887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 81987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // MIPS 64 little endian (we do not support big endian now) 82087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // has a "special" encoding of r_info relocation 82187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // field. Instead of one 64 bit little endian number, it is a little 82287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // endian 32 bit number followed by a 32 bit big endian number. 82387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = mcld::bswap32(r_info >> 32); 82487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = r_info & 0xffffffff; 82587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 82687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 82787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 82887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel, 82987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 83087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 83187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t& pOffset, 83287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int64_t& pAddend) const 83387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 83487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 83587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 83687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 83787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = pRel.r_info; 83887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = pRel.r_addend; 83987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 84087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 84187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 84287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info = mcld::bswap64(pRel.r_info); 84387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = mcld::bswap64(pRel.r_addend); 84487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 84587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 84687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = mcld::bswap32(r_info >> 32); 84787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = r_info & 0xffffffff; 84887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 84987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 85087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 85187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel, 85287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 85387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 85487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset) const 85587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 85687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset); 85787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 85887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 85987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel, 86087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 86187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 86287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset, 86387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t pAddend) const 86487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 86587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 86687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 86787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 86887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel, 86987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 87087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 87187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset) const 87287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 87387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = mcld::bswap32(pType); 87487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info <<= 32; 87587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info |= pSymIdx; 87687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 87787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_info = r_info; 87887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 87987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 88087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 88187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel, 88287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 88387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 88487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset, 88587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int64_t pAddend) const 88687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 88787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = mcld::bswap32(pType); 88887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info <<= 32; 88987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info |= pSymIdx; 89087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 89187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_info = r_info; 89287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 89387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_addend = pAddend; 89487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 89587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 89687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 89787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Mips32GNULDBackend 89887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 89987f34658dec9097d987d254a990ea7f311bfc95fStephen HinesMips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig, 90087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNUInfo* pInfo) 90187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines : MipsGNULDBackend(pConfig, pInfo) 90287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{} 90387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 90487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool Mips32GNULDBackend::initRelocator() 90587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 90687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (NULL == m_pRelocator) 90787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelocator = new Mips32Relocator(*this, config()); 90887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 90987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 91087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 91187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 91287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid Mips32GNULDBackend::initTargetSections(Module& pModule, 91387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ObjectBuilder& pBuilder) 91487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 91587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNULDBackend::initTargetSections(pModule, pBuilder); 91687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 91787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object == config().codeGenType()) 91887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 91987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 92087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFFileFormat* fileFormat = getOutputFormat(); 92187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 92287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got 92387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& got = fileFormat->getGOT(); 92487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOT = new Mips32GOT(got); 92587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 92687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got.plt 92787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& gotplt = fileFormat->getGOTPLT(); 92887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT = new MipsGOTPLT(gotplt); 92987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 93087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .plt 93187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& plt = fileFormat->getPLT(); 93287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT = new MipsPLT(plt); 93387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 93487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 93587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinessize_t Mips32GNULDBackend::getRelEntrySize() 93687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 93787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 8; 93887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 93987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 94087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinessize_t Mips32GNULDBackend::getRelaEntrySize() 94187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 94287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 12; 94387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 94487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 94587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 94687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Mips64GNULDBackend 94787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 94887f34658dec9097d987d254a990ea7f311bfc95fStephen HinesMips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig, 94987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNUInfo* pInfo) 95087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines : MipsGNULDBackend(pConfig, pInfo) 95187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{} 95287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 95387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool Mips64GNULDBackend::initRelocator() 95487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 95587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (NULL == m_pRelocator) 95687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelocator = new Mips64Relocator(*this, config()); 95787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 95887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 95987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 96087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 96187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid Mips64GNULDBackend::initTargetSections(Module& pModule, 96287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ObjectBuilder& pBuilder) 96387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 96487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNULDBackend::initTargetSections(pModule, pBuilder); 96587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 96687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object == config().codeGenType()) 96787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 96887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 96987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFFileFormat* fileFormat = getOutputFormat(); 97087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 97187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got 97287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& got = fileFormat->getGOT(); 97387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOT = new Mips64GOT(got); 97487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 97587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got.plt 97687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& gotplt = fileFormat->getGOTPLT(); 97787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT = new MipsGOTPLT(gotplt); 97887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 97987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .plt 98087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& plt = fileFormat->getPLT(); 98187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT = new MipsPLT(plt); 98287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 98387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 98487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinessize_t Mips64GNULDBackend::getRelEntrySize() 98587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 98687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 16; 98787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 98887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 98987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinessize_t Mips64GNULDBackend::getRelaEntrySize() 99087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{ 99187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 24; 99287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 99387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 9955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 9965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 99787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstatic TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig) 9985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 99987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::Triple& triple = pConfig.targets().triple(); 100087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 100187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (triple.isOSDarwin()) { 10025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 10035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 100487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (triple.isOSWindows()) { 10055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 10065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 100787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 100887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::Triple::ArchType arch = triple.getArch(); 100987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 101087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::Triple::mips64el == arch) 101187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple)); 101287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 101387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert (arch == llvm::Triple::mipsel); 101487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple)); 10155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 10165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 101722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 10185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 101922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 102022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeMipsLDBackend() { 10215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 102222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao createMipsLDBackend); 102387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget, 102487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines createMipsLDBackend); 10255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1026