1193323Sed//===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines the MachineRelocation class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#ifndef LLVM_CODEGEN_MACHINERELOCATION_H 15193323Sed#define LLVM_CODEGEN_MACHINERELOCATION_H 16193323Sed 17218893Sdim#include "llvm/Support/DataTypes.h" 18193323Sed#include <cassert> 19193323Sed 20193323Sednamespace llvm { 21193323Sedclass GlobalValue; 22193323Sedclass MachineBasicBlock; 23193323Sed 24193323Sed/// MachineRelocation - This represents a target-specific relocation value, 25193323Sed/// produced by the code emitter. This relocation is resolved after the has 26193323Sed/// been emitted, either to an object file or to memory, when the target of the 27193323Sed/// relocation can be resolved. 28193323Sed/// 29193323Sed/// A relocation is made up of the following logical portions: 30193323Sed/// 1. An offset in the machine code buffer, the location to modify. 31193323Sed/// 2. A target specific relocation type (a number from 0 to 63). 32193323Sed/// 3. A symbol being referenced, either as a GlobalValue* or as a string. 33193323Sed/// 4. An optional constant value to be added to the reference. 34193323Sed/// 5. A bit, CanRewrite, which indicates to the JIT that a function stub is 35193323Sed/// not needed for the relocation. 36193323Sed/// 6. An index into the GOT, if the target uses a GOT 37193323Sed/// 38193323Sedclass MachineRelocation { 39193323Sed enum AddressType { 40193323Sed isResult, // Relocation has be transformed into its result pointer. 41193323Sed isGV, // The Target.GV field is valid. 42193323Sed isIndirectSym, // Relocation of an indirect symbol. 43193323Sed isBB, // Relocation of BB address. 44193323Sed isExtSym, // The Target.ExtSym field is valid. 45193323Sed isConstPool, // Relocation of constant pool address. 46193323Sed isJumpTable, // Relocation of jump table address. 47193323Sed isGOTIndex // The Target.GOTIndex field is valid. 48193323Sed }; 49193323Sed 50193323Sed /// Offset - This is the offset from the start of the code buffer of the 51193323Sed /// relocation to perform. 52193323Sed uintptr_t Offset; 53193323Sed 54193323Sed /// ConstantVal - A field that may be used by the target relocation type. 55193323Sed intptr_t ConstantVal; 56193323Sed 57193323Sed union { 58193323Sed void *Result; // If this has been resolved to a resolved pointer 59193323Sed GlobalValue *GV; // If this is a pointer to a GV or an indirect ref. 60263508Sdim MachineBasicBlock *MBB; // If this is a pointer to an LLVM BB 61193323Sed const char *ExtSym; // If this is a pointer to a named symbol 62193323Sed unsigned Index; // Constant pool / jump table index 63193323Sed unsigned GOTIndex; // Index in the GOT of this symbol/global 64193323Sed } Target; 65193323Sed 66193323Sed unsigned TargetReloType : 6; // The target relocation ID 67193323Sed AddressType AddrType : 4; // The field of Target to use 68199481Srdivacky bool MayNeedFarStub : 1; // True if this relocation may require a far-stub 69193323Sed bool GOTRelative : 1; // Should this relocation be relative to the GOT? 70193323Sed bool TargetResolve : 1; // True if target should resolve the address 71193323Sed 72193323Sedpublic: 73193323Sed // Relocation types used in a generic implementation. Currently, relocation 74193323Sed // entries for all things use the generic VANILLA type until they are refined 75193323Sed // into target relocation types. 76193323Sed enum RelocationType { 77193323Sed VANILLA 78193323Sed }; 79193323Sed 80193323Sed /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue. 81193323Sed /// 82193323Sed static MachineRelocation getGV(uintptr_t offset, unsigned RelocationType, 83193323Sed GlobalValue *GV, intptr_t cst = 0, 84199481Srdivacky bool MayNeedFarStub = 0, 85193323Sed bool GOTrelative = 0) { 86193323Sed assert((RelocationType & ~63) == 0 && "Relocation type too large!"); 87193323Sed MachineRelocation Result; 88193323Sed Result.Offset = offset; 89193323Sed Result.ConstantVal = cst; 90193323Sed Result.TargetReloType = RelocationType; 91193323Sed Result.AddrType = isGV; 92199481Srdivacky Result.MayNeedFarStub = MayNeedFarStub; 93193323Sed Result.GOTRelative = GOTrelative; 94193323Sed Result.TargetResolve = false; 95193323Sed Result.Target.GV = GV; 96193323Sed return Result; 97193323Sed } 98193323Sed 99193323Sed /// MachineRelocation::getIndirectSymbol - Return a relocation entry for an 100193323Sed /// indirect symbol. 101193323Sed static MachineRelocation getIndirectSymbol(uintptr_t offset, 102193323Sed unsigned RelocationType, 103193323Sed GlobalValue *GV, intptr_t cst = 0, 104199481Srdivacky bool MayNeedFarStub = 0, 105193323Sed bool GOTrelative = 0) { 106193323Sed assert((RelocationType & ~63) == 0 && "Relocation type too large!"); 107193323Sed MachineRelocation Result; 108193323Sed Result.Offset = offset; 109193323Sed Result.ConstantVal = cst; 110193323Sed Result.TargetReloType = RelocationType; 111193323Sed Result.AddrType = isIndirectSym; 112199481Srdivacky Result.MayNeedFarStub = MayNeedFarStub; 113193323Sed Result.GOTRelative = GOTrelative; 114193323Sed Result.TargetResolve = false; 115193323Sed Result.Target.GV = GV; 116193323Sed return Result; 117193323Sed } 118193323Sed 119193323Sed /// MachineRelocation::getBB - Return a relocation entry for a BB. 120193323Sed /// 121193323Sed static MachineRelocation getBB(uintptr_t offset,unsigned RelocationType, 122193323Sed MachineBasicBlock *MBB, intptr_t cst = 0) { 123193323Sed assert((RelocationType & ~63) == 0 && "Relocation type too large!"); 124193323Sed MachineRelocation Result; 125193323Sed Result.Offset = offset; 126193323Sed Result.ConstantVal = cst; 127193323Sed Result.TargetReloType = RelocationType; 128193323Sed Result.AddrType = isBB; 129199481Srdivacky Result.MayNeedFarStub = false; 130193323Sed Result.GOTRelative = false; 131193323Sed Result.TargetResolve = false; 132193323Sed Result.Target.MBB = MBB; 133193323Sed return Result; 134193323Sed } 135193323Sed 136193323Sed /// MachineRelocation::getExtSym - Return a relocation entry for an external 137193323Sed /// symbol, like "free". 138193323Sed /// 139193323Sed static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType, 140193323Sed const char *ES, intptr_t cst = 0, 141203954Srdivacky bool GOTrelative = 0, 142203954Srdivacky bool NeedStub = true) { 143193323Sed assert((RelocationType & ~63) == 0 && "Relocation type too large!"); 144193323Sed MachineRelocation Result; 145193323Sed Result.Offset = offset; 146193323Sed Result.ConstantVal = cst; 147193323Sed Result.TargetReloType = RelocationType; 148193323Sed Result.AddrType = isExtSym; 149203954Srdivacky Result.MayNeedFarStub = NeedStub; 150193323Sed Result.GOTRelative = GOTrelative; 151193323Sed Result.TargetResolve = false; 152193323Sed Result.Target.ExtSym = ES; 153193323Sed return Result; 154193323Sed } 155193323Sed 156193323Sed /// MachineRelocation::getConstPool - Return a relocation entry for a constant 157193323Sed /// pool entry. 158193323Sed /// 159193323Sed static MachineRelocation getConstPool(uintptr_t offset,unsigned RelocationType, 160193323Sed unsigned CPI, intptr_t cst = 0, 161193323Sed bool letTargetResolve = false) { 162193323Sed assert((RelocationType & ~63) == 0 && "Relocation type too large!"); 163193323Sed MachineRelocation Result; 164193323Sed Result.Offset = offset; 165193323Sed Result.ConstantVal = cst; 166193323Sed Result.TargetReloType = RelocationType; 167193323Sed Result.AddrType = isConstPool; 168199481Srdivacky Result.MayNeedFarStub = false; 169193323Sed Result.GOTRelative = false; 170193323Sed Result.TargetResolve = letTargetResolve; 171193323Sed Result.Target.Index = CPI; 172193323Sed return Result; 173193323Sed } 174193323Sed 175193323Sed /// MachineRelocation::getJumpTable - Return a relocation entry for a jump 176193323Sed /// table entry. 177193323Sed /// 178193323Sed static MachineRelocation getJumpTable(uintptr_t offset,unsigned RelocationType, 179193323Sed unsigned JTI, intptr_t cst = 0, 180193323Sed bool letTargetResolve = false) { 181193323Sed assert((RelocationType & ~63) == 0 && "Relocation type too large!"); 182193323Sed MachineRelocation Result; 183193323Sed Result.Offset = offset; 184193323Sed Result.ConstantVal = cst; 185193323Sed Result.TargetReloType = RelocationType; 186193323Sed Result.AddrType = isJumpTable; 187199481Srdivacky Result.MayNeedFarStub = false; 188193323Sed Result.GOTRelative = false; 189193323Sed Result.TargetResolve = letTargetResolve; 190193323Sed Result.Target.Index = JTI; 191193323Sed return Result; 192193323Sed } 193193323Sed 194193323Sed /// getMachineCodeOffset - Return the offset into the code buffer that the 195193323Sed /// relocation should be performed. 196193323Sed intptr_t getMachineCodeOffset() const { 197193323Sed return Offset; 198193323Sed } 199193323Sed 200193323Sed /// getRelocationType - Return the target-specific relocation ID for this 201193323Sed /// relocation. 202193323Sed unsigned getRelocationType() const { 203193323Sed return TargetReloType; 204193323Sed } 205193323Sed 206193323Sed /// getConstantVal - Get the constant value associated with this relocation. 207193323Sed /// This is often an offset from the symbol. 208193323Sed /// 209193323Sed intptr_t getConstantVal() const { 210193323Sed return ConstantVal; 211193323Sed } 212193323Sed 213193323Sed /// setConstantVal - Set the constant value associated with this relocation. 214193323Sed /// This is often an offset from the symbol. 215193323Sed /// 216193323Sed void setConstantVal(intptr_t val) { 217193323Sed ConstantVal = val; 218193323Sed } 219193323Sed 220193323Sed /// isGlobalValue - Return true if this relocation is a GlobalValue, as 221193323Sed /// opposed to a constant string. 222193323Sed bool isGlobalValue() const { 223193323Sed return AddrType == isGV; 224193323Sed } 225193323Sed 226193323Sed /// isIndirectSymbol - Return true if this relocation is the address an 227193323Sed /// indirect symbol 228193323Sed bool isIndirectSymbol() const { 229193323Sed return AddrType == isIndirectSym; 230193323Sed } 231193323Sed 232193323Sed /// isBasicBlock - Return true if this relocation is a basic block reference. 233193323Sed /// 234193323Sed bool isBasicBlock() const { 235193323Sed return AddrType == isBB; 236193323Sed } 237193323Sed 238193323Sed /// isExternalSymbol - Return true if this is a constant string. 239193323Sed /// 240193323Sed bool isExternalSymbol() const { 241193323Sed return AddrType == isExtSym; 242193323Sed } 243193323Sed 244193323Sed /// isConstantPoolIndex - Return true if this is a constant pool reference. 245193323Sed /// 246193323Sed bool isConstantPoolIndex() const { 247193323Sed return AddrType == isConstPool; 248193323Sed } 249193323Sed 250193323Sed /// isJumpTableIndex - Return true if this is a jump table reference. 251193323Sed /// 252193323Sed bool isJumpTableIndex() const { 253193323Sed return AddrType == isJumpTable; 254193323Sed } 255193323Sed 256193323Sed /// isGOTRelative - Return true the target wants the index into the GOT of 257193323Sed /// the symbol rather than the address of the symbol. 258193323Sed bool isGOTRelative() const { 259193323Sed return GOTRelative; 260193323Sed } 261193323Sed 262199481Srdivacky /// mayNeedFarStub - This function returns true if the JIT for this target may 263199481Srdivacky /// need either a stub function or an indirect global-variable load to handle 264199481Srdivacky /// the relocated GlobalValue reference. For example, the x86-64 call 265199481Srdivacky /// instruction can only call functions within +/-2GB of the call site. 266199481Srdivacky /// Anything farther away needs a longer mov+call sequence, which can't just 267199481Srdivacky /// be written on top of the existing call. 268199481Srdivacky bool mayNeedFarStub() const { 269199481Srdivacky return MayNeedFarStub; 270193323Sed } 271193323Sed 272193323Sed /// letTargetResolve - Return true if the target JITInfo is usually 273193323Sed /// responsible for resolving the address of this relocation. 274193323Sed bool letTargetResolve() const { 275193323Sed return TargetResolve; 276193323Sed } 277193323Sed 278193323Sed /// getGlobalValue - If this is a global value reference, return the 279193323Sed /// referenced global. 280193323Sed GlobalValue *getGlobalValue() const { 281193323Sed assert((isGlobalValue() || isIndirectSymbol()) && 282193323Sed "This is not a global value reference!"); 283193323Sed return Target.GV; 284193323Sed } 285193323Sed 286193323Sed MachineBasicBlock *getBasicBlock() const { 287193323Sed assert(isBasicBlock() && "This is not a basic block reference!"); 288193323Sed return Target.MBB; 289193323Sed } 290193323Sed 291193323Sed /// getString - If this is a string value, return the string reference. 292193323Sed /// 293193323Sed const char *getExternalSymbol() const { 294193323Sed assert(isExternalSymbol() && "This is not an external symbol reference!"); 295193323Sed return Target.ExtSym; 296193323Sed } 297193323Sed 298193323Sed /// getConstantPoolIndex - If this is a const pool reference, return 299193323Sed /// the index into the constant pool. 300193323Sed unsigned getConstantPoolIndex() const { 301193323Sed assert(isConstantPoolIndex() && "This is not a constant pool reference!"); 302193323Sed return Target.Index; 303193323Sed } 304193323Sed 305193323Sed /// getJumpTableIndex - If this is a jump table reference, return 306193323Sed /// the index into the jump table. 307193323Sed unsigned getJumpTableIndex() const { 308193323Sed assert(isJumpTableIndex() && "This is not a jump table reference!"); 309193323Sed return Target.Index; 310193323Sed } 311193323Sed 312193323Sed /// getResultPointer - Once this has been resolved to point to an actual 313193323Sed /// address, this returns the pointer. 314193323Sed void *getResultPointer() const { 315193323Sed assert(AddrType == isResult && "Result pointer isn't set yet!"); 316193323Sed return Target.Result; 317193323Sed } 318193323Sed 319193323Sed /// setResultPointer - Set the result to the specified pointer value. 320193323Sed /// 321193323Sed void setResultPointer(void *Ptr) { 322193323Sed Target.Result = Ptr; 323193323Sed AddrType = isResult; 324193323Sed } 325193323Sed 326193323Sed /// setGOTIndex - Set the GOT index to a specific value. 327193323Sed void setGOTIndex(unsigned idx) { 328193323Sed AddrType = isGOTIndex; 329193323Sed Target.GOTIndex = idx; 330193323Sed } 331193323Sed 332193323Sed /// getGOTIndex - Once this has been resolved to an entry in the GOT, 333193323Sed /// this returns that index. The index is from the lowest address entry 334193323Sed /// in the GOT. 335193323Sed unsigned getGOTIndex() const { 336193323Sed assert(AddrType == isGOTIndex); 337193323Sed return Target.GOTIndex; 338193323Sed } 339193323Sed}; 340193323Sed} 341193323Sed 342193323Sed#endif 343