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