MachineRelocation.h [plain text]
#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
#define LLVM_CODEGEN_MACHINERELOCATION_H
#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
class GlobalValue;
class MachineBasicBlock;
class MachineRelocation {
enum AddressType {
isResult, isGV, isIndirectSym, isBB, isExtSym, isConstPool, isJumpTable, isGOTIndex };
uintptr_t Offset;
intptr_t ConstantVal;
union {
void *Result; GlobalValue *GV; MachineBasicBlock *MBB; const char *ExtSym; unsigned Index; unsigned GOTIndex; } Target;
unsigned TargetReloType : 6; AddressType AddrType : 4; bool MayNeedFarStub : 1; bool GOTRelative : 1; bool TargetResolve : 1;
public:
enum RelocationType {
VANILLA
};
static MachineRelocation getGV(uintptr_t offset, unsigned RelocationType,
GlobalValue *GV, intptr_t cst = 0,
bool MayNeedFarStub = 0,
bool GOTrelative = 0) {
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
MachineRelocation Result;
Result.Offset = offset;
Result.ConstantVal = cst;
Result.TargetReloType = RelocationType;
Result.AddrType = isGV;
Result.MayNeedFarStub = MayNeedFarStub;
Result.GOTRelative = GOTrelative;
Result.TargetResolve = false;
Result.Target.GV = GV;
return Result;
}
static MachineRelocation getIndirectSymbol(uintptr_t offset,
unsigned RelocationType,
GlobalValue *GV, intptr_t cst = 0,
bool MayNeedFarStub = 0,
bool GOTrelative = 0) {
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
MachineRelocation Result;
Result.Offset = offset;
Result.ConstantVal = cst;
Result.TargetReloType = RelocationType;
Result.AddrType = isIndirectSym;
Result.MayNeedFarStub = MayNeedFarStub;
Result.GOTRelative = GOTrelative;
Result.TargetResolve = false;
Result.Target.GV = GV;
return Result;
}
static MachineRelocation getBB(uintptr_t offset,unsigned RelocationType,
MachineBasicBlock *MBB, intptr_t cst = 0) {
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
MachineRelocation Result;
Result.Offset = offset;
Result.ConstantVal = cst;
Result.TargetReloType = RelocationType;
Result.AddrType = isBB;
Result.MayNeedFarStub = false;
Result.GOTRelative = false;
Result.TargetResolve = false;
Result.Target.MBB = MBB;
return Result;
}
static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType,
const char *ES, intptr_t cst = 0,
bool GOTrelative = 0,
bool NeedStub = true) {
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
MachineRelocation Result;
Result.Offset = offset;
Result.ConstantVal = cst;
Result.TargetReloType = RelocationType;
Result.AddrType = isExtSym;
Result.MayNeedFarStub = NeedStub;
Result.GOTRelative = GOTrelative;
Result.TargetResolve = false;
Result.Target.ExtSym = ES;
return Result;
}
static MachineRelocation getConstPool(uintptr_t offset,unsigned RelocationType,
unsigned CPI, intptr_t cst = 0,
bool letTargetResolve = false) {
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
MachineRelocation Result;
Result.Offset = offset;
Result.ConstantVal = cst;
Result.TargetReloType = RelocationType;
Result.AddrType = isConstPool;
Result.MayNeedFarStub = false;
Result.GOTRelative = false;
Result.TargetResolve = letTargetResolve;
Result.Target.Index = CPI;
return Result;
}
static MachineRelocation getJumpTable(uintptr_t offset,unsigned RelocationType,
unsigned JTI, intptr_t cst = 0,
bool letTargetResolve = false) {
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
MachineRelocation Result;
Result.Offset = offset;
Result.ConstantVal = cst;
Result.TargetReloType = RelocationType;
Result.AddrType = isJumpTable;
Result.MayNeedFarStub = false;
Result.GOTRelative = false;
Result.TargetResolve = letTargetResolve;
Result.Target.Index = JTI;
return Result;
}
intptr_t getMachineCodeOffset() const {
return Offset;
}
unsigned getRelocationType() const {
return TargetReloType;
}
intptr_t getConstantVal() const {
return ConstantVal;
}
void setConstantVal(intptr_t val) {
ConstantVal = val;
}
bool isGlobalValue() const {
return AddrType == isGV;
}
bool isIndirectSymbol() const {
return AddrType == isIndirectSym;
}
bool isBasicBlock() const {
return AddrType == isBB;
}
bool isExternalSymbol() const {
return AddrType == isExtSym;
}
bool isConstantPoolIndex() const {
return AddrType == isConstPool;
}
bool isJumpTableIndex() const {
return AddrType == isJumpTable;
}
bool isGOTRelative() const {
return GOTRelative;
}
bool mayNeedFarStub() const {
return MayNeedFarStub;
}
bool letTargetResolve() const {
return TargetResolve;
}
GlobalValue *getGlobalValue() const {
assert((isGlobalValue() || isIndirectSymbol()) &&
"This is not a global value reference!");
return Target.GV;
}
MachineBasicBlock *getBasicBlock() const {
assert(isBasicBlock() && "This is not a basic block reference!");
return Target.MBB;
}
const char *getExternalSymbol() const {
assert(isExternalSymbol() && "This is not an external symbol reference!");
return Target.ExtSym;
}
unsigned getConstantPoolIndex() const {
assert(isConstantPoolIndex() && "This is not a constant pool reference!");
return Target.Index;
}
unsigned getJumpTableIndex() const {
assert(isJumpTableIndex() && "This is not a jump table reference!");
return Target.Index;
}
void *getResultPointer() const {
assert(AddrType == isResult && "Result pointer isn't set yet!");
return Target.Result;
}
void setResultPointer(void *Ptr) {
Target.Result = Ptr;
AddrType = isResult;
}
void setGOTIndex(unsigned idx) {
AddrType = isGOTIndex;
Target.GOTIndex = idx;
}
unsigned getGOTIndex() const {
assert(AddrType == isGOTIndex);
return Target.GOTIndex;
}
};
}
#endif