LLVM API Documentation

MachineRelocation.h

Go to the documentation of this file.
00001 //===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the MachineRelocation class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CODEGEN_MACHINERELOCATION_H
00015 #define LLVM_CODEGEN_MACHINERELOCATION_H
00016 
00017 #include "llvm/Support/DataTypes.h"
00018 #include <cassert>
00019 
00020 namespace llvm {
00021 class GlobalValue;
00022 
00023 /// MachineRelocation - This represents a target-specific relocation value,
00024 /// produced by the code emitter.  This relocation is resolved after the has
00025 /// been emitted, either to an object file or to memory, when the target of the
00026 /// relocation can be resolved.
00027 ///
00028 /// A relocation is made up of the following logical portions:
00029 ///   1. An offset in the machine code buffer, the location to modify.
00030 ///   2. A target specific relocation type (a number from 0 to 63).
00031 ///   3. A symbol being referenced, either as a GlobalValue* or as a string.
00032 ///   4. An optional constant value to be added to the reference.
00033 ///   5. A bit, CanRewrite, which indicates to the JIT that a function stub is
00034 ///      not needed for the relocation.
00035 ///   6. An index into the GOT, if the target uses a GOT
00036 ///
00037 class MachineRelocation {
00038   /// OffsetTypeExternal - The low 24-bits of this value is the offset from the
00039   /// start of the code buffer of the relocation to perform.  Bit 24 of this is
00040   /// set if Target should use ExtSym instead of GV, Bit 25 is the CanRewrite
00041   /// bit, and the high 6 bits hold the relocation type.
00042   // FIXME: with the additional types of relocatable things, rearrange the
00043   // storage of things to be a bit more effiecient
00044   unsigned OffsetTypeExternal;
00045   union {
00046     GlobalValue *GV;     // If this is a pointer to an LLVM global
00047     const char *ExtSym;  // If this is a pointer to a named symbol
00048     void *Result;        // If this has been resolved to a resolved pointer
00049     unsigned GOTIndex;   // Index in the GOT of this symbol/global
00050     unsigned CPool;      // Index in the Constant Pool
00051   } Target;
00052   intptr_t ConstantVal;
00053   bool GOTRelative; //out of bits in OffsetTypeExternal
00054   bool isConstPool;
00055 
00056 public:
00057   MachineRelocation(unsigned Offset, unsigned RelocationType, GlobalValue *GV,
00058                     intptr_t cst = 0, bool DoesntNeedFunctionStub = 0,
00059                     bool GOTrelative = 0)
00060     : OffsetTypeExternal(Offset + (RelocationType << 26)), ConstantVal(cst),
00061       GOTRelative(GOTrelative), isConstPool(0) {
00062     assert((Offset & ~((1 << 24)-1)) == 0 && "Code offset too large!");
00063     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
00064     Target.GV = GV;
00065     if (DoesntNeedFunctionStub)
00066       OffsetTypeExternal |= 1 << 25;
00067   }
00068 
00069   MachineRelocation(unsigned Offset, unsigned RelocationType, const char *ES,
00070                     intptr_t cst = 0, bool GOTrelative = 0)
00071     : OffsetTypeExternal(Offset + (1 << 24) + (RelocationType << 26)),
00072       ConstantVal(cst), GOTRelative(GOTrelative), isConstPool(0) {
00073     assert((Offset & ~((1 << 24)-1)) == 0 && "Code offset too large!");
00074     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
00075     Target.ExtSym = ES;
00076   }
00077 
00078   MachineRelocation(unsigned Offset, unsigned RelocationType, unsigned CPI,
00079                     intptr_t cst = 0)
00080     : OffsetTypeExternal(Offset + (RelocationType << 26)),
00081       ConstantVal(cst), GOTRelative(0), isConstPool(1) {
00082     assert((Offset & ~((1 << 24)-1)) == 0 && "Code offset too large!");
00083     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
00084     Target.CPool = CPI;
00085   }
00086 
00087   /// getMachineCodeOffset - Return the offset into the code buffer that the
00088   /// relocation should be performed.
00089   unsigned getMachineCodeOffset() const {
00090     return OffsetTypeExternal & ((1 << 24)-1);
00091   }
00092 
00093   /// getRelocationType - Return the target-specific relocation ID for this
00094   /// relocation.
00095   unsigned getRelocationType() const {
00096     return OffsetTypeExternal >> 26;
00097   }
00098 
00099   /// getConstantVal - Get the constant value associated with this relocation.
00100   /// This is often an offset from the symbol.
00101   ///
00102   intptr_t getConstantVal() const {
00103     return ConstantVal;
00104   }
00105 
00106   /// isGlobalValue - Return true if this relocation is a GlobalValue, as
00107   /// opposed to a constant string.
00108   bool isGlobalValue() const {
00109     return (OffsetTypeExternal & (1 << 24)) == 0 && !isConstantPoolIndex();
00110   }
00111 
00112   /// isString - Return true if this is a constant string.
00113   ///
00114   bool isString() const {
00115     return !isGlobalValue() && !isConstantPoolIndex();
00116   }
00117 
00118   /// isConstantPoolIndex - Return true if this is a constant pool reference.
00119   ///
00120   bool isConstantPoolIndex() const {
00121     return isConstPool;
00122   }
00123 
00124   /// isGOTRelative - Return true the target wants the index into the GOT of
00125   /// the symbol rather than the address of the symbol.
00126   bool isGOTRelative() const {
00127     return GOTRelative;
00128   }
00129 
00130   /// doesntNeedFunctionStub - This function returns true if the JIT for this
00131   /// target is capable of directly handling the relocated instruction without
00132   /// using a stub function.  It is always conservatively correct for this flag
00133   /// to be false, but targets can improve their compilation callback functions
00134   /// to handle more general cases if they want improved performance.
00135   bool doesntNeedFunctionStub() const {
00136     return (OffsetTypeExternal & (1 << 25)) != 0;
00137   }
00138 
00139   /// getGlobalValue - If this is a global value reference, return the
00140   /// referenced global.
00141   GlobalValue *getGlobalValue() const {
00142     assert(isGlobalValue() && "This is not a global value reference!");
00143     return Target.GV;
00144   }
00145 
00146   /// getString - If this is a string value, return the string reference.
00147   ///
00148   const char *getString() const {
00149     assert(isString() && "This is not a string reference!");
00150     return Target.ExtSym;
00151   }
00152 
00153   /// getConstantPoolIndex - If this is a const pool reference, return
00154   /// the index into the constant pool.
00155   unsigned getConstantPoolIndex() const {
00156     assert(isConstantPoolIndex() && "This is not a constant pool reference!");
00157     return Target.CPool;
00158   }
00159 
00160   /// getResultPointer - Once this has been resolved to point to an actual
00161   /// address, this returns the pointer.
00162   void *getResultPointer() const {
00163     return Target.Result;
00164   }
00165 
00166   /// setResultPointer - Set the result to the specified pointer value.
00167   ///
00168   void setResultPointer(void *Ptr) {
00169     Target.Result = Ptr;
00170   }
00171 
00172   /// setGOTIndex - Set the GOT index to a specific value.
00173   void setGOTIndex(unsigned idx) {
00174     Target.GOTIndex = idx;
00175   }
00176 
00177   /// getGOTIndex - Once this has been resolved to an entry in the GOT,
00178   /// this returns that index.  The index is from the lowest address entry
00179   /// in the GOT.
00180   unsigned getGOTIndex() const {
00181     return Target.GOTIndex;
00182   }
00183 
00184 };
00185 
00186 }
00187 
00188 #endif