• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- TargetLDBackend.h - Target LD Backend -------------------*- C++ -*-===//
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 MCLD_TARGET_TARGETLDBACKEND_H_
10 #define MCLD_TARGET_TARGETLDBACKEND_H_
11 #include "mcld/Fragment/Relocation.h"
12 #include "mcld/LD/GarbageCollection.h"
13 #include "mcld/Support/Compiler.h"
14 #include "mcld/Support/GCFactoryListTraits.h"
15 
16 #include <llvm/ADT/StringRef.h>
17 #include <llvm/ADT/ilist.h>
18 #include <llvm/Support/DataTypes.h>
19 
20 namespace mcld {
21 
22 class ArchiveReader;
23 class BinaryReader;
24 class BinaryWriter;
25 class BranchIslandFactory;
26 class DynObjReader;
27 class DynObjWriter;
28 class ExecWriter;
29 class FileOutputBuffer;
30 class IRBuilder;
31 class Input;
32 class LDSection;
33 class LDSymbol;
34 class LinkerConfig;
35 class Module;
36 class ObjectBuilder;
37 class ObjectReader;
38 class ObjectWriter;
39 class Relocator;
40 class ResolveInfo;
41 class SectionData;
42 class SectionReachedListMap;
43 class StubFactory;
44 
45 //===----------------------------------------------------------------------===//
46 /// TargetLDBackend - Generic interface to target specific assembler backends.
47 //===----------------------------------------------------------------------===//
48 class TargetLDBackend {
49  public:
50   typedef llvm::iplist<Relocation, GCFactoryListTraits<Relocation> >
51       ExtraRelocList;
52   typedef ExtraRelocList::iterator extra_reloc_iterator;
53 
54  protected:
55   explicit TargetLDBackend(const LinkerConfig& pConfig);
56 
57  public:
58   virtual ~TargetLDBackend();
59 
60   // -----  target dependent  ----- //
initTargetSegments(IRBuilder & pBuilder)61   virtual void initTargetSegments(IRBuilder& pBuilder) {}
initTargetSections(Module & pModule,ObjectBuilder & pBuilder)62   virtual void initTargetSections(Module& pModule, ObjectBuilder& pBuilder) {}
initTargetSymbols(IRBuilder & pBuilder,Module & pModule)63   virtual void initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {}
initTargetRelocation(IRBuilder & pBuilder)64   virtual void initTargetRelocation(IRBuilder& pBuilder) {}
65   virtual bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule) = 0;
66 
67   virtual bool initRelocator() = 0;
68 
69   virtual Relocator* getRelocator() = 0;
70   virtual const Relocator* getRelocator() const = 0;
71 
72   // -----  format dependent  ----- //
73   virtual ArchiveReader* createArchiveReader(Module&) = 0;
74   virtual ObjectReader* createObjectReader(IRBuilder&) = 0;
75   virtual DynObjReader* createDynObjReader(IRBuilder&) = 0;
76   virtual BinaryReader* createBinaryReader(IRBuilder&) = 0;
77   virtual ObjectWriter* createWriter() = 0;
78 
79   virtual bool initStdSections(ObjectBuilder& pBuilder) = 0;
80 
81   /// layout - layout method
82   virtual void layout(Module& pModule) = 0;
83 
84   /// preLayout - Backend can do any needed modification before layout
85   virtual void preLayout(Module& pModule, IRBuilder& pBuilder) = 0;
86 
87   /// postLayout - Backend can do any needed modification after layout
88   virtual void postLayout(Module& pModule, IRBuilder& pBuilder) = 0;
89 
90   /// postProcessing - Backend can do any needed modification in the final stage
91   virtual void postProcessing(FileOutputBuffer& pOutput) = 0;
92 
93   /// section start offset in the output file
94   virtual size_t sectionStartOffset() const = 0;
95 
96   /// computeSectionOrder - compute the layout order of the given section
97   virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const = 0;
98 
99   /// sizeNamePools - compute the size of regular name pools
100   /// In ELF executable files, regular name pools are .symtab, .strtab.,
101   /// .dynsym, .dynstr, and .hash
102   virtual void sizeNamePools(Module& pModule) = 0;
103 
104   /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
105   /// then it will ask backend to finalize the symbol value.
106   /// @return ture - if backend set the symbol value sucessfully
107   /// @return false - if backend do not recognize the symbol
108   virtual bool finalizeSymbols() = 0;
109 
110   /// finalizeTLSSymbol - Linker asks backend to set the symbol value when it
111   /// meets a TLS symbol
112   virtual bool finalizeTLSSymbol(LDSymbol& pSymbol) = 0;
113 
114   /// allocateCommonSymbols - allocate common symbols in the corresponding
115   /// sections.
116   virtual bool allocateCommonSymbols(Module& pModule) = 0;
117 
118   /// preMergeSections - hooks to be executed before merging sections
preMergeSections(Module & pModule)119   virtual void preMergeSections(Module& pModule) { }
120 
121   /// postMergeSections - hooks to be executed after merging sections
postMergeSections(Module & pModule)122   virtual void postMergeSections(Module& pModule) { }
123 
124   /// mergeSection - merge target dependent sections.
mergeSection(Module & pModule,const Input & pInputFile,LDSection & pInputSection)125   virtual bool mergeSection(Module& pModule,
126                             const Input& pInputFile,
127                             LDSection& pInputSection) {
128     return true;
129   }
130 
131   /// setUpReachedSectionsForGC - set the reference between two sections for
132   /// some special target sections. GC will set up the reference for the Regular
133   /// and BSS sections. Backends can also set up the reference if need.
setUpReachedSectionsForGC(const Module & pModule,GarbageCollection::SectionReachedListMap & pSectReachedListMap)134   virtual void setUpReachedSectionsForGC(
135       const Module& pModule,
136       GarbageCollection::SectionReachedListMap& pSectReachedListMap) const {}
137 
138   /// updateSectionFlags - update pTo's flags when merging pFrom
139   /// update the output section flags based on input section flags.
140   /// FIXME: (Luba) I know ELF need to merge flags, but I'm not sure if
141   /// MachO and COFF also need this.
updateSectionFlags(LDSection & pTo,const LDSection & pFrom)142   virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom) {
143     return true;
144   }
145 
146   /// readSection - read a target dependent section
readSection(Input & pInput,SectionData & pSD)147   virtual bool readSection(Input& pInput, SectionData& pSD) { return true; }
148 
149   /// sizeInterp - compute the size of program interpreter's name
150   /// In ELF executables, this is the length of dynamic linker's path name
151   virtual void sizeInterp() = 0;
152 
153   /// getEntry - get the entry point name
154   virtual llvm::StringRef getEntry(const Module& pModule) const = 0;
155 
156   // -----  relaxation  ----- //
157   virtual bool initBRIslandFactory() = 0;
158   virtual bool initStubFactory() = 0;
initTargetStubs()159   virtual bool initTargetStubs() { return true; }
160 
161   virtual BranchIslandFactory* getBRIslandFactory() = 0;
162   virtual StubFactory* getStubFactory() = 0;
163 
164   /// relax - the relaxation pass
165   virtual bool relax(Module& pModule, IRBuilder& pBuilder) = 0;
166 
167   /// mayRelax - return true if the backend needs to do relaxation
168   virtual bool mayRelax() = 0;
169 
170   /// commonPageSize - the common page size of the target machine
171   virtual uint64_t commonPageSize() const = 0;
172 
173   /// abiPageSize - the abi page size of the target machine
174   virtual uint64_t abiPageSize() const = 0;
175 
176   /// sortRelocation - sort the dynamic relocations to let dynamic linker
177   /// process relocations more efficiently
178   virtual void sortRelocation(LDSection& pSection) = 0;
179 
180   /// createAndSizeEhFrameHdr - This is seperated since we may add eh_frame
181   /// entry in the middle
182   virtual void createAndSizeEhFrameHdr(Module& pModule) = 0;
183 
184   /// isSymbolPreemptible - whether the symbol can be preemted by other link
185   /// units
186   virtual bool isSymbolPreemptible(const ResolveInfo& pSym) const = 0;
187 
188   /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
189   /// function pointer access
190   virtual bool mayHaveUnsafeFunctionPointerAccess(
191       const LDSection& pSection) const = 0;
192 
extra_reloc_begin()193   extra_reloc_iterator extra_reloc_begin() {
194     return m_ExtraReloc.begin();
195   }
196 
extra_reloc_end()197   extra_reloc_iterator extra_reloc_end() {
198     return m_ExtraReloc.end();
199   }
200 
201  protected:
config()202   const LinkerConfig& config() const { return m_Config; }
203 
204   /// addExtraRelocation - Add an extra relocation which are automatically
205   /// generated by the LD backend.
addExtraRelocation(Relocation * reloc)206   void addExtraRelocation(Relocation* reloc) {
207     m_ExtraReloc.push_back(reloc);
208   }
209 
210  private:
211   const LinkerConfig& m_Config;
212 
213   /// m_ExtraReloc - Extra relocations that are automatically generated by the
214   /// linker.
215   ExtraRelocList m_ExtraReloc;
216 
217  private:
218   DISALLOW_COPY_AND_ASSIGN(TargetLDBackend);
219 };
220 
221 }  // namespace mcld
222 
223 #endif  // MCLD_TARGET_TARGETLDBACKEND_H_
224