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   enum AddressType {
00039     isResult,         // Relocation has be transformed into its result pointer.
00040     isGV,             // The Target.GV field is valid.
00041     isExtSym,         // The Target.ExtSym field is valid.
00042     isConstPool,      // Relocation of constant pool address.
00043     isJumpTable,      // Relocation of jump table address.
00044     isGOTIndex        // The Target.GOTIndex field is valid.
00045   };
00046   
00047   /// Offset - This is the offset from the start of the code buffer of the
00048   /// relocation to perform.
00049   intptr_t Offset;
00050   
00051   /// ConstantVal - A field that may be used by the target relocation type.
00052   intptr_t ConstantVal;
00053 
00054   union {
00055     void *Result;        // If this has been resolved to a resolved pointer
00056     GlobalValue *GV;     // If this is a pointer to an LLVM global
00057     const char *ExtSym;  // If this is a pointer to a named symbol
00058     unsigned Index;      // Constant pool / jump table index
00059     unsigned GOTIndex;   // Index in the GOT of this symbol/global
00060   } Target;
00061 
00062   unsigned TargetReloType : 6; // The target relocation ID.
00063   AddressType AddrType    : 3; // The field of Target to use.
00064   bool DoesntNeedFnStub   : 1; // True if we don't need a fn stub.
00065   bool GOTRelative        : 1; // Should this relocation be relative to the GOT?
00066 
00067 public:
00068   /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue.
00069   ///
00070   static MachineRelocation getGV(intptr_t offset, unsigned RelocationType, 
00071                                  GlobalValue *GV, intptr_t cst = 0,
00072                                  bool DoesntNeedFunctionStub = 0,
00073                                  bool GOTrelative = 0) {
00074     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
00075     MachineRelocation Result;
00076     Result.Offset = offset;
00077     Result.ConstantVal = cst;
00078     Result.TargetReloType = RelocationType;
00079     Result.AddrType = isGV;
00080     Result.DoesntNeedFnStub = DoesntNeedFunctionStub;
00081     Result.GOTRelative = GOTrelative;
00082     Result.Target.GV = GV;
00083     return Result;
00084   }
00085 
00086   /// MachineRelocation::getExtSym - Return a relocation entry for an external
00087   /// symbol, like "free".
00088   ///
00089   static MachineRelocation getExtSym(intptr_t offset, unsigned RelocationType, 
00090                                      const char *ES, intptr_t cst = 0,
00091                                      bool GOTrelative = 0) {
00092     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
00093     MachineRelocation Result;
00094     Result.Offset = offset;
00095     Result.ConstantVal = cst;
00096     Result.TargetReloType = RelocationType;
00097     Result.AddrType = isExtSym;
00098     Result.DoesntNeedFnStub = false;
00099     Result.GOTRelative = GOTrelative;
00100     Result.Target.ExtSym = ES;
00101     return Result;
00102   }
00103 
00104   /// MachineRelocation::getConstPool - Return a relocation entry for a constant
00105   /// pool entry.
00106   ///
00107   static MachineRelocation getConstPool(intptr_t offset,unsigned RelocationType,
00108                                         unsigned CPI, intptr_t cst = 0) {
00109     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
00110     MachineRelocation Result;
00111     Result.Offset = offset;
00112     Result.ConstantVal = cst;
00113     Result.TargetReloType = RelocationType;
00114     Result.AddrType = isConstPool;
00115     Result.DoesntNeedFnStub = false;
00116     Result.GOTRelative = false;
00117     Result.Target.Index = CPI;
00118     return Result;
00119   }
00120 
00121   /// MachineRelocation::getJumpTable - Return a relocation entry for a jump
00122   /// table entry.
00123   ///
00124   static MachineRelocation getJumpTable(intptr_t offset,unsigned RelocationType,
00125                                         unsigned JTI, intptr_t cst = 0) {
00126     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
00127     MachineRelocation Result;
00128     Result.Offset = offset;
00129     Result.ConstantVal = cst;
00130     Result.TargetReloType = RelocationType;
00131     Result.AddrType = isJumpTable;
00132     Result.DoesntNeedFnStub = false;
00133     Result.GOTRelative = false;
00134     Result.Target.Index = JTI;
00135     return Result;
00136   }
00137 
00138   /// getMachineCodeOffset - Return the offset into the code buffer that the
00139   /// relocation should be performed.
00140   intptr_t getMachineCodeOffset() const {
00141     return Offset;
00142   }
00143 
00144   /// getRelocationType - Return the target-specific relocation ID for this
00145   /// relocation.
00146   unsigned getRelocationType() const {
00147     return TargetReloType;
00148   }
00149 
00150   /// getConstantVal - Get the constant value associated with this relocation.
00151   /// This is often an offset from the symbol.
00152   ///
00153   intptr_t getConstantVal() const {
00154     return ConstantVal;
00155   }
00156 
00157   /// isGlobalValue - Return true if this relocation is a GlobalValue, as
00158   /// opposed to a constant string.
00159   bool isGlobalValue() const {
00160     return AddrType == isGV;
00161   }
00162 
00163   /// isString - Return true if this is a constant string.
00164   ///
00165   bool isString() const {
00166     return AddrType == isExtSym;
00167   }
00168 
00169   /// isConstantPoolIndex - Return true if this is a constant pool reference.
00170   ///
00171   bool isConstantPoolIndex() const {
00172     return AddrType == isConstPool;
00173   }
00174 
00175   /// isJumpTableIndex - Return true if this is a jump table reference.
00176   ///
00177   bool isJumpTableIndex() const {
00178     return AddrType == isJumpTable;
00179   }
00180 
00181   /// isGOTRelative - Return true the target wants the index into the GOT of
00182   /// the symbol rather than the address of the symbol.
00183   bool isGOTRelative() const {
00184     return GOTRelative;
00185   }
00186 
00187   /// doesntNeedFunctionStub - This function returns true if the JIT for this
00188   /// target is capable of directly handling the relocated instruction without
00189   /// using a stub function.  It is always conservatively correct for this flag
00190   /// to be false, but targets can improve their compilation callback functions
00191   /// to handle more general cases if they want improved performance.
00192   bool doesntNeedFunctionStub() const {
00193     return DoesntNeedFnStub;
00194   }
00195 
00196   /// getGlobalValue - If this is a global value reference, return the
00197   /// referenced global.
00198   GlobalValue *getGlobalValue() const {
00199     assert(isGlobalValue() && "This is not a global value reference!");
00200     return Target.GV;
00201   }
00202 
00203   /// getString - If this is a string value, return the string reference.
00204   ///
00205   const char *getString() const {
00206     assert(isString() && "This is not a string reference!");
00207     return Target.ExtSym;
00208   }
00209 
00210   /// getConstantPoolIndex - If this is a const pool reference, return
00211   /// the index into the constant pool.
00212   unsigned getConstantPoolIndex() const {
00213     assert(isConstantPoolIndex() && "This is not a constant pool reference!");
00214     return Target.Index;
00215   }
00216 
00217   /// getJumpTableIndex - If this is a jump table reference, return
00218   /// the index into the jump table.
00219   unsigned getJumpTableIndex() const {
00220     assert(isJumpTableIndex() && "This is not a jump table reference!");
00221     return Target.Index;
00222   }
00223 
00224   /// getResultPointer - Once this has been resolved to point to an actual
00225   /// address, this returns the pointer.
00226   void *getResultPointer() const {
00227     assert(AddrType == isResult && "Result pointer isn't set yet!");
00228     return Target.Result;
00229   }
00230 
00231   /// setResultPointer - Set the result to the specified pointer value.
00232   ///
00233   void setResultPointer(void *Ptr) {
00234     Target.Result = Ptr;
00235     AddrType = isResult;
00236   }
00237 
00238   /// setGOTIndex - Set the GOT index to a specific value.
00239   void setGOTIndex(unsigned idx) {
00240     AddrType = isGOTIndex;
00241     Target.GOTIndex = idx;
00242   }
00243 
00244   /// getGOTIndex - Once this has been resolved to an entry in the GOT,
00245   /// this returns that index.  The index is from the lowest address entry
00246   /// in the GOT.
00247   unsigned getGOTIndex() const {
00248     assert(AddrType == isGOTIndex);
00249     return Target.GOTIndex;
00250   }
00251 };
00252 }
00253 
00254 #endif