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