MipsLDBackend.h revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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 MCLinker;
18class OutputRelocSection;
19class SectionMap;
20
21//===----------------------------------------------------------------------===//
22/// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
23///
24class MipsGNULDBackend : public GNULDBackend
25{
26public:
27  enum ReservedEntryType {
28    None          = 0,  // no reserved entry
29    ReserveRel    = 1,  // reserve a dynamic relocation entry
30    ReserveGot    = 2,  // reserve a GOT entry
31    ReserveGpDisp = 8   // reserve _gp_disp symbol
32  };
33
34public:
35  MipsGNULDBackend();
36  ~MipsGNULDBackend();
37
38public:
39  /// initTargetSectionMap - initialize target dependent section mapping.
40  bool initTargetSectionMap(SectionMap& pSectionMap);
41
42  /// initTargetSections - initialize target dependent sections in output
43  void initTargetSections(MCLinker& pLinker);
44
45  /// initTargetSymbols - initialize target dependent symbols in output.
46  void initTargetSymbols(MCLinker& pLinker);
47
48  /// initRelocFactory - create and initialize RelocationFactory.
49  bool initRelocFactory(const MCLinker& pLinker);
50
51  /// getRelocFactory - return relocation factory.
52  RelocationFactory* getRelocFactory();
53
54  /// scanRelocation - determine the empty entries are needed or not and
55  /// create the empty entries if needed.
56  /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
57  void scanRelocation(Relocation& pReloc,
58                      const LDSymbol& pInputSym,
59                      MCLinker& pLinker,
60                      const MCLDInfo& pLDInfo,
61                      const Output& pOutput);
62
63  uint32_t machine() const;
64
65  /// OSABI - the value of e_ident[EI_OSABI]
66  uint8_t OSABI() const;
67
68  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
69  uint8_t ABIVersion() const;
70
71  /// flags - the value of ElfXX_Ehdr::e_flags
72  uint64_t flags() const;
73
74  bool isLittleEndian() const;
75
76  unsigned int bitclass() const;
77
78  /// preLayout - Backend can do any needed modification before layout
79  void doPreLayout(const Output& pOutput,
80                   const MCLDInfo& pInfo,
81                   MCLinker& pLinker);
82
83  /// postLayout -Backend can do any needed modification after layout
84  void doPostLayout(const Output& pOutput,
85                    const MCLDInfo& pInfo,
86                    MCLinker& pLinker);
87
88  /// dynamic - the dynamic section of the target machine.
89  /// Use co-variant return type to return its own dynamic section.
90  MipsELFDynamic& dynamic();
91
92  /// dynamic - the dynamic section of the target machine.
93  /// Use co-variant return type to return its own dynamic section.
94  const MipsELFDynamic& dynamic() const;
95
96  /// emitSectionData - write out the section data into the memory region.
97  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
98  /// call back target backend to emit the data.
99  ///
100  /// Backends handle the target-special tables (plt, gp,...) by themselves.
101  /// Backend can put the data of the tables in MCSectionData directly
102  ///  - LDSection.getSectionData can get the section data.
103  /// Or, backend can put the data into special data structure
104  ///  - backend can maintain its own map<LDSection, table> to get the table
105  /// from given LDSection.
106  ///
107  /// @param pOutput - the output file
108  /// @param pSection - the given LDSection
109  /// @param pInfo - all options in the command line.
110  /// @param pRegion - the region to write out data
111  /// @return the size of the table in the file.
112  uint64_t emitSectionData(const Output& pOutput,
113                           const LDSection& pSection,
114                           const MCLDInfo& pInfo,
115                           MemoryRegion& pRegion) const;
116
117  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
118  virtual void emitDynNamePools(Output& pOutput,
119                                SymbolCategory& pSymbols,
120                                const Layout& pLayout,
121                                const MCLDInfo& pLDInfo);
122
123  MipsGOT& getGOT();
124  const MipsGOT& getGOT() const;
125
126  OutputRelocSection& getRelDyn();
127  const OutputRelocSection& getRelDyn() const;
128
129  /// getTargetSectionOrder - compute the layout order of ARM target sections
130  unsigned int getTargetSectionOrder(const Output& pOutput,
131                                     const LDSection& pSectHdr) const;
132
133  /// finalizeSymbol - finalize the symbol value
134  /// If the symbol's reserved field is not zero, MCLinker will call back this
135  /// function to ask the final value of the symbol
136  bool finalizeSymbol(LDSymbol& pSymbol) const;
137
138  /// allocateCommonSymbols - allocate common symbols in the corresponding
139  /// sections.
140  bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
141
142private:
143  void scanLocalReloc(Relocation& pReloc,
144                      const LDSymbol& pInputSym,
145                      MCLinker& pLinker,
146                      const MCLDInfo& pLDInfo,
147                      const Output& pOutput);
148
149  void scanGlobalReloc(Relocation& pReloc,
150                      const LDSymbol& pInputSym,
151                      MCLinker& pLinker,
152                      const MCLDInfo& pLDInfo,
153                      const Output& pOutput);
154
155  bool isSymbolNeedsPLT(ResolveInfo& pSym, const Output& pOutput) const;
156  bool isSymbolNeedsDynRel(ResolveInfo& pSym, const Output& pOutput) const;
157
158  void createGOT(MCLinker& pLinker, const Output& pOutput);
159  void createRelDyn(MCLinker& pLinker, const Output& pOutput);
160
161  ELFFileFormat* getOutputFormat(const Output& pOutput) const;
162
163  /// updateAddend - update addend value of the relocation if the
164  /// the target symbol is a section symbol. Addend is the offset
165  /// in the section. This value should be updated after section
166  /// merged.
167  void updateAddend(Relocation& pReloc,
168                    const LDSymbol& pInputSym,
169                    const Layout& pLayout) const;
170
171private:
172  RelocationFactory* m_pRelocFactory;
173
174  MipsGOT* m_pGOT;                      // .got
175  OutputRelocSection* m_pRelDyn;        // .rel.dyn
176
177  MipsELFDynamic* m_pDynamic;
178  LDSymbol* m_pGOTSymbol;
179  LDSymbol* m_pGpDispSymbol;
180
181  std::vector<LDSymbol*> m_LocalGOTSyms;
182  std::vector<LDSymbol*> m_GlobalGOTSyms;
183
184private:
185  /// isGOTSymbol - return true if the symbol is the GOT entry.
186  bool isGOTSymbol(const LDSymbol& pSymbol) const;
187  /// emitDynamicSymbol - emit dynamic symbol.
188  void emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
189                         Output& pOutput,
190                         LDSymbol& pSymbol,
191                         const Layout& pLayout,
192                         char* strtab,
193                         size_t strtabsize,
194                         size_t symtabIdx);
195};
196
197} // namespace of mcld
198
199#endif
200
201