1d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===- Relocator.h --------------------------------------------------------===//
2d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//
3d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//                     The MCLinker Project
4d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//
5d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// This file is distributed under the University of Illinois Open Source
6d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// License. See LICENSE.TXT for details.
7d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//
8d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_LD_RELOCATOR_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_LD_RELOCATOR_H_
11d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Relocation.h"
13d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Input;
17f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass IRBuilder;
18f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass Module;
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass TargetLDBackend;
20d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
21d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/** \class Relocator
22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao *  \brief Relocator provides the interface of performing relocations
23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao */
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Relocator {
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef Relocation::Type Type;
27d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  typedef Relocation::Address Address;
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef Relocation::DWord DWord;
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef Relocation::SWord SWord;
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef Relocation::Size Size;
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  enum Result { OK, BadReloc, Overflow, Unsupported, Unknown };
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  explicit Relocator(const LinkerConfig& pConfig) : m_Config(pConfig) {}
37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual ~Relocator() = 0;
39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// apply - general apply function
41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  virtual Result applyRelocation(Relocation& pRelocation) = 0;
42d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// scanRelocation - When read in relocations, backend can do any modification
44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// to relocation and generate empty entries, such as GOT, dynamic relocation
45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// entries and other target dependent entries. These entries are generated
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// for layout to adjust the ouput offset.
47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @param pReloc - a read in relocation entry
48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @param pInputSym - the input LDSymbol of relocation target symbol
49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @param pSection - the section of relocation applying target
5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// @param pInput - the input file of relocation
51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void scanRelocation(Relocation& pReloc,
52f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                              IRBuilder& pBuilder,
53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                              Module& pModule,
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              LDSection& pSection,
5587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              Input& pInput) = 0;
5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /// issueUndefRefError - Provides a basic version for undefined reference
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /// dump.
5987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// It will handle the filename and function name automatically.
6087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// @param pReloc - a read in relocation entry
6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// @param pSection - the section of relocation applying target
6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// @ param pInput - the input file of relocation
6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void issueUndefRef(Relocation& pReloc,
6487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                             LDSection& pSection,
6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                             Input& pInput);
66f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// initializeScan - do initialization before scan relocations in pInput
68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @return - return true for initialization success
6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool initializeScan(Input& pInput) { return true; }
70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// finalizeScan - do finalization after scan relocations in pInput
72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @return - return true for finalization success
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool finalizeScan(Input& pInput) { return true; }
74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// initializeApply - do initialization before apply relocations in pInput
76f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @return - return true for initialization success
7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool initializeApply(Input& pInput) { return true; }
78f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
79f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// finalizeApply - do finalization after apply relocations in pInput
80f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @return - return true for finalization success
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool finalizeApply(Input& pInput) { return true; }
82f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// partialScanRelocation - When doing partial linking, backend can do any
84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// modification to relocation to fix the relocation offset after section
85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// merge
86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @param pReloc - a read in relocation entry
87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @param pInputSym - the input LDSymbol of relocation target symbol
88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @param pSection - the section of relocation applying target
89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void partialScanRelocation(Relocation& pReloc,
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                     Module& pModule);
91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
92d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // ------ observers -----//
93d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  virtual TargetLDBackend& getTarget() = 0;
94d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
95d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  virtual const TargetLDBackend& getTarget() const = 0;
96d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// getName - get the name of a relocation
98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  virtual const char* getName(Type pType) const = 0;
99d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// getSize - get the size of a relocation in bit
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual Size getSize(Type pType) const = 0;
102f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1030dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// mayHaveFunctionPointerAccess - check if the given reloc would possibly
1040dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// access a function pointer.
1050dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// Note: Each target relocator should override this function, or be
1060dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// conservative and return true to avoid getting folded.
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool mayHaveFunctionPointerAccess(const Relocation& pReloc) const {
10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return true;
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /// getDebugStringOffset - get the offset from the relocation target. This is
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /// used to get the debug string offset.
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual uint32_t getDebugStringOffset(Relocation& pReloc) const = 0;
1140dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /// applyDebugStringOffset - apply the relocation target to specific offset.
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /// This is used to set the debug string offset.
11737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset) = 0;
11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
11937b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
120f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  const LinkerConfig& config() const { return m_Config; }
121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  const LinkerConfig& m_Config;
124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao};
125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
127d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_LD_RELOCATOR_H_
129