1 //===-- X86ELFRelocationInfo.cpp ----------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/X86MCTargetDesc.h" 11 #include "llvm/MC/MCContext.h" 12 #include "llvm/MC/MCExpr.h" 13 #include "llvm/MC/MCInst.h" 14 #include "llvm/MC/MCSymbol.h" 15 #include "llvm/MC/MCRelocationInfo.h" 16 #include "llvm/Object/ELF.h" 17 #include "llvm/Support/ELF.h" 18 19 using namespace llvm; 20 using namespace object; 21 using namespace ELF; 22 23 namespace { 24 class X86_64ELFRelocationInfo : public MCRelocationInfo { 25 public: 26 X86_64ELFRelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {} 27 28 const MCExpr *createExprForRelocation(RelocationRef Rel) { 29 uint64_t RelType; Rel.getType(RelType); 30 symbol_iterator SymI = Rel.getSymbol(); 31 32 StringRef SymName; SymI->getName(SymName); 33 uint64_t SymAddr; SymI->getAddress(SymAddr); 34 uint64_t SymSize; SymI->getSize(SymSize); 35 int64_t Addend; getELFRelocationAddend(Rel, Addend); 36 37 MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName); 38 // FIXME: check that the value is actually the same. 39 if (Sym->isVariable() == false) 40 Sym->setVariableValue(MCConstantExpr::Create(SymAddr, Ctx)); 41 42 const MCExpr *Expr = 0; 43 // If hasAddend is true, then we need to add Addend (r_addend) to Expr. 44 bool hasAddend = false; 45 46 // The AMD64 SysV ABI says: 47 // A: the addend used to compute the value of the relocatable field. 48 // B: the base address at which a shared object has been loaded into memory 49 // during execution. Generally, a shared object is built with a 0 base 50 // virtual address, but the execution address will be different. 51 // G: the offset into the global offset table at which the relocation 52 // entry's symbol will reside during execution. 53 // GOT: the address of the global offset table. 54 // L: the place (section offset or address) of the Procedure Linkage Table 55 // entry for a symbol. 56 // P: the place (section offset or address) of the storage unit being 57 // relocated (computed using r_offset). 58 // S: the value of the symbol whose index resides in the relocation entry. 59 // Z: the size of the symbol whose index resides in the relocation entry. 60 61 switch(RelType) { 62 case R_X86_64_NONE: 63 case R_X86_64_COPY: 64 // none 65 break; 66 case R_X86_64_64: 67 case R_X86_64_16: 68 case R_X86_64_8: 69 // S + A 70 case R_X86_64_32: 71 case R_X86_64_32S: 72 // S + A (We don't care about the result not fitting in 32 bits.) 73 case R_X86_64_PC32: 74 case R_X86_64_PC16: 75 case R_X86_64_PC8: 76 case R_X86_64_PC64: 77 // S + A - P (P/pcrel is implicit) 78 hasAddend = true; 79 Expr = MCSymbolRefExpr::Create(Sym, Ctx); 80 break; 81 case R_X86_64_GOT32: 82 case R_X86_64_GOT64: 83 case R_X86_64_GOTPC32: 84 case R_X86_64_GOTPC64: 85 case R_X86_64_GOTPLT64: 86 // G + A 87 hasAddend = true; 88 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOT, Ctx); 89 break; 90 case R_X86_64_PLT32: 91 // L + A - P -> S@PLT + A 92 hasAddend = true; 93 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_PLT, Ctx); 94 break; 95 case R_X86_64_GLOB_DAT: 96 case R_X86_64_JUMP_SLOT: 97 // S 98 Expr = MCSymbolRefExpr::Create(Sym, Ctx); 99 break; 100 case R_X86_64_GOTPCREL: 101 case R_X86_64_GOTPCREL64: 102 // G + GOT + A - P -> S@GOTPCREL + A 103 hasAddend = true; 104 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx); 105 break; 106 case R_X86_64_GOTOFF64: 107 // S + A - GOT 108 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTOFF, Ctx); 109 break; 110 case R_X86_64_PLTOFF64: 111 // L + A - GOT 112 break; 113 case R_X86_64_SIZE32: 114 case R_X86_64_SIZE64: 115 // Z + A 116 Expr = MCConstantExpr::Create(SymSize, Ctx); 117 break; 118 default: 119 Expr = MCSymbolRefExpr::Create(Sym, Ctx); 120 break; 121 } 122 if (Expr && hasAddend && Addend != 0) 123 Expr = MCBinaryExpr::CreateAdd(Expr, 124 MCConstantExpr::Create(Addend, Ctx), 125 Ctx); 126 return Expr; 127 } 128 }; 129 } // End unnamed namespace 130 131 /// createX86ELFRelocationInfo - Construct an X86 Mach-O RelocationInfo. 132 MCRelocationInfo *llvm::createX86_64ELFRelocationInfo(MCContext &Ctx) { 133 // We only handle x86-64 for now. 134 return new X86_64ELFRelocationInfo(Ctx); 135 } 136