C++程序  |  121行  |  3.55 KB

//===- Relocator.h --------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_RELOCATOR_H
#define MCLD_RELOCATOR_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif

#include <mcld/Fragment/Relocation.h>

namespace mcld
{

class FragmentLinker;
class TargetLDBackend;
class IRBuilder;
class Module;
class Input;

/** \class Relocator
 *  \brief Relocator provides the interface of performing relocations
 */
class Relocator
{
public:
  typedef Relocation::Type    Type;
  typedef Relocation::Address Address;
  typedef Relocation::DWord   DWord;
  typedef Relocation::SWord   SWord;
  typedef Relocation::Size    Size;

public:
  enum Result {
    OK,
    BadReloc,
    Overflow,
    Unsupport,
    Unknown
  };

public:
  Relocator(const LinkerConfig& pConfig)
    : m_Config(pConfig)
  {}

  virtual ~Relocator() = 0;

  /// apply - general apply function
  virtual Result applyRelocation(Relocation& pRelocation) = 0;

  /// scanRelocation - When read in relocations, backend can do any modification
  /// to relocation and generate empty entries, such as GOT, dynamic relocation
  /// entries and other target dependent entries. These entries are generated
  /// for layout to adjust the ouput offset.
  /// @param pReloc - a read in relocation entry
  /// @param pInputSym - the input LDSymbol of relocation target symbol
  /// @param pSection - the section of relocation applying target
  virtual void scanRelocation(Relocation& pReloc,
                              IRBuilder& pBuilder,
                              Module& pModule,
                              LDSection& pSection) = 0;

  /// initializeScan - do initialization before scan relocations in pInput
  /// @return - return true for initialization success
  virtual bool initializeScan(Input& pInput)
  { return true; }

  /// finalizeScan - do finalization after scan relocations in pInput
  /// @return - return true for finalization success
  virtual bool finalizeScan(Input& pInput)
  { return true; }

  /// initializeApply - do initialization before apply relocations in pInput
  /// @return - return true for initialization success
  virtual bool initializeApply(Input& pInput)
  { return true; }

  /// finalizeApply - do finalization after apply relocations in pInput
  /// @return - return true for finalization success
  virtual bool finalizeApply(Input& pInput)
  { return true; }

  /// partialScanRelocation - When doing partial linking, backend can do any
  /// modification to relocation to fix the relocation offset after section
  /// merge
  /// @param pReloc - a read in relocation entry
  /// @param pInputSym - the input LDSymbol of relocation target symbol
  /// @param pSection - the section of relocation applying target
  virtual void partialScanRelocation(Relocation& pReloc,
                                     Module& pModule,
                                     const LDSection& pSection);

  // ------ observers -----//
  virtual TargetLDBackend& getTarget() = 0;

  virtual const TargetLDBackend& getTarget() const = 0;

  /// getName - get the name of a relocation
  virtual const char* getName(Type pType) const = 0;

  /// getSize - get the size of a relocation in bit
  virtual Size getSize(Type pType) const = 0;

protected:
  const LinkerConfig& config() const { return m_Config; }

private:
  const LinkerConfig& m_Config;
};

} // namespace of mcld

#endif