MipsLDBackend.h revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
1//===- MipsLDBackend.h ----------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef MIPS_LDBACKEND_H
10#define MIPS_LDBACKEND_H
11#include <mcld/Target/GNULDBackend.h>
12#include "MipsELFDynamic.h"
13#include "MipsGOT.h"
14
15namespace mcld {
16
17class LinkerConfig;
18class OutputRelocSection;
19class SectionMap;
20class MemoryArea;
21class MipsGNUInfo;
22
23//===----------------------------------------------------------------------===//
24/// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
25///
26class MipsGNULDBackend : public GNULDBackend
27{
28public:
29  enum ReservedEntryType {
30    None          = 0,  // no reserved entry
31    ReserveRel    = 1,  // reserve a dynamic relocation entry
32    ReserveGot    = 2,  // reserve a GOT entry
33    ReserveGpDisp = 8   // reserve _gp_disp symbol
34  };
35
36public:
37  MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
38  ~MipsGNULDBackend();
39
40public:
41  /// initTargetSections - initialize target dependent sections in output
42  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
43
44  /// initTargetSymbols - initialize target dependent symbols in output.
45  void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
46
47  /// initRelocator - create and initialize Relocator.
48  bool initRelocator();
49
50  /// getRelocator - return relocator.
51  Relocator* getRelocator();
52
53  /// scanRelocation - determine the empty entries are needed or not and
54  /// create the empty entries if needed.
55  /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
56  void scanRelocation(Relocation& pReloc,
57                      IRBuilder& pBuilder,
58                      Module& pModule,
59                      LDSection& pSection);
60
61  /// preLayout - Backend can do any needed modification before layout
62  void doPreLayout(IRBuilder& pBuilder);
63
64  /// postLayout - Backend can do any needed modification after layout
65  void doPostLayout(Module& pModule, IRBuilder& pBuilder);
66
67  /// dynamic - the dynamic section of the target machine.
68  /// Use co-variant return type to return its own dynamic section.
69  MipsELFDynamic& dynamic();
70
71  /// dynamic - the dynamic section of the target machine.
72  /// Use co-variant return type to return its own dynamic section.
73  const MipsELFDynamic& dynamic() const;
74
75  /// emitSectionData - write out the section data into the memory region.
76  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
77  /// call back target backend to emit the data.
78  ///
79  /// Backends handle the target-special tables (plt, gp,...) by themselves.
80  /// Backend can put the data of the tables in SectionData directly
81  ///  - LDSection.getSectionData can get the section data.
82  /// Or, backend can put the data into special data structure
83  ///  - backend can maintain its own map<LDSection, table> to get the table
84  /// from given LDSection.
85  ///
86  /// @param pSection - the given LDSection
87  /// @param pRegion - the region to write out data
88  /// @return the size of the table in the file.
89  uint64_t emitSectionData(const LDSection& pSection,
90                           MemoryRegion& pRegion) const;
91
92  void sizeNamePools(Module& pModule, bool pIsStaticLink);
93
94  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
95  void emitDynNamePools(Module& pModule, MemoryArea& pOut);
96
97
98  MipsGOT& getGOT();
99  const MipsGOT& getGOT() const;
100
101  OutputRelocSection& getRelDyn();
102  const OutputRelocSection& getRelDyn() const;
103
104  /// getTargetSectionOrder - compute the layout order of ARM target sections
105  unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
106
107  /// finalizeSymbol - finalize the symbol value
108  bool finalizeTargetSymbols();
109
110  /// allocateCommonSymbols - allocate common symbols in the corresponding
111  /// sections.
112  bool allocateCommonSymbols(Module& pModule);
113
114private:
115  void scanLocalReloc(Relocation& pReloc,
116                      IRBuilder& pBuilder,
117                      const LDSection& pSection);
118
119  void scanGlobalReloc(Relocation& pReloc,
120                       IRBuilder& pBuilder,
121                       const LDSection& pSection);
122
123  void defineGOTSymbol(IRBuilder& pBuilder);
124
125  /// emitSymbol32 - emit an ELF32 symbol, override parent's function
126  void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
127                    LDSymbol& pSymbol,
128                    char* pStrtab,
129                    size_t pStrtabsize,
130                    size_t pSymtabIdx);
131
132  /// getRelEntrySize - the size in BYTE of rel type relocation
133  size_t getRelEntrySize()
134  { return 8; }
135
136  /// getRelEntrySize - the size in BYTE of rela type relocation
137  size_t getRelaEntrySize()
138  { return 12; }
139
140  /// doCreateProgramHdrs - backend can implement this function to create the
141  /// target-dependent segments
142  void doCreateProgramHdrs(Module& pModule);
143
144private:
145  Relocator* m_pRelocator;
146
147  MipsGOT* m_pGOT;                      // .got
148  OutputRelocSection* m_pRelDyn;        // .rel.dyn
149
150  MipsELFDynamic* m_pDynamic;
151  LDSymbol* m_pGOTSymbol;
152  LDSymbol* m_pGpDispSymbol;
153
154  std::vector<LDSymbol*> m_GlobalGOTSyms;
155
156private:
157  /// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
158  bool isGlobalGOTSymbol(const LDSymbol& pSymbol) const;
159
160};
161
162} // namespace of mcld
163
164#endif
165
166