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" 19cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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" 25cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines#include "mcld/LD/ELFSegment.h" 26cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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> 36cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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> 40cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines#include <llvm/Support/MipsABIFlags.h> 41cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 42cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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), 60cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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); 110cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 111cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // initialize .sdata 112cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_psdata = pBuilder.CreateSection( 113cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ".sdata", LDFileFormat::Target, llvm::ELF::SHT_PROGBITS, 114cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_MIPS_GPREL, 115cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 4); 116cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 117cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // initialize .MIPS.abiflags 118cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pAbiFlags = pBuilder.CreateSection(".MIPS.abiflags", LDFileFormat::Target, 119cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::ELF::SHT_MIPS_ABIFLAGS, 120cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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 185cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (m_pAbiInfo.hasValue()) 186cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pAbiFlags->setSize(m_pAbiInfo->size()); 187cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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 278cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (&pSection == m_pAbiFlags && m_pAbiInfo.hasValue()) 279cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return MipsAbiFlags::emit(*m_pAbiInfo, pRegion); 280cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 281cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (&pSection == m_psdata && m_psdata->hasSectionData()) { 282cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines const SectionData* sect_data = pSection.getSectionData(); 283cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 284cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint8_t* out_offset = pRegion.begin(); 285cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 286cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines size_t size = frag_iter->size(); 287cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines switch (frag_iter->getKind()) { 288cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case Fragment::Fillment: { 289cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter); 290cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (fill_frag.getValueSize() == 0) { 291cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // virtual fillment, ignore it. 292cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 293cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 294cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines memset(out_offset, fill_frag.getValue(), fill_frag.size()); 295cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 296cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 297cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case Fragment::Region: { 298cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines const RegionFragment& region_frag = 299cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::cast<RegionFragment>(*frag_iter); 300cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines const char* start = region_frag.getRegion().begin(); 301cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines memcpy(out_offset, start, size); 302cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 303cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 304cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case Fragment::Alignment: { 305cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines const AlignFragment& align_frag = 306cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::cast<AlignFragment>(*frag_iter); 307cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t count = size / align_frag.getValueSize(); 308cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines switch (align_frag.getValueSize()) { 309cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case 1u: 310cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines std::memset(out_offset, align_frag.getValue(), count); 311cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 312cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines default: 313cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::report_fatal_error( 314cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines "unsupported value size for align fragment emission yet.\n"); 315cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 316cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } // end switch 317cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 318cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 319cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case Fragment::Null: { 320cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines assert(0x0 == size); 321cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 322cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 323cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines default: 324cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::report_fatal_error("unsupported fragment type.\n"); 325cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 326cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } // end switch 327cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines out_offset += size; 328cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 329cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return pRegion.size(); 330cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 331cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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 402cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesstatic const char* ArchName(uint64_t flagBits) { 403cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines switch (flagBits) { 404cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_1: 405cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips1"; 406cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_2: 407cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips2"; 408cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_3: 409cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips3"; 410cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_4: 411cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips4"; 412cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_5: 413cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips5"; 414cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_32: 415cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips32"; 416cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_64: 417cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips64"; 418cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_32R2: 419cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips32r2"; 420cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_64R2: 421cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips64r2"; 422cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_32R6: 423cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips32r6"; 424cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines case llvm::ELF::EF_MIPS_ARCH_64R6: 425cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "mips64r6"; 426cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines default: 427cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return "Unknown Arch"; 428cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 429cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 430cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 431cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesvoid MipsGNULDBackend::mergeFlags(Input& pInput, const char* ELF_hdr) { 432cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines bool isTarget64Bit = config().targets().triple().isArch64Bit(); 433cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines bool isInput64Bit = ELF_hdr[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64; 43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 435cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (isTarget64Bit != isInput64Bit) { 436cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines fatal(diag::error_Mips_incompatible_class) 437cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines << (isTarget64Bit ? "ELFCLASS64" : "ELFCLASS32") 438cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines << (isInput64Bit ? "ELFCLASS64" : "ELFCLASS32") << pInput.name(); 439cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return; 440cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 441cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 442cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_ElfFlagsMap[&pInput] = 443cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines isInput64Bit ? 444cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(ELF_hdr)->e_flags : 445cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(ELF_hdr)->e_flags; 446cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 447cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 448cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesbool MipsGNULDBackend::readSection(Input& pInput, SectionData& pSD) { 449cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((pSD.getSection().flag() & llvm::ELF::SHF_MIPS_GPREL) || 450cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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 561cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (&pSectHdr == m_psdata) 562cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return SHO_SMALL_DATA; 563cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 564cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (&pSectHdr == m_pAbiFlags) 565cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return SHO_RO_NOTE; 566cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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 676cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesuint64_t MipsGNULDBackend::getTPOffset(const Input& pInput) const { 677cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return m_TpOffsetMap.lookup(&pInput); 678cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 679cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 680cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesuint64_t MipsGNULDBackend::getDTPOffset(const Input& pInput) const { 681cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return m_DtpOffsetMap.lookup(&pInput); 682cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 683cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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) { 746cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!m_pAbiFlags || m_pAbiFlags->size() == 0) 747cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return; 748cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 749cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // create PT_MIPS_ABIFLAGS segment 750cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ELFSegmentFactory::iterator sit = 751cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines elfSegmentTable().find(llvm::ELF::PT_INTERP, 0x0, 0x0); 752cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (sit == elfSegmentTable().end()) 753cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines sit = elfSegmentTable().find(llvm::ELF::PT_PHDR, 0x0, 0x0); 754cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (sit == elfSegmentTable().end()) 755cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines sit = elfSegmentTable().begin(); 756cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines else 757cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ++sit; 758cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 759cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ELFSegment* abiSeg = elfSegmentTable().insert(sit, 760cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::ELF::PT_MIPS_ABIFLAGS, 761cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm::ELF::PF_R); 762cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines abiSeg->setAlign(8); 763cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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); 783cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // reset the branch target of the reloc to this stub instead 784cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines pRel.setSymInfo(stub->symInfo()); 785cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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 828cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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; 835cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (island.size() > stubGroupSize()) { 836cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines error(diag::err_no_space_to_place_stubs) << stubGroupSize(); 837cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 838cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 839cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 840cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (island.numOfStubs() == 0) { 841cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 842cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 843cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 844cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines Fragment* exit = &*island.end(); 845cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (exit == island.begin()->getParent()->end()) { 846cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 847cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 84887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 84987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((island.offset() + island.size()) > exit->getOffset()) { 850cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (invalid_frags.empty() || 851cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines (invalid_frags.back()->getParent() != island.getParent())) { 852cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid_frags.push_back(exit); 853cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines pFinished = false; 854cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 855cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 85687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 85787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 85887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 85987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // reset the offset of invalid fragments 860cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie; 861cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ++it) { 862cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines Fragment* invalid = *it; 863cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines while (invalid != NULL) { 864cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid->setOffset(invalid->getPrevNode()->getOffset() + 865cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid->getPrevNode()->size()); 866cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid = invalid->getNextNode(); 867cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 86887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 86987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 870cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // reset the size of section that has stubs inserted. 871cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (isRelaxed) { 872cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData* prev = NULL; 873cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 874cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines island_end = getBRIslandFactory()->end(); 875cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines island != island_end; 876cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ++island) { 877cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData* sd = (*island).begin()->getParent(); 878cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((*island).numOfStubs() != 0) { 879cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (sd != prev) { 880cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines sd->getSection().setSize(sd->back().getOffset() + sd->back().size()); 881cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 882cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 883cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines prev = sd; 884cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 885cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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 997cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesnamespace { 998cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesstruct ISATreeEdge { 999cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines unsigned child; 1000cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines unsigned parent; 1001cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines}; 1002cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1003cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1004cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesstatic ISATreeEdge isaTree[] = { 1005cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS32R6 and MIPS64R6 are not compatible with other extensions 1006cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1007cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS64 extensions. 1008cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_64R2, llvm::ELF::EF_MIPS_ARCH_64}, 1009cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS V extensions. 1010cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_64, llvm::ELF::EF_MIPS_ARCH_5}, 1011cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS IV extensions. 1012cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_5, llvm::ELF::EF_MIPS_ARCH_4}, 1013cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS III extensions. 1014cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_4, llvm::ELF::EF_MIPS_ARCH_3}, 1015cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS32 extensions. 1016cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_32R2, llvm::ELF::EF_MIPS_ARCH_32}, 1017cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS II extensions. 1018cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_3, llvm::ELF::EF_MIPS_ARCH_2}, 1019cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_32, llvm::ELF::EF_MIPS_ARCH_2}, 1020cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // MIPS I extensions. 1021cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines {llvm::ELF::EF_MIPS_ARCH_2, llvm::ELF::EF_MIPS_ARCH_1}, 1022cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines}; 1023cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1024cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesstatic bool isIsaMatched(uint32_t base, uint32_t ext) { 1025cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (base == ext) 1026cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1027cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (base == llvm::ELF::EF_MIPS_ARCH_32 && 1028cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines isIsaMatched(llvm::ELF::EF_MIPS_ARCH_64, ext)) 1029cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1030cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (base == llvm::ELF::EF_MIPS_ARCH_32R2 && 1031cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines isIsaMatched(llvm::ELF::EF_MIPS_ARCH_64R2, ext)) 1032cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1033cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (const auto &edge : isaTree) { 1034cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (ext == edge.child) { 1035cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ext = edge.parent; 1036cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (ext == base) 1037cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1038cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1039cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1040cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1041cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1042cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1043cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesstatic bool getAbiFlags(const Input& pInput, uint64_t elfFlags, bool& hasFlags, 1044cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines MipsAbiFlags& pFlags) { 1045cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines MipsAbiFlags pElfFlags = {}; 1046cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!MipsAbiFlags::fillByElfFlags(pInput, elfFlags, pElfFlags)) 1047cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1048cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1049cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines const LDContext* ctx = pInput.context(); 1050cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (auto it = ctx->sectBegin(), ie = ctx->sectEnd(); it != ie; ++it) 1051cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((*it)->type() == llvm::ELF::SHT_MIPS_ABIFLAGS) { 1052cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!MipsAbiFlags::fillBySection(pInput, **it, pFlags)) 1053cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1054cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!MipsAbiFlags::isCompatible(pInput, pElfFlags, pFlags)) 1055cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1056cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines hasFlags = true; 1057cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1058cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1059cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1060cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines pFlags = pElfFlags; 1061cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1062cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1063cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1064cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesstatic const char* getNanName(uint64_t flags) { 1065cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return flags & llvm::ELF::EF_MIPS_NAN2008 ? "2008" : "legacy"; 1066cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1067cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1068cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesstatic bool mergeElfFlags(const Input& pInput, uint64_t& oldElfFlags, 1069cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t newElfFlags) { 1070cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // PIC code is inherently CPIC and may not set CPIC flag explicitly. 1071cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Ensure that this flag will exist in the linked file. 1072cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (newElfFlags & llvm::ELF::EF_MIPS_PIC) 1073cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines newElfFlags |= llvm::ELF::EF_MIPS_CPIC; 1074cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1075cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (newElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE_M16) { 1076cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines error(diag::error_Mips_m16_unsupported) << pInput.name(); 1077cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1078cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1079cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1080cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!oldElfFlags) { 1081cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags = newElfFlags; 1082cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1083cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1084cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1085cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t newPic = 1086cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines newElfFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC); 1087cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t oldPic = 1088cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC); 1089cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1090cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Check PIC / CPIC flags compatibility. 1091cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((newPic != 0) != (oldPic != 0)) 1092cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines warning(diag::warn_Mips_abicalls_linking) << pInput.name(); 1093cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1094cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!(newPic & llvm::ELF::EF_MIPS_PIC)) 1095cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags &= ~llvm::ELF::EF_MIPS_PIC; 1096cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (newPic) 1097cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags |= llvm::ELF::EF_MIPS_CPIC; 1098cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1099cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Check ISA compatibility. 1100cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t newArch = newElfFlags & llvm::ELF::EF_MIPS_ARCH; 1101cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t oldArch = oldElfFlags & llvm::ELF::EF_MIPS_ARCH; 1102cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!isIsaMatched(newArch, oldArch)) { 1103cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!isIsaMatched(oldArch, newArch)) { 1104cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines error(diag::error_Mips_inconsistent_arch) 1105cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines << ArchName(oldArch) << ArchName(newArch) << pInput.name(); 1106cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1107cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1108cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags &= ~llvm::ELF::EF_MIPS_ARCH; 1109cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags |= newArch; 1110cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1111cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1112cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Check ABI compatibility. 1113cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint32_t newAbi = newElfFlags & llvm::ELF::EF_MIPS_ABI; 1114cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint32_t oldAbi = oldElfFlags & llvm::ELF::EF_MIPS_ABI; 1115cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (newAbi != oldAbi && newAbi && oldAbi) { 1116cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines error(diag::error_Mips_inconsistent_abi) << pInput.name(); 1117cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1118cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1119cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1120cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Check -mnan flags compatibility. 1121cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((newElfFlags & llvm::ELF::EF_MIPS_NAN2008) != 1122cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines (oldElfFlags & llvm::ELF::EF_MIPS_NAN2008)) { 1123cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Linking -mnan=2008 and -mnan=legacy modules 1124cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines error(diag::error_Mips_inconsistent_mnan) 1125cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines << getNanName(oldElfFlags) << getNanName(newElfFlags) << pInput.name(); 1126cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1127cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1128cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1129cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Check ASE compatibility. 1130cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t newAse = newElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE; 1131cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t oldAse = oldElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE; 1132cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (newAse != oldAse) 1133cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags |= newAse; 1134cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1135cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Check FP64 compatibility. 1136cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((newElfFlags & llvm::ELF::EF_MIPS_FP64) != 1137cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines (oldElfFlags & llvm::ELF::EF_MIPS_FP64)) { 1138cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Linking -mnan=2008 and -mnan=legacy modules 1139cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines error(diag::error_Mips_inconsistent_fp64) << pInput.name(); 1140cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 1141cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1142cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1143cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_NOREORDER; 1144cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_MICROMIPS; 1145cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_NAN2008; 1146cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_32BITMODE; 1147cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1148cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1149cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1150cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1151cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesvoid MipsGNULDBackend::saveTPOffset(const Input& pInput) { 1152cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines const LDContext* ctx = pInput.context(); 1153cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (auto it = ctx->sectBegin(), ie = ctx->sectEnd(); it != ie; ++it) { 1154cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines LDSection* sect = *it; 1155cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (sect->flag() & llvm::ELF::SHF_TLS) { 1156cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_TpOffsetMap[&pInput] = sect->addr() + 0x7000; 1157cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_DtpOffsetMap[&pInput] = sect->addr() + 0x8000; 1158cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines break; 1159cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1160cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1161cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1162cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1163cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesvoid MipsGNULDBackend::preMergeSections(Module& pModule) { 1164cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t elfFlags = 0; 1165cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines bool hasAbiFlags = false; 1166cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines MipsAbiFlags abiFlags = {}; 1167cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (const Input *input : pModule.getObjectList()) { 1168cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (input->type() != Input::Object) 1169cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 1170cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1171cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t newElfFlags = m_ElfFlagsMap[input]; 1172cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1173cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines MipsAbiFlags newAbiFlags = {}; 1174cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!getAbiFlags(*input, newElfFlags, hasAbiFlags, newAbiFlags)) 1175cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 1176cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1177cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!mergeElfFlags(*input, elfFlags, newElfFlags)) 1178cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 1179cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1180cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!MipsAbiFlags::merge(*input, abiFlags, newAbiFlags)) 1181cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 1182cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1183cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines saveTPOffset(*input); 1184cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1185cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1186cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pInfo.setElfFlags(elfFlags); 1187cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (hasAbiFlags) 1188cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pAbiInfo = abiFlags; 1189cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1190cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1191cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesbool MipsGNULDBackend::mergeSection(Module& pModule, const Input& pInput, 1192cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines LDSection& pSection) { 1193cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (pSection.flag() & llvm::ELF::SHF_MIPS_GPREL) { 1194cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData* sd = NULL; 1195cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (!m_psdata->hasSectionData()) { 1196cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines sd = IRBuilder::CreateSectionData(*m_psdata); 1197cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_psdata->setSectionData(sd); 1198cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1199cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines sd = m_psdata->getSectionData(); 1200cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines moveSectionData(*pSection.getSectionData(), *sd); 1201cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } else if (pSection.type() == llvm::ELF::SHT_MIPS_ABIFLAGS) { 1202cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // Nothing to do because we handle all .MIPS.abiflags sections 1203cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // in the preMergeSections method. 1204cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } else { 1205cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ObjectBuilder builder(pModule); 1206cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines builder.MergeSection(pInput, pSection); 1207cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1208cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 1209cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1210cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1211cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesvoid MipsGNULDBackend::moveSectionData(SectionData& pFrom, SectionData& pTo) { 1212cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines assert(&pFrom != &pTo && "Cannot move section data to itself!"); 1213cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1214cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines uint64_t offset = pTo.getSection().size(); 1215cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines AlignFragment* align = NULL; 1216cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (pFrom.getSection().align() > 1) { 1217cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // if the align constraint is larger than 1, append an alignment 1218cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines unsigned int alignment = pFrom.getSection().align(); 1219cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines align = new AlignFragment(/*alignment*/ alignment, 1220cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines /*the filled value*/ 0x0, 1221cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines /*the size of filled value*/ 1u, 1222cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines /*max bytes to emit*/ alignment - 1); 1223cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines align->setOffset(offset); 1224cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines align->setParent(&pTo); 1225cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines pTo.getFragmentList().push_back(align); 1226cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines offset += align->size(); 1227cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1228cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1229cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // move fragments from pFrom to pTO 1230cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData::FragmentListType& from_list = pFrom.getFragmentList(); 1231cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData::FragmentListType& to_list = pTo.getFragmentList(); 1232cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData::FragmentListType::iterator frag, fragEnd = from_list.end(); 1233cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (frag = from_list.begin(); frag != fragEnd; ++frag) { 1234cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines frag->setParent(&pTo); 1235cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines frag->setOffset(offset); 1236cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines offset += frag->size(); 1237cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 1238cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines to_list.splice(to_list.end(), from_list); 1239cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 1240cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // set up pTo's header 1241cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines pTo.getSection().setSize(offset); 1242cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 1243cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen 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