• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 namespace mcld {
16 
17 class MCLinker;
18 class OutputRelocSection;
19 class SectionMap;
20 
21 //===----------------------------------------------------------------------===//
22 /// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
23 ///
24 class MipsGNULDBackend : public GNULDBackend
25 {
26 public:
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 
34 public:
35   MipsGNULDBackend();
36   ~MipsGNULDBackend();
37 
38 public:
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 
142 private:
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 
171 private:
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 
184 private:
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