15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsLDBackend.h ----------------------------------------------------===//
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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef TARGET_MIPS_MIPSLDBACKEND_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define TARGET_MIPS_MIPSLDBACKEND_H_
11b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include <llvm/Support/ELF.h>
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h"
13b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines#include "MipsAbiFlags.h"
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsELFDynamic.h"
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsGOT.h"
1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include "MipsGOTPLT.h"
1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include "MipsPLT.h"
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig;
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass MemoryArea;
23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass MipsGNUInfo;
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass OutputRelocSection;
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass SectionMap;
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/** \class MipsGNULDBackend
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines *  \brief Base linker backend of Mips target of GNU ELF format.
2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass MipsGNULDBackend : public GNULDBackend {
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  typedef std::vector<LDSymbol*> SymbolListType;
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ~MipsGNULDBackend();
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool needsLA25Stub(Relocation::Type pType, const mcld::ResolveInfo* pSym);
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void addNonPICBranchSym(ResolveInfo* rsym);
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool hasNonPICBranch(const ResolveInfo* rsym) const;
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// initTargetSections - initialize target dependent sections in output
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// initTargetSymbols - initialize target dependent symbols in output.
486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// getRelocator - return relocator.
510dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  const Relocator* getRelocator() const;
52d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocator* getRelocator();
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void doPreLayout(IRBuilder& pBuilder);
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// postLayout - Backend can do any needed modification after layout
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void doPostLayout(Module& pModule, IRBuilder& pBuilder);
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Use co-variant return type to return its own dynamic section.
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsELFDynamic& dynamic();
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Use co-variant return type to return its own dynamic section.
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const MipsELFDynamic& dynamic() const;
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - write out the section data into the memory region.
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// call back target backend to emit the data.
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Backends handle the target-special tables (plt, gp,...) by themselves.
73cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  /// Backend can put the data of the tables in SectionData directly
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///  - LDSection.getSectionData can get the section data.
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Or, backend can put the data into special data structure
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///  - backend can maintain its own map<LDSection, table> to get the table
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// from given LDSection.
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pSection - the given LDSection
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pRegion - the region to write out data
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @return the size of the table in the file.
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t emitSectionData(const LDSection& pSection,
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           MemoryRegion& pRegion) const;
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// hasEntryInStrTab - symbol has an entry in a .strtab
86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool hasEntryInStrTab(const LDSymbol& pSym) const;
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// orderSymbolTable - order symbol table before emitting
89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void orderSymbolTable(Module& pModule);
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readSection - read a target dependent section.
9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool readSection(Input& pInput, SectionData& pSD);
9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsGOT& getGOT();
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const MipsGOT& getGOT() const;
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MipsPLT& getPLT();
9887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const MipsPLT& getPLT() const;
9987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MipsGOTPLT& getGOTPLT();
10187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const MipsGOTPLT& getGOTPLT() const;
10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  OutputRelocSection& getRelPLT();
10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const OutputRelocSection& getRelPLT() const;
10587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  OutputRelocSection& getRelDyn();
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const OutputRelocSection& getRelDyn() const;
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  LDSymbol* getGOTSymbol() { return m_pGOTSymbol; }
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; }
111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  LDSymbol* getGpDispSymbol() { return m_pGpDispSymbol; }
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const LDSymbol* getGpDispSymbol() const { return m_pGpDispSymbol; }
114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  SymbolListType& getGlobalGOTSyms() { return m_GlobalGOTSyms; }
116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  const SymbolListType& getGlobalGOTSyms() const { return m_GlobalGOTSyms; }
117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of ARM target sections
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// finalizeSymbol - finalize the symbol value
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool finalizeTargetSymbols();
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// allocateCommonSymbols - allocate common symbols in the corresponding
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sections.
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool allocateCommonSymbols(Module& pModule);
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
128b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  /// getTPOffset - return TP_OFFSET against the SHF_TLS
129b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  /// section in the specified input.
130b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  uint64_t getTPOffset(const Input& pInput) const;
131b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
132b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  /// getDTPOffset - return DTP_OFFSET against the SHF_TLS
133b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  /// section in the specified input.
134b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  uint64_t getDTPOffset(const Input& pInput) const;
135b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
13687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getGP0 - the gp value used to create the relocatable objects
13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// in the specified input.
13887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t getGP0(const Input& pInput) const;
13987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void defineGOTSymbol(IRBuilder& pBuilder);
14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void defineGOTPLTSymbol(IRBuilder& pBuilder);
14387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
14487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool relaxRelocation(IRBuilder& pBuilder, Relocation& pRel);
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol32 - emit an ELF32 symbol, override parent's function
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doCreateProgramHdrs - backend can implement this function to create the
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// target-dependent segments
1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void doCreateProgramHdrs(Module& pModule);
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// mayRelax - Backends should override this function if they need relaxation
15887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool mayRelax() { return true; }
15987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
16087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// doRelax - Backend can orevride this function to add its relaxation
16187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// implementation. Return true if the output (e.g., .text) is "relaxed"
16287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// (i.e. layout is changed), and set pFinished to true if everything is fit,
16387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// otherwise set it to false.
16487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
16587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
16687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// initTargetStubs
16787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool initTargetStubs();
16887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
16987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rel entry
17087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool readRelocation(const llvm::ELF::Elf32_Rel& pRel,
17187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type& pType,
17287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t& pSymIdx,
17387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t& pOffset) const;
17487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
17587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rela entry
17687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool readRelocation(const llvm::ELF::Elf32_Rela& pRel,
17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type& pType,
17887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t& pSymIdx,
17987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t& pOffset,
18087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      int32_t& pAddend) const;
18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
18287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF64_Rel entry
18387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool readRelocation(const llvm::ELF::Elf64_Rel& pRel,
18487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type& pType,
18587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t& pSymIdx,
18687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint64_t& pOffset) const;
18787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
18887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRel - read ELF64_Rela entry
18987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool readRelocation(const llvm::ELF::Elf64_Rela& pRel,
19087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type& pType,
19187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t& pSymIdx,
19287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint64_t& pOffset,
19387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      int64_t& pAddend) const;
19487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
19587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rel entry
19687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitRelocation(llvm::ELF::Elf32_Rel& pRel,
19787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type pType,
19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t pSymIdx,
19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t pOffset) const;
20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rela entry
20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitRelocation(llvm::ELF::Elf32_Rela& pRel,
20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type pType,
20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t pSymIdx,
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t pOffset,
20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      int32_t pAddend) const;
20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rel entry
20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitRelocation(llvm::ELF::Elf64_Rel& pRel,
21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type pType,
21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t pSymIdx,
21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint64_t pOffset) const;
21387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rela entry
21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitRelocation(llvm::ELF::Elf64_Rela& pRel,
21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      Relocation::Type pType,
21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint32_t pSymIdx,
21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      uint64_t pOffset,
21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      int64_t pAddend) const;
22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
221b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  /// preMergeSections - hooks to be executed before merging sections
222b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  void preMergeSections(Module& pModule);
223b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
224b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  /// mergeSection - merge target dependent sections
225b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
226b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
227b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines protected:
228b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  virtual void mergeFlags(Input& pInput, const char* ELF_hdr);
229b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
23037b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef llvm::DenseSet<const ResolveInfo*> ResolveInfoSetType;
232b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  typedef llvm::DenseMap<const Input*, llvm::ELF::Elf64_Addr> InputNumMapType;
233b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  typedef llvm::DenseMap<const Input*, uint64_t> ElfFlagsMapType;
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23537b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Relocator* m_pRelocator;
23737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MipsGOT* m_pGOT;        // .got
23837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MipsPLT* m_pPLT;        // .plt
23937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  MipsGOTPLT* m_pGOTPLT;  // .got.plt
24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24137b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  MipsGNUInfo& m_pInfo;
243b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  llvm::Optional<MipsAbiFlags> m_pAbiInfo;
24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  OutputRelocSection* m_pRelPlt;  // .rel.plt
24637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  OutputRelocSection* m_pRelDyn;  // .rel.dyn
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsELFDynamic* m_pDynamic;
249b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  LDSection* m_psdata;
250b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  LDSection* m_pAbiFlags;
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* m_pGOTSymbol;
25287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  LDSymbol* m_pPLTSymbol;
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* m_pGpDispSymbol;
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
255f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SymbolListType m_GlobalGOTSyms;
25687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ResolveInfoSetType m_HasNonPICBranchSyms;
257b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  InputNumMapType m_GP0Map;
258b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  InputNumMapType m_TpOffsetMap;
259b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  InputNumMapType m_DtpOffsetMap;
260b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  ElfFlagsMapType m_ElfFlagsMap;
261b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
262b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  void moveSectionData(SectionData& pFrom, SectionData& pTo);
263b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  void saveTPOffset(const Input& pInput);
26487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines};
26587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
26687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/** \class Mips32GNULDBackend
26787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines *  \brief Base linker backend of Mips 32-bit target of GNU ELF format.
26887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */
26937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Mips32GNULDBackend : public MipsGNULDBackend {
27037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
27187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Mips32GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
27337b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // MipsGNULDBackend
27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
27687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool initRelocator();
27787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t getRelEntrySize();
27987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t getRelaEntrySize();
28087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines};
28187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
28287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/** \class Mips64GNULDBackend
28387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines *  \brief Base linker backend of Mips 64-bit target of GNU ELF format.
28487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */
28537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Mips64GNULDBackend : public MipsGNULDBackend {
28637b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
28787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Mips64GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
28887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
28937b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
29087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // MipsGNULDBackend
29187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
29287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool initRelocator();
29387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t getRelEntrySize();
29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t getRelaEntrySize();
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
30037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // TARGET_MIPS_MIPSLDBACKEND_H_
301