diff options
Diffstat (limited to 'include/llvm/CodeGen/MachineRelocation.h')
-rw-r--r-- | include/llvm/CodeGen/MachineRelocation.h | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h new file mode 100644 index 0000000000..b25ed3b007 --- /dev/null +++ b/include/llvm/CodeGen/MachineRelocation.h @@ -0,0 +1,188 @@ +//===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MachineRelocation class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINERELOCATION_H +#define LLVM_CODEGEN_MACHINERELOCATION_H + +#include "llvm/Support/DataTypes.h" +#include <cassert> + +namespace llvm { +class GlobalValue; + +/// MachineRelocation - This represents a target-specific relocation value, +/// produced by the code emitter. This relocation is resolved after the has +/// been emitted, either to an object file or to memory, when the target of the +/// relocation can be resolved. +/// +/// A relocation is made up of the following logical portions: +/// 1. An offset in the machine code buffer, the location to modify. +/// 2. A target specific relocation type (a number from 0 to 63). +/// 3. A symbol being referenced, either as a GlobalValue* or as a string. +/// 4. An optional constant value to be added to the reference. +/// 5. A bit, CanRewrite, which indicates to the JIT that a function stub is +/// not needed for the relocation. +/// 6. An index into the GOT, if the target uses a GOT +/// +class MachineRelocation { + /// OffsetTypeExternal - The low 24-bits of this value is the offset from the + /// start of the code buffer of the relocation to perform. Bit 24 of this is + /// set if Target should use ExtSym instead of GV, Bit 25 is the CanRewrite + /// bit, and the high 6 bits hold the relocation type. + // FIXME: with the additional types of relocatable things, rearrange the + // storage of things to be a bit more effiecient + unsigned OffsetTypeExternal; + union { + GlobalValue *GV; // If this is a pointer to an LLVM global + const char *ExtSym; // If this is a pointer to a named symbol + void *Result; // If this has been resolved to a resolved pointer + unsigned GOTIndex; // Index in the GOT of this symbol/global + unsigned CPool; // Index in the Constant Pool + } Target; + intptr_t ConstantVal; + bool GOTRelative; //out of bits in OffsetTypeExternal + bool isConstPool; + +public: + MachineRelocation(unsigned Offset, unsigned RelocationType, GlobalValue *GV, + intptr_t cst = 0, bool DoesntNeedFunctionStub = 0, + bool GOTrelative = 0) + : OffsetTypeExternal(Offset + (RelocationType << 26)), ConstantVal(cst), + GOTRelative(GOTrelative), isConstPool(0) { + assert((Offset & ~((1 << 24)-1)) == 0 && "Code offset too large!"); + assert((RelocationType & ~63) == 0 && "Relocation type too large!"); + Target.GV = GV; + if (DoesntNeedFunctionStub) + OffsetTypeExternal |= 1 << 25; + } + + MachineRelocation(unsigned Offset, unsigned RelocationType, const char *ES, + intptr_t cst = 0, bool GOTrelative = 0) + : OffsetTypeExternal(Offset + (1 << 24) + (RelocationType << 26)), + ConstantVal(cst), GOTRelative(GOTrelative), isConstPool(0) { + assert((Offset & ~((1 << 24)-1)) == 0 && "Code offset too large!"); + assert((RelocationType & ~63) == 0 && "Relocation type too large!"); + Target.ExtSym = ES; + } + + MachineRelocation(unsigned Offset, unsigned RelocationType, unsigned CPI, + intptr_t cst = 0) + : OffsetTypeExternal(Offset + (RelocationType << 26)), + ConstantVal(cst), GOTRelative(0), isConstPool(1) { + assert((Offset & ~((1 << 24)-1)) == 0 && "Code offset too large!"); + assert((RelocationType & ~63) == 0 && "Relocation type too large!"); + Target.CPool = CPI; + } + + /// getMachineCodeOffset - Return the offset into the code buffer that the + /// relocation should be performed. + unsigned getMachineCodeOffset() const { + return OffsetTypeExternal & ((1 << 24)-1); + } + + /// getRelocationType - Return the target-specific relocation ID for this + /// relocation. + unsigned getRelocationType() const { + return OffsetTypeExternal >> 26; + } + + /// getConstantVal - Get the constant value associated with this relocation. + /// This is often an offset from the symbol. + /// + intptr_t getConstantVal() const { + return ConstantVal; + } + + /// isGlobalValue - Return true if this relocation is a GlobalValue, as + /// opposed to a constant string. + bool isGlobalValue() const { + return (OffsetTypeExternal & (1 << 24)) == 0 && !isConstantPoolIndex(); + } + + /// isString - Return true if this is a constant string. + /// + bool isString() const { + return !isGlobalValue() && !isConstantPoolIndex(); + } + + /// isConstantPoolIndex - Return true if this is a constant pool reference. + /// + bool isConstantPoolIndex() const { + return isConstPool; + } + + /// isGOTRelative - Return true the target wants the index into the GOT of + /// the symbol rather than the address of the symbol. + bool isGOTRelative() const { + return GOTRelative; + } + + /// doesntNeedFunctionStub - This function returns true if the JIT for this + /// target is capable of directly handling the relocated instruction without + /// using a stub function. It is always conservatively correct for this flag + /// to be false, but targets can improve their compilation callback functions + /// to handle more general cases if they want improved performance. + bool doesntNeedFunctionStub() const { + return (OffsetTypeExternal & (1 << 25)) != 0; + } + + /// getGlobalValue - If this is a global value reference, return the + /// referenced global. + GlobalValue *getGlobalValue() const { + assert(isGlobalValue() && "This is not a global value reference!"); + return Target.GV; + } + + /// getString - If this is a string value, return the string reference. + /// + const char *getString() const { + assert(isString() && "This is not a string reference!"); + return Target.ExtSym; + } + + /// getConstantPoolIndex - If this is a const pool reference, return + /// the index into the constant pool. + unsigned getConstantPoolIndex() const { + assert(isConstantPoolIndex() && "This is not a constant pool reference!"); + return Target.CPool; + } + + /// getResultPointer - Once this has been resolved to point to an actual + /// address, this returns the pointer. + void *getResultPointer() const { + return Target.Result; + } + + /// setResultPointer - Set the result to the specified pointer value. + /// + void setResultPointer(void *Ptr) { + Target.Result = Ptr; + } + + /// setGOTIndex - Set the GOT index to a specific value. + void setGOTIndex(unsigned idx) { + Target.GOTIndex = idx; + } + + /// getGOTIndex - Once this has been resolved to an entry in the GOT, + /// this returns that index. The index is from the lowest address entry + /// in the GOT. + unsigned getGOTIndex() const { + return Target.GOTIndex; + } + +}; + +} + +#endif |