Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 1 | //===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===// |
Misha Brukman | ea61c35 | 2005-04-21 20:39:54 +0000 | [diff] [blame] | 2 | // |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by the LLVM research group and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
Misha Brukman | ea61c35 | 2005-04-21 20:39:54 +0000 | [diff] [blame] | 7 | // |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file defines the MachineRelocation class. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_CODEGEN_MACHINERELOCATION_H |
| 15 | #define LLVM_CODEGEN_MACHINERELOCATION_H |
| 16 | |
| 17 | #include "llvm/Support/DataTypes.h" |
Chris Lattner | 4e2239d | 2004-11-20 23:40:54 +0000 | [diff] [blame] | 18 | #include <cassert> |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 19 | |
| 20 | namespace llvm { |
| 21 | class GlobalValue; |
| 22 | |
| 23 | /// MachineRelocation - This represents a target-specific relocation value, |
| 24 | /// produced by the code emitter. This relocation is resolved after the has |
| 25 | /// been emitted, either to an object file or to memory, when the target of the |
| 26 | /// relocation can be resolved. |
| 27 | /// |
| 28 | /// A relocation is made up of the following logical portions: |
| 29 | /// 1. An offset in the machine code buffer, the location to modify. |
Chris Lattner | 765da91 | 2004-11-21 03:27:13 +0000 | [diff] [blame] | 30 | /// 2. A target specific relocation type (a number from 0 to 63). |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 31 | /// 3. A symbol being referenced, either as a GlobalValue* or as a string. |
| 32 | /// 4. An optional constant value to be added to the reference. |
Chris Lattner | 765da91 | 2004-11-21 03:27:13 +0000 | [diff] [blame] | 33 | /// 5. A bit, CanRewrite, which indicates to the JIT that a function stub is |
| 34 | /// not needed for the relocation. |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 35 | /// 6. An index into the GOT, if the target uses a GOT |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 36 | /// |
| 37 | class MachineRelocation { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 38 | enum AddressType { |
| 39 | isResult, // Relocation has be transformed into its result pointer. |
| 40 | isGV, // The Target.GV field is valid. |
| 41 | isExtSym, // The Target.ExtSym field is valid. |
Evan Cheng | 52b510b | 2006-06-23 01:02:37 +0000 | [diff] [blame^] | 42 | isConstPool, // Relocation of constant pool address. |
| 43 | isJumpTable, // Relocation of jump table address. |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 44 | isGOTIndex // The Target.GOTIndex field is valid. |
| 45 | }; |
| 46 | |
| 47 | /// Offset - This is the offset from the start of the code buffer of the |
| 48 | /// relocation to perform. |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 49 | intptr_t Offset; |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 50 | |
| 51 | /// ConstantVal - A field that may be used by the target relocation type. |
| 52 | intptr_t ConstantVal; |
| 53 | |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 54 | union { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 55 | void *Result; // If this has been resolved to a resolved pointer |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 56 | GlobalValue *GV; // If this is a pointer to an LLVM global |
| 57 | const char *ExtSym; // If this is a pointer to a named symbol |
Evan Cheng | 52b510b | 2006-06-23 01:02:37 +0000 | [diff] [blame^] | 58 | unsigned Index; // Constant pool / jump table index |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 59 | unsigned GOTIndex; // Index in the GOT of this symbol/global |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 60 | } Target; |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 61 | |
| 62 | unsigned TargetReloType : 6; // The target relocation ID. |
| 63 | AddressType AddrType : 3; // The field of Target to use. |
| 64 | bool DoesntNeedFnStub : 1; // True if we don't need a fn stub. |
| 65 | bool GOTRelative : 1; // Should this relocation be relative to the GOT? |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 66 | |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 67 | public: |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 68 | /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue. |
| 69 | /// |
| 70 | static MachineRelocation getGV(intptr_t offset, unsigned RelocationType, |
| 71 | GlobalValue *GV, intptr_t cst = 0, |
| 72 | bool DoesntNeedFunctionStub = 0, |
| 73 | bool GOTrelative = 0) { |
Chris Lattner | 765da91 | 2004-11-21 03:27:13 +0000 | [diff] [blame] | 74 | assert((RelocationType & ~63) == 0 && "Relocation type too large!"); |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 75 | MachineRelocation Result; |
| 76 | Result.Offset = offset; |
| 77 | Result.ConstantVal = cst; |
| 78 | Result.TargetReloType = RelocationType; |
| 79 | Result.AddrType = isGV; |
| 80 | Result.DoesntNeedFnStub = DoesntNeedFunctionStub; |
| 81 | Result.GOTRelative = GOTrelative; |
| 82 | Result.Target.GV = GV; |
| 83 | return Result; |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 84 | } |
| 85 | |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 86 | /// MachineRelocation::getExtSym - Return a relocation entry for an external |
| 87 | /// symbol, like "free". |
| 88 | /// |
| 89 | static MachineRelocation getExtSym(intptr_t offset, unsigned RelocationType, |
| 90 | const char *ES, intptr_t cst = 0, |
| 91 | bool GOTrelative = 0) { |
Chris Lattner | 765da91 | 2004-11-21 03:27:13 +0000 | [diff] [blame] | 92 | assert((RelocationType & ~63) == 0 && "Relocation type too large!"); |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 93 | MachineRelocation Result; |
| 94 | Result.Offset = offset; |
| 95 | Result.ConstantVal = cst; |
| 96 | Result.TargetReloType = RelocationType; |
| 97 | Result.AddrType = isExtSym; |
| 98 | Result.DoesntNeedFnStub = false; |
| 99 | Result.GOTRelative = GOTrelative; |
| 100 | Result.Target.ExtSym = ES; |
| 101 | return Result; |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 102 | } |
| 103 | |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 104 | /// MachineRelocation::getConstPool - Return a relocation entry for a constant |
| 105 | /// pool entry. |
| 106 | /// |
| 107 | static MachineRelocation getConstPool(intptr_t offset,unsigned RelocationType, |
| 108 | unsigned CPI, intptr_t cst = 0) { |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 109 | assert((RelocationType & ~63) == 0 && "Relocation type too large!"); |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 110 | MachineRelocation Result; |
| 111 | Result.Offset = offset; |
| 112 | Result.ConstantVal = cst; |
| 113 | Result.TargetReloType = RelocationType; |
| 114 | Result.AddrType = isConstPool; |
| 115 | Result.DoesntNeedFnStub = false; |
| 116 | Result.GOTRelative = false; |
Evan Cheng | 52b510b | 2006-06-23 01:02:37 +0000 | [diff] [blame^] | 117 | Result.Target.Index = CPI; |
| 118 | return Result; |
| 119 | } |
| 120 | |
| 121 | /// MachineRelocation::getJumpTable - Return a relocation entry for a jump |
| 122 | /// table entry. |
| 123 | /// |
| 124 | static MachineRelocation getJumpTable(intptr_t offset,unsigned RelocationType, |
| 125 | unsigned JTI, intptr_t cst = 0) { |
| 126 | assert((RelocationType & ~63) == 0 && "Relocation type too large!"); |
| 127 | MachineRelocation Result; |
| 128 | Result.Offset = offset; |
| 129 | Result.ConstantVal = cst; |
| 130 | Result.TargetReloType = RelocationType; |
| 131 | Result.AddrType = isJumpTable; |
| 132 | Result.DoesntNeedFnStub = false; |
| 133 | Result.GOTRelative = false; |
| 134 | Result.Target.Index = JTI; |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 135 | return Result; |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 136 | } |
| 137 | |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 138 | /// getMachineCodeOffset - Return the offset into the code buffer that the |
| 139 | /// relocation should be performed. |
Chris Lattner | 5a032de | 2006-05-03 20:30:20 +0000 | [diff] [blame] | 140 | intptr_t getMachineCodeOffset() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 141 | return Offset; |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 142 | } |
| 143 | |
Chris Lattner | fab11a7 | 2004-11-20 03:43:50 +0000 | [diff] [blame] | 144 | /// getRelocationType - Return the target-specific relocation ID for this |
| 145 | /// relocation. |
| 146 | unsigned getRelocationType() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 147 | return TargetReloType; |
Chris Lattner | fab11a7 | 2004-11-20 03:43:50 +0000 | [diff] [blame] | 148 | } |
| 149 | |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 150 | /// getConstantVal - Get the constant value associated with this relocation. |
| 151 | /// This is often an offset from the symbol. |
| 152 | /// |
| 153 | intptr_t getConstantVal() const { |
| 154 | return ConstantVal; |
| 155 | } |
| 156 | |
| 157 | /// isGlobalValue - Return true if this relocation is a GlobalValue, as |
| 158 | /// opposed to a constant string. |
| 159 | bool isGlobalValue() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 160 | return AddrType == isGV; |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | /// isString - Return true if this is a constant string. |
| 164 | /// |
| 165 | bool isString() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 166 | return AddrType == isExtSym; |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 167 | } |
| 168 | |
| 169 | /// isConstantPoolIndex - Return true if this is a constant pool reference. |
| 170 | /// |
| 171 | bool isConstantPoolIndex() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 172 | return AddrType == isConstPool; |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 173 | } |
| 174 | |
Evan Cheng | 52b510b | 2006-06-23 01:02:37 +0000 | [diff] [blame^] | 175 | /// isJumpTableIndex - Return true if this is a jump table reference. |
| 176 | /// |
| 177 | bool isJumpTableIndex() const { |
| 178 | return AddrType == isJumpTable; |
| 179 | } |
| 180 | |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 181 | /// isGOTRelative - Return true the target wants the index into the GOT of |
| 182 | /// the symbol rather than the address of the symbol. |
| 183 | bool isGOTRelative() const { |
| 184 | return GOTRelative; |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 185 | } |
| 186 | |
Chris Lattner | 765da91 | 2004-11-21 03:27:13 +0000 | [diff] [blame] | 187 | /// doesntNeedFunctionStub - This function returns true if the JIT for this |
| 188 | /// target is capable of directly handling the relocated instruction without |
| 189 | /// using a stub function. It is always conservatively correct for this flag |
| 190 | /// to be false, but targets can improve their compilation callback functions |
| 191 | /// to handle more general cases if they want improved performance. |
| 192 | bool doesntNeedFunctionStub() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 193 | return DoesntNeedFnStub; |
Chris Lattner | 765da91 | 2004-11-21 03:27:13 +0000 | [diff] [blame] | 194 | } |
| 195 | |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 196 | /// getGlobalValue - If this is a global value reference, return the |
| 197 | /// referenced global. |
| 198 | GlobalValue *getGlobalValue() const { |
| 199 | assert(isGlobalValue() && "This is not a global value reference!"); |
| 200 | return Target.GV; |
| 201 | } |
| 202 | |
| 203 | /// getString - If this is a string value, return the string reference. |
| 204 | /// |
| 205 | const char *getString() const { |
| 206 | assert(isString() && "This is not a string reference!"); |
| 207 | return Target.ExtSym; |
| 208 | } |
| 209 | |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 210 | /// getConstantPoolIndex - If this is a const pool reference, return |
| 211 | /// the index into the constant pool. |
| 212 | unsigned getConstantPoolIndex() const { |
| 213 | assert(isConstantPoolIndex() && "This is not a constant pool reference!"); |
Evan Cheng | 52b510b | 2006-06-23 01:02:37 +0000 | [diff] [blame^] | 214 | return Target.Index; |
| 215 | } |
| 216 | |
| 217 | /// getJumpTableIndex - If this is a jump table reference, return |
| 218 | /// the index into the jump table. |
| 219 | unsigned getJumpTableIndex() const { |
| 220 | assert(isJumpTableIndex() && "This is not a jump table reference!"); |
| 221 | return Target.Index; |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 222 | } |
| 223 | |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 224 | /// getResultPointer - Once this has been resolved to point to an actual |
| 225 | /// address, this returns the pointer. |
| 226 | void *getResultPointer() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 227 | assert(AddrType == isResult && "Result pointer isn't set yet!"); |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 228 | return Target.Result; |
| 229 | } |
| 230 | |
| 231 | /// setResultPointer - Set the result to the specified pointer value. |
| 232 | /// |
| 233 | void setResultPointer(void *Ptr) { |
| 234 | Target.Result = Ptr; |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 235 | AddrType = isResult; |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 236 | } |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 237 | |
| 238 | /// setGOTIndex - Set the GOT index to a specific value. |
| 239 | void setGOTIndex(unsigned idx) { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 240 | AddrType = isGOTIndex; |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 241 | Target.GOTIndex = idx; |
| 242 | } |
| 243 | |
| 244 | /// getGOTIndex - Once this has been resolved to an entry in the GOT, |
Jeff Cohen | 9eb59ec | 2005-07-27 05:53:44 +0000 | [diff] [blame] | 245 | /// this returns that index. The index is from the lowest address entry |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 246 | /// in the GOT. |
| 247 | unsigned getGOTIndex() const { |
Chris Lattner | 1e3822c | 2006-05-03 18:52:31 +0000 | [diff] [blame] | 248 | assert(AddrType == isGOTIndex); |
Andrew Lenharth | 6a6b2db | 2005-07-22 20:46:42 +0000 | [diff] [blame] | 249 | return Target.GOTIndex; |
| 250 | } |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 251 | }; |
Chris Lattner | b89df9c | 2004-11-20 03:05:50 +0000 | [diff] [blame] | 252 | } |
| 253 | |
| 254 | #endif |