1 //===- Relocator.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 MCLD_LD_RELOCATOR_H_
10 #define MCLD_LD_RELOCATOR_H_
11 
12 #include "mcld/Fragment/Relocation.h"
13 
14 namespace mcld {
15 
16 class Input;
17 class IRBuilder;
18 class Module;
19 class TargetLDBackend;
20 
21 /** \class Relocator
22  *  \brief Relocator provides the interface of performing relocations
23  */
24 class Relocator {
25  public:
26   typedef Relocation::Type Type;
27   typedef Relocation::Address Address;
28   typedef Relocation::DWord DWord;
29   typedef Relocation::SWord SWord;
30   typedef Relocation::Size Size;
31 
32  public:
33   enum Result { OK, BadReloc, Overflow, Unsupported, Unknown };
34 
35  public:
Relocator(const LinkerConfig & pConfig)36   explicit Relocator(const LinkerConfig& pConfig) : m_Config(pConfig) {}
37 
38   virtual ~Relocator() = 0;
39 
40   /// apply - general apply function
41   virtual Result applyRelocation(Relocation& pRelocation) = 0;
42 
43   /// scanRelocation - When read in relocations, backend can do any modification
44   /// to relocation and generate empty entries, such as GOT, dynamic relocation
45   /// entries and other target dependent entries. These entries are generated
46   /// for layout to adjust the ouput offset.
47   /// @param pReloc - a read in relocation entry
48   /// @param pInputSym - the input LDSymbol of relocation target symbol
49   /// @param pSection - the section of relocation applying target
50   /// @param pInput - the input file of relocation
51   virtual void scanRelocation(Relocation& pReloc,
52                               IRBuilder& pBuilder,
53                               Module& pModule,
54                               LDSection& pSection,
55                               Input& pInput) = 0;
56 
57   /// issueUndefRefError - Provides a basic version for undefined reference
58   /// dump.
59   /// It will handle the filename and function name automatically.
60   /// @param pReloc - a read in relocation entry
61   /// @param pSection - the section of relocation applying target
62   /// @ param pInput - the input file of relocation
63   virtual void issueUndefRef(Relocation& pReloc,
64                              LDSection& pSection,
65                              Input& pInput);
66 
67   /// initializeScan - do initialization before scan relocations in pInput
68   /// @return - return true for initialization success
initializeScan(Input & pInput)69   virtual bool initializeScan(Input& pInput) { return true; }
70 
71   /// finalizeScan - do finalization after scan relocations in pInput
72   /// @return - return true for finalization success
finalizeScan(Input & pInput)73   virtual bool finalizeScan(Input& pInput) { return true; }
74 
75   /// initializeApply - do initialization before apply relocations in pInput
76   /// @return - return true for initialization success
initializeApply(Input & pInput)77   virtual bool initializeApply(Input& pInput) { return true; }
78 
79   /// finalizeApply - do finalization after apply relocations in pInput
80   /// @return - return true for finalization success
finalizeApply(Input & pInput)81   virtual bool finalizeApply(Input& pInput) { return true; }
82 
83   /// partialScanRelocation - When doing partial linking, backend can do any
84   /// modification to relocation to fix the relocation offset after section
85   /// merge
86   /// @param pReloc - a read in relocation entry
87   /// @param pInputSym - the input LDSymbol of relocation target symbol
88   /// @param pSection - the section of relocation applying target
89   virtual void partialScanRelocation(Relocation& pReloc,
90                                      Module& pModule);
91 
92   // ------ observers -----//
93   virtual TargetLDBackend& getTarget() = 0;
94 
95   virtual const TargetLDBackend& getTarget() const = 0;
96 
97   /// getName - get the name of a relocation
98   virtual const char* getName(Type pType) const = 0;
99 
100   /// getSize - get the size of a relocation in bit
101   virtual Size getSize(Type pType) const = 0;
102 
103   /// mayHaveFunctionPointerAccess - check if the given reloc would possibly
104   /// access a function pointer.
105   /// Note: Each target relocator should override this function, or be
106   /// conservative and return true to avoid getting folded.
mayHaveFunctionPointerAccess(const Relocation & pReloc)107   virtual bool mayHaveFunctionPointerAccess(const Relocation& pReloc) const {
108     return true;
109   }
110 
111   /// getDebugStringOffset - get the offset from the relocation target. This is
112   /// used to get the debug string offset.
113   virtual uint32_t getDebugStringOffset(Relocation& pReloc) const = 0;
114 
115   /// applyDebugStringOffset - apply the relocation target to specific offset.
116   /// This is used to set the debug string offset.
117   virtual void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset) = 0;
118 
119  protected:
config()120   const LinkerConfig& config() const { return m_Config; }
121 
122  private:
123   const LinkerConfig& m_Config;
124 };
125 
126 }  // namespace mcld
127 
128 #endif  // MCLD_LD_RELOCATOR_H_
129