MipsLDBackend.h revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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 FragmentLinker;
19class OutputRelocSection;
20class SectionMap;
21class MemoryArea;
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);
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(FragmentLinker& pLinker);
46
47  /// initRelocFactory - create and initialize RelocationFactory.
48  bool initRelocFactory(const FragmentLinker& pLinker);
49
50  /// getRelocFactory - return relocation factory.
51  RelocationFactory* getRelocFactory();
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                      FragmentLinker& pLinker,
58                      Module& pModule,
59                      const LDSection& pSection);
60
61  uint32_t machine() const;
62
63  /// OSABI - the value of e_ident[EI_OSABI]
64  uint8_t OSABI() const;
65
66  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
67  uint8_t ABIVersion() const;
68
69  /// flags - the value of ElfXX_Ehdr::e_flags
70  uint64_t flags() const;
71
72  bool isLittleEndian() const;
73
74  unsigned int bitclass() const;
75
76  uint64_t defaultTextSegmentAddr() const;
77
78  /// abiPageSize - the abi page size of the target machine
79  uint64_t abiPageSize() const;
80
81  /// preLayout - Backend can do any needed modification before layout
82  void doPreLayout(FragmentLinker& pLinker);
83
84  /// postLayout -Backend can do any needed modification after layout
85  void doPostLayout(Module& pModule, FragmentLinker& pLinker);
86
87  /// dynamic - the dynamic section of the target machine.
88  /// Use co-variant return type to return its own dynamic section.
89  MipsELFDynamic& dynamic();
90
91  /// dynamic - the dynamic section of the target machine.
92  /// Use co-variant return type to return its own dynamic section.
93  const MipsELFDynamic& dynamic() const;
94
95  /// emitSectionData - write out the section data into the memory region.
96  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
97  /// call back target backend to emit the data.
98  ///
99  /// Backends handle the target-special tables (plt, gp,...) by themselves.
100  /// Backend can put the data of the tables in SectionData directly
101  ///  - LDSection.getSectionData can get the section data.
102  /// Or, backend can put the data into special data structure
103  ///  - backend can maintain its own map<LDSection, table> to get the table
104  /// from given LDSection.
105  ///
106  /// @param pSection - the given LDSection
107  /// @param pRegion - the region to write out data
108  /// @return the size of the table in the file.
109  uint64_t emitSectionData(const LDSection& pSection,
110                           MemoryRegion& pRegion) const;
111
112  void sizeNamePools(const Module& pModule, bool pIsStaticLink);
113
114  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
115  void emitDynNamePools(const Module& pModule, MemoryArea& pOut);
116
117
118  MipsGOT& getGOT();
119  const MipsGOT& getGOT() const;
120
121  OutputRelocSection& getRelDyn();
122  const OutputRelocSection& getRelDyn() const;
123
124  /// getTargetSectionOrder - compute the layout order of ARM target sections
125  unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
126
127  /// finalizeSymbol - finalize the symbol value
128  bool finalizeTargetSymbols(FragmentLinker& pLinker);
129
130  /// allocateCommonSymbols - allocate common symbols in the corresponding
131  /// sections.
132  bool allocateCommonSymbols(Module& pModule);
133
134private:
135  void scanLocalReloc(Relocation& pReloc, FragmentLinker& pLinker);
136
137  void scanGlobalReloc(Relocation& pReloc, FragmentLinker& pLinker);
138
139  void defineGOTSymbol(FragmentLinker& pLinker);
140
141  /// emitSymbol32 - emit an ELF32 symbol, override parent's function
142  void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
143                    LDSymbol& pSymbol,
144                    char* pStrtab,
145                    size_t pStrtabsize,
146                    size_t pSymtabIdx);
147
148  /// getRelEntrySize - the size in BYTE of rel type relocation
149  size_t getRelEntrySize()
150  { return 8; }
151
152  /// getRelEntrySize - the size in BYTE of rela type relocation
153  size_t getRelaEntrySize()
154  { return 12; }
155
156  /// doCreateProgramHdrs - backend can implement this function to create the
157  /// target-dependent segments
158  virtual void doCreateProgramHdrs(Module& pModule,
159                                   const FragmentLinker& pLinker);
160
161private:
162  RelocationFactory* m_pRelocFactory;
163
164  MipsGOT* m_pGOT;                      // .got
165  OutputRelocSection* m_pRelDyn;        // .rel.dyn
166
167  MipsELFDynamic* m_pDynamic;
168  LDSymbol* m_pGOTSymbol;
169  LDSymbol* m_pGpDispSymbol;
170
171  std::vector<LDSymbol*> m_GlobalGOTSyms;
172
173private:
174  /// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
175  bool isGlobalGOTSymbol(const LDSymbol& pSymbol) const;
176
177};
178
179} // namespace of mcld
180
181#endif
182
183