//===- Stub.h -------------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_FRAGMENT_STUB_H
#define MCLD_FRAGMENT_STUB_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <llvm/Support/DataTypes.h>
#include <mcld/Fragment/Fragment.h>
#include <mcld/Fragment/Relocation.h>
#include <vector>
#include <string>
namespace mcld
{
class Relocation;
class ResolveInfo;
class Stub: public Fragment
{
public:
typedef Relocation::DWord DWord;
typedef Relocation::SWord SWord;
typedef Relocation::Type Type;
class Fixup
{
public:
Fixup(DWord pOffset, SWord pAddend, Type pType)
: m_Offset(pOffset), m_Addend(pAddend), m_Type(pType)
{ }
~Fixup()
{ }
DWord offset() const { return m_Offset; }
SWord addend() const { return m_Addend; }
Type type() const { return m_Type; }
private:
DWord m_Offset;
SWord m_Addend;
Type m_Type;
};
public:
typedef std::vector<Fixup*> FixupListType;
typedef FixupListType::iterator fixup_iterator;
typedef FixupListType::const_iterator const_fixup_iterator;
public:
Stub();
virtual ~Stub();
/// clone - clone function for stub factory to create the corresponding stub
Stub* clone() { return doClone(); }
/// isMyDuty - return true when the pReloc is problematic and the stub is able
/// to fix it!
virtual bool isMyDuty(const class Relocation& pReloc,
uint64_t pSource,
uint64_t pTargetSymValue) const = 0;
/// name - name of this stub
virtual const std::string& name() const = 0;
/// getContent - content of the stub
virtual const uint8_t* getContent() const = 0;
/// size - size of the stub
virtual size_t size() const = 0;
/// alignment - alignment of the stub
virtual size_t alignment() const = 0;
/// symInfo - ResolveInfo of this Stub
ResolveInfo* symInfo() { return m_pSymInfo; }
const ResolveInfo* symInfo() const { return m_pSymInfo; }
/// symValue - initial value for stub's symbol
virtual uint64_t initSymValue() const { return 0x0; }
/// ----- Fixup ----- ///
fixup_iterator fixup_begin() { return m_FixupList.begin(); }
const_fixup_iterator fixup_begin() const { return m_FixupList.begin(); }
fixup_iterator fixup_end() { return m_FixupList.end(); }
const_fixup_iterator fixup_end() const { return m_FixupList.end(); }
/// ----- modifiers ----- ///
void setSymInfo(ResolveInfo* pSymInfo);
// Stub is a kind of Fragment with type of Stub
static bool classof(const Fragment *F)
{ return F->getKind() == Fragment::Stub; }
static bool classof(const Stub *)
{ return true; }
protected:
/// addFixup - add a fixup for this stub to build a relocation
void addFixup(DWord pOffset, SWord pAddend, Type pType);
/// addFixup - add a fixup from a existing fixup of the prototype
void addFixup(const Fixup& pFixup);
private:
/// doClone - when adding a backend stub, we should implement this function
virtual Stub* doClone() = 0;
private:
ResolveInfo* m_pSymInfo;
FixupListType m_FixupList;
};
} // namespace of mcld
#endif