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 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 19b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/Fragment/AlignFragment.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/BranchIslandFactory.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/StubFactory.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 25b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/LD/ELFSegment.h" 26b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "mcld/LD/ELFSegmentFactory.h" 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Attribute.h" 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryRegion.h" 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h" 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/TargetRegistry.h" 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/OutputRelocSection.h" 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Triple.h> 36b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include <llvm/Object/ELFTypes.h> 3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Casting.h> 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Host.h> 40b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include <llvm/Support/MipsABIFlags.h> 41b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 42b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include <vector> 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// MipsGNULDBackend 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoMipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig, 50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao MipsGNUInfo* pInfo) 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines : GNULDBackend(pConfig, pInfo), 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelocator(NULL), 5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOT(NULL), 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLT(NULL), 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTPLT(NULL), 5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pInfo(*pInfo), 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelPlt(NULL), 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelDyn(NULL), 5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pDynamic(NULL), 60b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pAbiFlags(NULL), 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol(NULL), 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLTSymbol(NULL), 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGpDispSymbol(NULL) { 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 6637b74a387bb3993387029859c2d9d051c41c724eStephen HinesMipsGNULDBackend::~MipsGNULDBackend() { 67d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao delete m_pRelocator; 6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pPLT; 6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines delete m_pRelPlt; 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pRelDyn; 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete m_pDynamic; 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::needsLA25Stub(Relocation::Type pType, 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines const mcld::ResolveInfo* pSym) { 7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().isCodeIndep()) 7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::R_MIPS_26 != pType) 8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pSym->isLocal()) 8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::addNonPICBranchSym(ResolveInfo* rsym) { 8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_HasNonPICBranchSyms.insert(rsym); 9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGNULDBackend::hasNonPICBranch(const ResolveInfo* rsym) const { 9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_HasNonPICBranchSyms.count(rsym); 9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 9587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::initTargetSections(Module& pModule, 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 9887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object == config().codeGenType()) 9987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 10087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 10187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFFileFormat* file_format = getOutputFormat(); 10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 10387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .rel.plt 10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& relplt = file_format->getRelPlt(); 10587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelPlt = new OutputRelocSection(pModule, relplt); 10687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .rel.dyn 10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& reldyn = file_format->getRelDyn(); 10987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelDyn = new OutputRelocSection(pModule, reldyn); 110b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 111b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // initialize .sdata 112b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_psdata = pBuilder.CreateSection( 113b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ".sdata", LDFileFormat::Target, llvm::ELF::SHT_PROGBITS, 114b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_MIPS_GPREL, 115b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 4); 116b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 117b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // initialize .MIPS.abiflags 118b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pAbiFlags = pBuilder.CreateSection(".MIPS.abiflags", LDFileFormat::Target, 119b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::ELF::SHT_MIPS_ABIFLAGS, 120b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::ELF::SHF_ALLOC, 4); 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) { 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // same name in input 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 13437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Define the symbol _PROCEDURE_LINKAGE_TABLE_ if there is a symbol with the 13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // same name in input 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_PROCEDURE_LINKAGE_TABLE_", 14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 14737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 14837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGpDispSymbol = 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_gp_disp", 15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Section, 15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 15637b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 15737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 1580dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 15937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>( 16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_gp", 16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::NoType, 16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 16337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 16437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), // FragRef 16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Default); 16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 17037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst Relocator* MipsGNULDBackend::getRelocator() const { 17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 1720dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return m_pRelocator; 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 17537b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocator* MipsGNULDBackend::getRelocator() { 17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return m_pRelocator; 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::doPreLayout(IRBuilder& pBuilder) { 1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 18237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!config().isCodeStatic() && m_pDynamic == NULL) 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new MipsELFDynamic(*this, config()); 184cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 185b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (m_pAbiInfo.hasValue()) 186b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pAbiFlags->setSize(m_pAbiInfo->size()); 187b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .got size 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when building shared object, the .got section is must. 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != config().codeGenType()) { 19137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == config().codeGenType() || m_pGOT->hasGOT1() || 19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol != NULL) { 193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOT->finalizeScanning(*m_pRelDyn); 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pGOT->finalizeSectionSize(); 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines defineGOTSymbol(pBuilder); 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_pGOTPLT->hasGOT1()) { 20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT->finalizeSectionSize(); 20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines defineGOTPLTSymbol(pBuilder); 20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_pPLT->hasPLT1()) 20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT->finalizeSectionSize(); 20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 208d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set .rel.plt size 21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_pRelPlt->empty()) { 21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 21337b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 21437b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 21537b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelPlt().setSize(m_pRelPlt->numOfRelocs() * 21637b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelEntrySize()); 21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set .rel.dyn size 2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!m_pRelDyn->empty()) { 22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 22237b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 22337b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 22437b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelDyn().setSize(m_pRelDyn->numOfRelocs() * 22537b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelEntrySize()); 2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) { 23137b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFFileFormat* format = getOutputFormat(); 23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (format->hasGOTPLT()) { 23437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL && "doPostLayout failed, m_pGOTPLT is NULL!"); 23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT->applyAllGOTPLT(m_pPLT->addr()); 23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (format->hasPLT()) { 23937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "doPostLayout failed, m_pPLT is NULL!"); 24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT->applyAllPLT(*m_pGOTPLT); 24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pInfo.setABIVersion(m_pPLT && m_pPLT->hasPLT1() ? 1 : 0); 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. 24837b74a387bb3993387029859c2d9d051c41c724eStephen HinesMipsELFDynamic& MipsGNULDBackend::dynamic() { 24937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// dynamic - the dynamic section of the target machine. 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Use co-variant return type to return its own dynamic section. 25537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst MipsELFDynamic& MipsGNULDBackend::dynamic() const { 25637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pDynamic; 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection, 26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pRegion.size() && "Size of MemoryRegion is zero!"); 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 26687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { 26787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_pGOT->emit(pRegion); 26887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 26987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 27087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { 27187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_pPLT->emit(pRegion); 27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 27387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) { 27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_pGOTPLT->emit(pRegion); 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 278b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (&pSection == m_pAbiFlags && m_pAbiInfo.hasValue()) 279b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return MipsAbiFlags::emit(*m_pAbiInfo, pRegion); 280b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 281b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (&pSection == m_psdata && m_psdata->hasSectionData()) { 282b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const SectionData* sect_data = pSection.getSectionData(); 283b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 284b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint8_t* out_offset = pRegion.begin(); 285b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 286b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines size_t size = frag_iter->size(); 287b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines switch (frag_iter->getKind()) { 288b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case Fragment::Fillment: { 289b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter); 290b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (fill_frag.getValueSize() == 0) { 291b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // virtual fillment, ignore it. 292b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 293b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 294b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines memset(out_offset, fill_frag.getValue(), fill_frag.size()); 295b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 296b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 297b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case Fragment::Region: { 298b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const RegionFragment& region_frag = 299b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::cast<RegionFragment>(*frag_iter); 300b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const char* start = region_frag.getRegion().begin(); 301b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines memcpy(out_offset, start, size); 302b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 303b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 304b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case Fragment::Alignment: { 305b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const AlignFragment& align_frag = 306b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::cast<AlignFragment>(*frag_iter); 307b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t count = size / align_frag.getValueSize(); 308b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines switch (align_frag.getValueSize()) { 309b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case 1u: 310b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines std::memset(out_offset, align_frag.getValue(), count); 311b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 312b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines default: 313b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::report_fatal_error( 314b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines "unsupported value size for align fragment emission yet.\n"); 315b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 316b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // end switch 317b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 318b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 319b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case Fragment::Null: { 320b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(0x0 == size); 321b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 322b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 323b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines default: 324b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::report_fatal_error("unsupported fragment type.\n"); 325b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 326b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } // end switch 327b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines out_offset += size; 328b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 329b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return pRegion.size(); 330b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 331b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 33237b74a387bb3993387029859c2d9d051c41c724eStephen Hines fatal(diag::unrecognized_output_sectoin) << pSection.name() 33337b74a387bb3993387029859c2d9d051c41c724eStephen Hines << "mclinker@googlegroups.com"; 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 33737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const { 33837b74a387bb3993387029859c2d9d051c41c724eStephen Hines return ResolveInfo::Section != pSym.type() || m_pGpDispSymbol == &pSym; 339f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace { 34237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstruct DynsymGOTCompare { 34337b74a387bb3993387029859c2d9d051c41c724eStephen Hines const MipsGOT& m_pGOT; 34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 34537b74a387bb3993387029859c2d9d051c41c724eStephen Hines explicit DynsymGOTCompare(const MipsGOT& pGOT) : m_pGOT(pGOT) {} 34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 34737b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool operator()(const LDSymbol* X, const LDSymbol* Y) const { 34837b74a387bb3993387029859c2d9d051c41c724eStephen Hines return m_pGOT.dynSymOrderCompare(X, Y); 34937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 35037b74a387bb3993387029859c2d9d051c41c724eStephen Hines}; 35137b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // anonymous namespace 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 35337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::orderSymbolTable(Module& pModule) { 3542bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if (config().options().hasGNUHash()) { 355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // The MIPS ABI and .gnu.hash require .dynsym to be sorted 356f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // in different ways. The MIPS ABI requires a mapping between 357f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // the GOT and the symbol table. At the same time .gnu.hash 358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // needs symbols to be grouped by hash code. 359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::errs() << ".gnu.hash is incompatible with the MIPS ABI\n"; 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module::SymbolTable& symbols = pModule.getSymbolTable(); 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 36437b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::stable_sort( 36537b74a387bb3993387029859c2d9d051c41c724eStephen Hines symbols.dynamicBegin(), symbols.dynamicEnd(), DynsymGOTCompare(*m_pGOT)); 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 36837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 36937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 37087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace llvm { 37187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace ELF { 37287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// SHT_MIPS_OPTIONS section's block descriptor. 37387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstruct Elf_Options { 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines unsigned char kind; // Determines interpretation of variable 37537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // part of descriptor. See ODK_xxx enumeration. 37637b74a387bb3993387029859c2d9d051c41c724eStephen Hines unsigned char size; // Byte size of descriptor, including this header. 37737b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf64_Half section; // Section header index of section affected, 37837b74a387bb3993387029859c2d9d051c41c724eStephen Hines // or 0 for global options. 37937b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf64_Word info; // Kind-specific information. 38087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 38187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 38287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 32 bit ABI. 38387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstruct Elf32_RegInfo { 38437b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf32_Word ri_gprmask; // Mask of general purpose registers used. 38537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used. 38637b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf32_Addr ri_gp_value; // GP register value for this object file. 38787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 38887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 38987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 64 bit ABI. 39087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstruct Elf64_RegInfo { 39137b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf32_Word ri_gprmask; // Mask of general purpose registers used. 39237b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf32_Word ri_pad; // Padding. 39337b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used. 39437b74a387bb3993387029859c2d9d051c41c724eStephen Hines Elf64_Addr ri_gp_value; // GP register value for this object file. 39587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 39687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 39737b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace ELF 39837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace llvm 39937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 40037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 40187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 402b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic const char* ArchName(uint64_t flagBits) { 403b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines switch (flagBits) { 404b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_1: 405b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips1"; 406b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_2: 407b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips2"; 408b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_3: 409b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips3"; 410b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_4: 411b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips4"; 412b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_5: 413b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips5"; 414b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_32: 415b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips32"; 416b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_64: 417b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips64"; 418b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_32R2: 419b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips32r2"; 420b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_64R2: 421b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips64r2"; 422b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_32R6: 423b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips32r6"; 424b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines case llvm::ELF::EF_MIPS_ARCH_64R6: 425b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "mips64r6"; 426b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines default: 427b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return "Unknown Arch"; 428b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 429b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 430b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 431b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid MipsGNULDBackend::mergeFlags(Input& pInput, const char* ELF_hdr) { 432b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines bool isTarget64Bit = config().targets().triple().isArch64Bit(); 433b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines bool isInput64Bit = ELF_hdr[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64; 43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 435b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (isTarget64Bit != isInput64Bit) { 436b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines fatal(diag::error_Mips_incompatible_class) 437b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines << (isTarget64Bit ? "ELFCLASS64" : "ELFCLASS32") 438b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines << (isInput64Bit ? "ELFCLASS64" : "ELFCLASS32") << pInput.name(); 439b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return; 440b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 441b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 442b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_ElfFlagsMap[&pInput] = 443b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines isInput64Bit ? 444b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(ELF_hdr)->e_flags : 445b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(ELF_hdr)->e_flags; 446b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 447b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 448b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesbool MipsGNULDBackend::readSection(Input& pInput, SectionData& pSD) { 449b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((pSD.getSection().flag() & llvm::ELF::SHF_MIPS_GPREL) || 450b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines (pSD.getSection().type() == llvm::ELF::SHT_MIPS_ABIFLAGS)) { 45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t offset = pInput.fileOffset() + pSD.getSection().offset(); 45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t size = pSD.getSection().size(); 45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pSD.getSection().type() == llvm::ELF::SHT_MIPS_OPTIONS) { 46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t size = pSD.getSection().size(); 46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef region = pInput.memArea()->request(offset, size); 46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (region.size() > 0) { 46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf_Options* optb = 46637b74a387bb3993387029859c2d9d051c41c724eStephen Hines reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin()); 46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf_Options* opte = 46837b74a387bb3993387029859c2d9d051c41c724eStephen Hines reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin() + 46937b74a387bb3993387029859c2d9d051c41c724eStephen Hines size); 47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 47137b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (const llvm::ELF::Elf_Options* opt = optb; opt < opte; 47237b74a387bb3993387029859c2d9d051c41c724eStephen Hines opt += opt->size) { 47387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (opt->kind) { 47487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: 47587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Nothing to do. 47687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 47787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case llvm::ELF::ODK_REGINFO: 47887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (config().targets().triple().isArch32Bit()) { 47987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf32_RegInfo* reg = 48037b74a387bb3993387029859c2d9d051c41c724eStephen Hines reinterpret_cast<const llvm::ELF::Elf32_RegInfo*>(opt + 1); 48187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GP0Map[&pInput] = reg->ri_gp_value; 48237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 48387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::ELF::Elf64_RegInfo* reg = 48437b74a387bb3993387029859c2d9d051c41c724eStephen Hines reinterpret_cast<const llvm::ELF::Elf64_RegInfo*>(opt + 1); 48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GP0Map[&pInput] = reg->ri_gp_value; 48687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 48787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 48887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 48987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 49087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 49187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 49287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 49387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 49487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 49587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return GNULDBackend::readSection(pInput, pSD); 49687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 49787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 49837b74a387bb3993387029859c2d9d051c41c724eStephen HinesMipsGOT& MipsGNULDBackend::getGOT() { 49937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 50337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst MipsGOT& MipsGNULDBackend::getGOT() const { 50437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pGOT; 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 50837b74a387bb3993387029859c2d9d051c41c724eStephen HinesMipsPLT& MipsGNULDBackend::getPLT() { 50937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL); 51087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pPLT; 51187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 51287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 51337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst MipsPLT& MipsGNULDBackend::getPLT() const { 51437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL); 51587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pPLT; 51687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 51787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 51837b74a387bb3993387029859c2d9d051c41c724eStephen HinesMipsGOTPLT& MipsGNULDBackend::getGOTPLT() { 51937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 52087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pGOTPLT; 52187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 52287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 52337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst MipsGOTPLT& MipsGNULDBackend::getGOTPLT() const { 52437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 52587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pGOTPLT; 52687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 52787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 52837b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& MipsGNULDBackend::getRelPLT() { 52937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelPlt != NULL); 53087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pRelPlt; 53187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 53287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 53337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& MipsGNULDBackend::getRelPLT() const { 53437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelPlt != NULL); 53587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return *m_pRelPlt; 53687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 53787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 53837b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& MipsGNULDBackend::getRelDyn() { 53937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelDyn != NULL); 5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 54337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& MipsGNULDBackend::getRelDyn() const { 54437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelDyn != NULL); 5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *m_pRelDyn; 5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 54837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int MipsGNULDBackend::getTargetSectionOrder( 54937b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection& pSectHdr) const { 55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* file_format = getOutputFormat(); 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 55287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) 55387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return SHO_DATA; 55487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 55587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_DATA; 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 55887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 55987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return SHO_PLT; 56087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 561b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (&pSectHdr == m_psdata) 562b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return SHO_SMALL_DATA; 563b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 564b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (&pSectHdr == m_pAbiFlags) 565b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return SHO_RO_NOTE; 566b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return SHO_UNDEFINED; 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// finalizeSymbol - finalize the symbol value 57137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGNULDBackend::finalizeTargetSymbols() { 57237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pGpDispSymbol != NULL) 573f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGpDispSymbol->setValue(m_pGOT->getGPDispAddress()); 574f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// allocateCommonSymbols - allocate common symbols in the corresponding 57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// sections. This is called at pre-layout stage. 5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// FIXME: Mips needs to allocate small common symbol 58137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) { 58222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymbolCategory& symbol_list = pModule.getSymbolTable(); 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (symbol_list.emptyCommons() && symbol_list.emptyFiles() && 5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines symbol_list.emptyLocals() && symbol_list.emptyLocalDyns()) 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 588affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SymbolCategory::iterator com_sym, com_end; 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: If the order of common symbols is defined, then sort common symbols 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // std::sort(com_sym, com_end, some kind of order); 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 59322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get corresponding BSS LDSection 59422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* file_format = getOutputFormat(); 59522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& bss_sect = file_format->getBSS(); 59622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& tbss_sect = file_format->getTBSS(); 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 598cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get or create corresponding BSS SectionData 59922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* bss_sect_data = NULL; 60022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (bss_sect.hasSectionData()) 60122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = bss_sect.getSectionData(); 60222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 60322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 60422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 60522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* tbss_sect_data = NULL; 60622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (tbss_sect.hasSectionData()) 60722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = tbss_sect.getSectionData(); 60822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 60922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // remember original BSS size 61237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t bss_offset = bss_sect.size(); 61322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tbss_offset = tbss_sect.size(); 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all local common symbols 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.localEnd(); 617affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (ResolveInfo::Common == (*com_sym)->desc()) { 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 626cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 627affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 628affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 629affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 63037b74a387bb3993387029859c2d9d051c41c724eStephen Hines tbss_offset += ObjectBuilder::AppendFragment( 63137b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *tbss_sect_data, (*com_sym)->value()); 632551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 63387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 63437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 63537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: how to identify small and large common symbols? 63637b74a387bb3993387029859c2d9d051c41c724eStephen Hines bss_offset += ObjectBuilder::AppendFragment( 63737b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *bss_sect_data, (*com_sym)->value()); 638551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 63987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 640affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // allocate all global common symbols 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao com_end = symbol_list.commonEnd(); 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We have to reset the description of the symbol here. When doing 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // incremental linking, the output relocatable object may have common 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbols. Therefore, we can not treat common symbols as normal symbols 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // when emitting the regular name pools. We must change the symbols' 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // description here. 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 653cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 654affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 655affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 656affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // allocate TLS common symbol in tbss section 65737b74a387bb3993387029859c2d9d051c41c724eStephen Hines tbss_offset += ObjectBuilder::AppendFragment( 65837b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *tbss_sect_data, (*com_sym)->value()); 659551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); 66087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 66137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 66237b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: how to identify small and large common symbols? 66337b74a387bb3993387029859c2d9d051c41c724eStephen Hines bss_offset += ObjectBuilder::AppendFragment( 66437b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *bss_sect_data, (*com_sym)->value()); 665551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); 66687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 667affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 67022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bss_sect.setSize(bss_offset); 67122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao tbss_sect.setSize(tbss_offset); 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao symbol_list.changeCommonsToGlobal(); 6735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 676b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesuint64_t MipsGNULDBackend::getTPOffset(const Input& pInput) const { 677b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return m_TpOffsetMap.lookup(&pInput); 678b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 679b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 680b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesuint64_t MipsGNULDBackend::getDTPOffset(const Input& pInput) const { 681b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return m_DtpOffsetMap.lookup(&pInput); 682b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 683b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 68437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t MipsGNULDBackend::getGP0(const Input& pInput) const { 68587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_GP0Map.lookup(&pInput); 68687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 68787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 68837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) { 689f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // If we do not reserve any GOT entries, we do not need to re-define GOT 690f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // symbol. 691f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pGOT->hasGOT1()) 692f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return; 693f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 69422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // define symbol _GLOBAL_OFFSET_TABLE_ 69537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pGOTSymbol != NULL) { 6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 69737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 69837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 69937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 70037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 70137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 70237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 70337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pGOT->begin()), 0x0), 70437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 70537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 70737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 70837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 70937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 71037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 71137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 71237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 71337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pGOT->begin()), 0x0), 71437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 7155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 71837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder) { 71987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // define symbol _PROCEDURE_LINKAGE_TABLE_ 72037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pPLTSymbol != NULL) { 72187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 72237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_PROCEDURE_LINKAGE_TABLE_", 72337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 72437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 72537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 72637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 72737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 72837b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pPLT->begin()), 0x0), 72937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 73037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 73187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 73237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_PROCEDURE_LINKAGE_TABLE_", 73337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 73437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 73537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 73637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 73737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 73837b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(*(m_pPLT->begin()), 0x0), 73937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 74087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 74187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 74287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 74322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// doCreateProgramHdrs - backend can implement this function to create the 74422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// target-dependent segments 74537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGNULDBackend::doCreateProgramHdrs(Module& pModule) { 746b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!m_pAbiFlags || m_pAbiFlags->size() == 0) 747b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return; 748b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 749b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // create PT_MIPS_ABIFLAGS segment 750b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ELFSegmentFactory::iterator sit = 751b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines elfSegmentTable().find(llvm::ELF::PT_INTERP, 0x0, 0x0); 752b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (sit == elfSegmentTable().end()) 753b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sit = elfSegmentTable().find(llvm::ELF::PT_PHDR, 0x0, 0x0); 754b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (sit == elfSegmentTable().end()) 755b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sit = elfSegmentTable().begin(); 756b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines else 757b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++sit; 758b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 759b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ELFSegment* abiSeg = elfSegmentTable().insert(sit, 760b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::ELF::PT_MIPS_ABIFLAGS, 761b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines llvm::ELF::PF_R); 762b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines abiSeg->setAlign(8); 763b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines abiSeg->append(m_pAbiFlags); 7645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 7655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 76637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel) { 76787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t sym_value = 0x0; 76887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 76987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSymbol* symbol = pRel.symInfo()->outSymbol(); 77087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (symbol->hasFragRef()) { 77187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t value = symbol->fragRef()->getOutputOffset(); 77287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); 77387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sym_value = addr + value; 77487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 77587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77637b74a387bb3993387029859c2d9d051c41c724eStephen Hines Stub* stub = getStubFactory()->create( 77737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pRel, sym_value, pBuilder, *getBRIslandFactory()); 77887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (stub == NULL) 78087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 78187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 78237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(stub->symInfo() != NULL); 783b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // reset the branch target of the reloc to this stub instead 784b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pRel.setSymInfo(stub->symInfo()); 785b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 78687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // increase the size of .symtab and .strtab 78787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& symtab = getOutputFormat()->getSymTab(); 78887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& strtab = getOutputFormat()->getStrTab(); 78987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 79087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 79187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 79287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 79387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 79487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 79537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGNULDBackend::doRelax(Module& pModule, 79637b74a387bb3993387029859c2d9d051c41c724eStephen Hines IRBuilder& pBuilder, 79737b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool& pFinished) { 79837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(getStubFactory() != NULL && getBRIslandFactory() != NULL); 79987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 80087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool isRelaxed = false; 80187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 80287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (Module::obj_iterator input = pModule.obj_begin(); 80337b74a387bb3993387029859c2d9d051c41c724eStephen Hines input != pModule.obj_end(); 80437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++input) { 80587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDContext* context = (*input)->context(); 80687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 80787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (LDContext::sect_iterator rs = context->relocSectBegin(); 80837b74a387bb3993387029859c2d9d051c41c724eStephen Hines rs != context->relocSectEnd(); 80937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++rs) { 81087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* sec = *rs; 81187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 81287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData()) 81387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 81487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 81587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (RelocData::iterator reloc = sec->getRelocData()->begin(); 81637b74a387bb3993387029859c2d9d051c41c724eStephen Hines reloc != sec->getRelocData()->end(); 81737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++reloc) { 81887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::R_MIPS_26 != reloc->type()) 81987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines continue; 82087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 82187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc))) 82287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines isRelaxed = true; 82387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 82487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 82587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 82687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 82787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // find the first fragment w/ invalid offset due to stub insertion 828b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines std::vector<Fragment*> invalid_frags; 82987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pFinished = true; 83087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(), 83187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ie = getBRIslandFactory()->end(); 83237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ii != ie; 83337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++ii) { 83487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines BranchIsland& island = *ii; 835b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (island.size() > stubGroupSize()) { 836b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::err_no_space_to_place_stubs) << stubGroupSize(); 837b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 838b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 839b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 840b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (island.numOfStubs() == 0) { 841b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 842b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 843b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 844b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* exit = &*island.end(); 8452a0b905c72a5b9554c9eeb0bda6fbdea49bcddffPirama Arumuga Nainar if (exit == &*island.begin()->getParent()->end()) { 846b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 847b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 84887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 84987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((island.offset() + island.size()) > exit->getOffset()) { 850b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (invalid_frags.empty() || 851b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines (invalid_frags.back()->getParent() != island.getParent())) { 852b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid_frags.push_back(exit); 853b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pFinished = false; 854b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 855b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 85687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 85787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 85887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 85987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // reset the offset of invalid fragments 860b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie; 861b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++it) { 862b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines Fragment* invalid = *it; 863b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines while (invalid != NULL) { 864b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid->setOffset(invalid->getPrevNode()->getOffset() + 865b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid->getPrevNode()->size()); 866b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines invalid = invalid->getNextNode(); 867b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 86887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 86987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 870b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // reset the size of section that has stubs inserted. 871b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (isRelaxed) { 872b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* prev = NULL; 873b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 874b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island_end = getBRIslandFactory()->end(); 875b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines island != island_end; 876b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ++island) { 877b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* sd = (*island).begin()->getParent(); 878b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*island).numOfStubs() != 0) { 879b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (sd != prev) { 880b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sd->getSection().setSize(sd->back().getOffset() + sd->back().size()); 881b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 882b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 883b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines prev = sd; 884b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 885b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 88687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 88787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return isRelaxed; 88887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 88987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 89037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGNULDBackend::initTargetStubs() { 89137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (getStubFactory() == NULL) 89287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 89387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 89487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines getStubFactory()->addPrototype(new MipsLA25Stub(*this)); 89587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 89687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 89787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 89887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel, 89987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 90087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 90137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t& pOffset) const { 90287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset); 90387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 90487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 90587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel, 90687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 90787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 90887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset, 90937b74a387bb3993387029859c2d9d051c41c724eStephen Hines int32_t& pAddend) const { 91087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 91187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 91287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 91387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel, 91487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 91587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 91637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t& pOffset) const { 91787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 91887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 91987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 92037b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = pRel.r_info; 92137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 92287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 92337b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = mcld::bswap64(pRel.r_info); 92487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 92587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 92687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // MIPS 64 little endian (we do not support big endian now) 92787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // has a "special" encoding of r_info relocation 92887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // field. Instead of one 64 bit little endian number, it is a little 92987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // endian 32 bit number followed by a 32 bit big endian number. 93087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = mcld::bswap32(r_info >> 32); 93187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = r_info & 0xffffffff; 93287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 93387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 93487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 93587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel, 93687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type& pType, 93787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 93887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t& pOffset, 93937b74a387bb3993387029859c2d9d051c41c724eStephen Hines int64_t& pAddend) const { 94087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = 0x0; 94187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) { 94287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = pRel.r_offset; 94337b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = pRel.r_info; 94487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = pRel.r_addend; 94537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 94687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pOffset = mcld::bswap64(pRel.r_offset); 94737b74a387bb3993387029859c2d9d051c41c724eStephen Hines r_info = mcld::bswap64(pRel.r_info); 94887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pAddend = mcld::bswap64(pRel.r_addend); 94987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 95087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 95187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pType = mcld::bswap32(r_info >> 32); 95287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pSymIdx = r_info & 0xffffffff; 95387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 95487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 95587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 95687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel, 95787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 95887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 95937b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t pOffset) const { 96087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset); 96187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 96287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 96387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel, 96487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 96587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 96687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset, 96737b74a387bb3993387029859c2d9d051c41c724eStephen Hines int32_t pAddend) const { 96887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend); 96987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 97087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 97187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel, 97287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 97387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 97437b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t pOffset) const { 97587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = mcld::bswap32(pType); 97687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info <<= 32; 97787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info |= pSymIdx; 97887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 97987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_info = r_info; 98087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 98187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 98287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 98387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel, 98487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Relocation::Type pType, 98587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 98687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset, 98737b74a387bb3993387029859c2d9d051c41c724eStephen Hines int64_t pAddend) const { 98887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t r_info = mcld::bswap32(pType); 98987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info <<= 32; 99087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_info |= pSymIdx; 99187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 99287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_info = r_info; 99387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_offset = pOffset; 99487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pRel.r_addend = pAddend; 99587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 99687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 997b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesnamespace { 998b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstruct ISATreeEdge { 999b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines unsigned child; 1000b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines unsigned parent; 1001b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines}; 1002b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1003b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1004b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic ISATreeEdge isaTree[] = { 1005b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS32R6 and MIPS64R6 are not compatible with other extensions 1006b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1007b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS64 extensions. 1008b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_64R2, llvm::ELF::EF_MIPS_ARCH_64}, 1009b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS V extensions. 1010b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_64, llvm::ELF::EF_MIPS_ARCH_5}, 1011b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS IV extensions. 1012b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_5, llvm::ELF::EF_MIPS_ARCH_4}, 1013b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS III extensions. 1014b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_4, llvm::ELF::EF_MIPS_ARCH_3}, 1015b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS32 extensions. 1016b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_32R2, llvm::ELF::EF_MIPS_ARCH_32}, 1017b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS II extensions. 1018b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_3, llvm::ELF::EF_MIPS_ARCH_2}, 1019b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_32, llvm::ELF::EF_MIPS_ARCH_2}, 1020b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // MIPS I extensions. 1021b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines {llvm::ELF::EF_MIPS_ARCH_2, llvm::ELF::EF_MIPS_ARCH_1}, 1022b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines}; 1023b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1024b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic bool isIsaMatched(uint32_t base, uint32_t ext) { 1025b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (base == ext) 1026b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1027b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (base == llvm::ELF::EF_MIPS_ARCH_32 && 1028b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines isIsaMatched(llvm::ELF::EF_MIPS_ARCH_64, ext)) 1029b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1030b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (base == llvm::ELF::EF_MIPS_ARCH_32R2 && 1031b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines isIsaMatched(llvm::ELF::EF_MIPS_ARCH_64R2, ext)) 1032b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1033b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (const auto &edge : isaTree) { 1034b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (ext == edge.child) { 1035b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ext = edge.parent; 1036b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (ext == base) 1037b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1038b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1039b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1040b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1041b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1042b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1043b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic bool getAbiFlags(const Input& pInput, uint64_t elfFlags, bool& hasFlags, 1044b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines MipsAbiFlags& pFlags) { 1045b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines MipsAbiFlags pElfFlags = {}; 1046b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!MipsAbiFlags::fillByElfFlags(pInput, elfFlags, pElfFlags)) 1047b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1048b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1049b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const LDContext* ctx = pInput.context(); 1050b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (auto it = ctx->sectBegin(), ie = ctx->sectEnd(); it != ie; ++it) 1051b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((*it)->type() == llvm::ELF::SHT_MIPS_ABIFLAGS) { 1052b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!MipsAbiFlags::fillBySection(pInput, **it, pFlags)) 1053b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1054b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!MipsAbiFlags::isCompatible(pInput, pElfFlags, pFlags)) 1055b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1056b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines hasFlags = true; 1057b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1058b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1059b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1060b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pFlags = pElfFlags; 1061b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1062b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1063b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1064b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic const char* getNanName(uint64_t flags) { 1065b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return flags & llvm::ELF::EF_MIPS_NAN2008 ? "2008" : "legacy"; 1066b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1067b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1068b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesstatic bool mergeElfFlags(const Input& pInput, uint64_t& oldElfFlags, 1069b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t newElfFlags) { 1070b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // PIC code is inherently CPIC and may not set CPIC flag explicitly. 1071b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Ensure that this flag will exist in the linked file. 1072b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (newElfFlags & llvm::ELF::EF_MIPS_PIC) 1073b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines newElfFlags |= llvm::ELF::EF_MIPS_CPIC; 1074b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1075b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (newElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE_M16) { 1076b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::error_Mips_m16_unsupported) << pInput.name(); 1077b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1078b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1079b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1080b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!oldElfFlags) { 1081b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags = newElfFlags; 1082b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1083b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1084b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1085b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t newPic = 1086b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines newElfFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC); 1087b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t oldPic = 1088b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC); 1089b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1090b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Check PIC / CPIC flags compatibility. 1091b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((newPic != 0) != (oldPic != 0)) 1092b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines warning(diag::warn_Mips_abicalls_linking) << pInput.name(); 1093b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1094b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!(newPic & llvm::ELF::EF_MIPS_PIC)) 1095b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags &= ~llvm::ELF::EF_MIPS_PIC; 1096b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (newPic) 1097b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags |= llvm::ELF::EF_MIPS_CPIC; 1098b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1099b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Check ISA compatibility. 1100b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t newArch = newElfFlags & llvm::ELF::EF_MIPS_ARCH; 1101b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t oldArch = oldElfFlags & llvm::ELF::EF_MIPS_ARCH; 1102b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!isIsaMatched(newArch, oldArch)) { 1103b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!isIsaMatched(oldArch, newArch)) { 1104b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::error_Mips_inconsistent_arch) 1105b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines << ArchName(oldArch) << ArchName(newArch) << pInput.name(); 1106b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1107b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1108b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags &= ~llvm::ELF::EF_MIPS_ARCH; 1109b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags |= newArch; 1110b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1111b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1112b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Check ABI compatibility. 1113b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint32_t newAbi = newElfFlags & llvm::ELF::EF_MIPS_ABI; 1114b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint32_t oldAbi = oldElfFlags & llvm::ELF::EF_MIPS_ABI; 1115b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (newAbi != oldAbi && newAbi && oldAbi) { 1116b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::error_Mips_inconsistent_abi) << pInput.name(); 1117b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1118b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1119b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1120b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Check -mnan flags compatibility. 1121b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((newElfFlags & llvm::ELF::EF_MIPS_NAN2008) != 1122b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines (oldElfFlags & llvm::ELF::EF_MIPS_NAN2008)) { 1123b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Linking -mnan=2008 and -mnan=legacy modules 1124b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::error_Mips_inconsistent_mnan) 1125b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines << getNanName(oldElfFlags) << getNanName(newElfFlags) << pInput.name(); 1126b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1127b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1128b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1129b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Check ASE compatibility. 1130b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t newAse = newElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE; 1131b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t oldAse = oldElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE; 1132b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (newAse != oldAse) 1133b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags |= newAse; 1134b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1135b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Check FP64 compatibility. 1136b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if ((newElfFlags & llvm::ELF::EF_MIPS_FP64) != 1137b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines (oldElfFlags & llvm::ELF::EF_MIPS_FP64)) { 1138b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Linking -mnan=2008 and -mnan=legacy modules 1139b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines error(diag::error_Mips_inconsistent_fp64) << pInput.name(); 1140b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return false; 1141b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1142b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1143b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_NOREORDER; 1144b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_MICROMIPS; 1145b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_NAN2008; 1146b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_32BITMODE; 1147b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1148b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1149b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1150b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1151b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid MipsGNULDBackend::saveTPOffset(const Input& pInput) { 1152b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines const LDContext* ctx = pInput.context(); 1153b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (auto it = ctx->sectBegin(), ie = ctx->sectEnd(); it != ie; ++it) { 1154b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines LDSection* sect = *it; 1155b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (sect->flag() & llvm::ELF::SHF_TLS) { 1156b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_TpOffsetMap[&pInput] = sect->addr() + 0x7000; 1157b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_DtpOffsetMap[&pInput] = sect->addr() + 0x8000; 1158b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines break; 1159b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1160b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1161b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1162b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1163b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid MipsGNULDBackend::preMergeSections(Module& pModule) { 1164b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t elfFlags = 0; 1165b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines bool hasAbiFlags = false; 1166b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines MipsAbiFlags abiFlags = {}; 1167b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (const Input *input : pModule.getObjectList()) { 1168b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (input->type() != Input::Object) 1169b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 1170b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1171b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t newElfFlags = m_ElfFlagsMap[input]; 1172b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1173b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines MipsAbiFlags newAbiFlags = {}; 1174b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!getAbiFlags(*input, newElfFlags, hasAbiFlags, newAbiFlags)) 1175b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 1176b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1177b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!mergeElfFlags(*input, elfFlags, newElfFlags)) 1178b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 1179b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1180b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!MipsAbiFlags::merge(*input, abiFlags, newAbiFlags)) 1181b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines continue; 1182b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1183b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines saveTPOffset(*input); 1184b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1185b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1186b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pInfo.setElfFlags(elfFlags); 1187b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (hasAbiFlags) 1188b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_pAbiInfo = abiFlags; 1189b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1190b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1191b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesbool MipsGNULDBackend::mergeSection(Module& pModule, const Input& pInput, 1192b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines LDSection& pSection) { 1193b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (pSection.flag() & llvm::ELF::SHF_MIPS_GPREL) { 1194b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData* sd = NULL; 1195b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (!m_psdata->hasSectionData()) { 1196b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sd = IRBuilder::CreateSectionData(*m_psdata); 1197b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines m_psdata->setSectionData(sd); 1198b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1199b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines sd = m_psdata->getSectionData(); 1200b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines moveSectionData(*pSection.getSectionData(), *sd); 1201b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } else if (pSection.type() == llvm::ELF::SHT_MIPS_ABIFLAGS) { 1202b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // Nothing to do because we handle all .MIPS.abiflags sections 1203b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // in the preMergeSections method. 1204b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } else { 1205b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines ObjectBuilder builder(pModule); 1206b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines builder.MergeSection(pInput, pSection); 1207b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1208b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines return true; 1209b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1210b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1211b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesvoid MipsGNULDBackend::moveSectionData(SectionData& pFrom, SectionData& pTo) { 1212b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines assert(&pFrom != &pTo && "Cannot move section data to itself!"); 1213b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1214b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines uint64_t offset = pTo.getSection().size(); 1215b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines AlignFragment* align = NULL; 1216b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines if (pFrom.getSection().align() > 1) { 1217b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // if the align constraint is larger than 1, append an alignment 1218b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines unsigned int alignment = pFrom.getSection().align(); 1219b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines align = new AlignFragment(/*alignment*/ alignment, 1220b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /*the filled value*/ 0x0, 1221b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /*the size of filled value*/ 1u, 1222b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines /*max bytes to emit*/ alignment - 1); 1223b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines align->setOffset(offset); 1224b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines align->setParent(&pTo); 1225b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pTo.getFragmentList().push_back(align); 1226b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines offset += align->size(); 1227b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1228b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1229b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // move fragments from pFrom to pTO 1230b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::FragmentListType& from_list = pFrom.getFragmentList(); 1231b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::FragmentListType& to_list = pTo.getFragmentList(); 1232b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines SectionData::FragmentListType::iterator frag, fragEnd = from_list.end(); 1233b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines for (frag = from_list.begin(); frag != fragEnd; ++frag) { 1234b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines frag->setParent(&pTo); 1235b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines frag->setOffset(offset); 1236b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines offset += frag->size(); 1237b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines } 1238b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines to_list.splice(to_list.end(), from_list); 1239b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 1240b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines // set up pTo's header 1241b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines pTo.getSection().setSize(offset); 1242b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines} 1243b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines 124487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 124587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Mips32GNULDBackend 124687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 124787f34658dec9097d987d254a990ea7f311bfc95fStephen HinesMips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig, 124887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNUInfo* pInfo) 124937b74a387bb3993387029859c2d9d051c41c724eStephen Hines : MipsGNULDBackend(pConfig, pInfo) { 125037b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 125187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 125237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Mips32GNULDBackend::initRelocator() { 125337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pRelocator == NULL) 125487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelocator = new Mips32Relocator(*this, config()); 125587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 125687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 125787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 125887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 125987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid Mips32GNULDBackend::initTargetSections(Module& pModule, 126037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 126187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNULDBackend::initTargetSections(pModule, pBuilder); 126287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 126387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object == config().codeGenType()) 126487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 126587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 126687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFFileFormat* fileFormat = getOutputFormat(); 126787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 126887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got 126987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& got = fileFormat->getGOT(); 127087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOT = new Mips32GOT(got); 127187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 127287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got.plt 127387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& gotplt = fileFormat->getGOTPLT(); 127487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT = new MipsGOTPLT(gotplt); 127587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 127687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .plt 127787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& plt = fileFormat->getPLT(); 127887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT = new MipsPLT(plt); 127987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 128087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 128137b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t Mips32GNULDBackend::getRelEntrySize() { 128287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 8; 128387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 128487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 128537b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t Mips32GNULDBackend::getRelaEntrySize() { 128687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 12; 128787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 128887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 128987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 129087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Mips64GNULDBackend 129187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 129287f34658dec9097d987d254a990ea7f311bfc95fStephen HinesMips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig, 129387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNUInfo* pInfo) 129437b74a387bb3993387029859c2d9d051c41c724eStephen Hines : MipsGNULDBackend(pConfig, pInfo) { 129537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 129687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 129737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Mips64GNULDBackend::initRelocator() { 129837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pRelocator == NULL) 129987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pRelocator = new Mips64Relocator(*this, config()); 130087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 130187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 130287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 130387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 130487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid Mips64GNULDBackend::initTargetSections(Module& pModule, 130537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 130687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MipsGNULDBackend::initTargetSections(pModule, pBuilder); 130787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 130887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (LinkerConfig::Object == config().codeGenType()) 130987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 131087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 131187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFFileFormat* fileFormat = getOutputFormat(); 131287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 131387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got 131487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& got = fileFormat->getGOT(); 131587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOT = new Mips64GOT(got); 131687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 131787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .got.plt 131887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& gotplt = fileFormat->getGOTPLT(); 131987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLT = new MipsGOTPLT(gotplt); 132087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 132187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // initialize .plt 132287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& plt = fileFormat->getPLT(); 132387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pPLT = new MipsPLT(plt); 132487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 132587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 132637b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t Mips64GNULDBackend::getRelEntrySize() { 132787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 16; 132887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 132987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 133037b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t Mips64GNULDBackend::getRelaEntrySize() { 133187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 24; 133287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 133387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 13345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 13355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend 13365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 133737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig) { 133887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const llvm::Triple& triple = pConfig.targets().triple(); 133987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 134087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (triple.isOSDarwin()) { 13415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "MachO linker is not supported yet"); 13425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 134387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (triple.isOSWindows()) { 13445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(0 && "COFF linker is not supported yet"); 13455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 134687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 134787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::Triple::ArchType arch = triple.getArch(); 134887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 134987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::Triple::mips64el == arch) 135087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple)); 135187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 135237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(arch == llvm::Triple::mipsel); 135387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple)); 13545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 13555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 135637b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 135737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 135822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 13595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Force static initialization. 136022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 136122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoextern "C" void MCLDInitializeMipsLDBackend() { 13625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget, 136337b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createMipsLDBackend); 136487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget, 136537b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createMipsLDBackend); 13665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1367