1//===-- X86MachORelocationInfo.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/MachO.h" 17 18using namespace llvm; 19using namespace object; 20using namespace macho; 21 22namespace { 23class X86_64MachORelocationInfo : public MCRelocationInfo { 24public: 25 X86_64MachORelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {} 26 27 const MCExpr *createExprForRelocation(RelocationRef Rel) { 28 const MachOObjectFile *Obj = cast<MachOObjectFile>(Rel.getObjectFile()); 29 30 uint64_t RelType; Rel.getType(RelType); 31 symbol_iterator SymI = Rel.getSymbol(); 32 33 StringRef SymName; SymI->getName(SymName); 34 uint64_t SymAddr; SymI->getAddress(SymAddr); 35 36 RelocationEntry RE = Obj->getRelocation(Rel.getRawDataRefImpl()); 37 bool isPCRel = Obj->getAnyRelocationPCRel(RE); 38 39 MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName); 40 // FIXME: check that the value is actually the same. 41 if (Sym->isVariable() == false) 42 Sym->setVariableValue(MCConstantExpr::Create(SymAddr, Ctx)); 43 const MCExpr *Expr = 0; 44 45 switch(RelType) { 46 case RIT_X86_64_TLV: 47 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx); 48 break; 49 case RIT_X86_64_Signed4: 50 Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 51 MCConstantExpr::Create(4, Ctx), 52 Ctx); 53 break; 54 case RIT_X86_64_Signed2: 55 Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 56 MCConstantExpr::Create(2, Ctx), 57 Ctx); 58 break; 59 case RIT_X86_64_Signed1: 60 Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 61 MCConstantExpr::Create(1, Ctx), 62 Ctx); 63 break; 64 case RIT_X86_64_GOTLoad: 65 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx); 66 break; 67 case RIT_X86_64_GOT: 68 Expr = MCSymbolRefExpr::Create(Sym, isPCRel ? 69 MCSymbolRefExpr::VK_GOTPCREL : 70 MCSymbolRefExpr::VK_GOT, 71 Ctx); 72 break; 73 case RIT_X86_64_Subtractor: 74 { 75 RelocationRef RelNext; 76 Obj->getRelocationNext(Rel.getRawDataRefImpl(), RelNext); 77 RelocationEntry RENext = Obj->getRelocation(RelNext.getRawDataRefImpl()); 78 79 // X86_64_SUBTRACTOR must be followed by a relocation of type 80 // X86_64_RELOC_UNSIGNED . 81 // NOTE: Scattered relocations don't exist on x86_64. 82 unsigned RType = Obj->getAnyRelocationType(RENext); 83 if (RType != RIT_X86_64_Unsigned) 84 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " 85 "X86_64_RELOC_SUBTRACTOR."); 86 87 const MCExpr *LHS = MCSymbolRefExpr::Create(Sym, Ctx); 88 89 symbol_iterator RSymI = RelNext.getSymbol(); 90 uint64_t RSymAddr; 91 RSymI->getAddress(RSymAddr); 92 StringRef RSymName; 93 RSymI->getName(RSymName); 94 95 MCSymbol *RSym = Ctx.GetOrCreateSymbol(RSymName); 96 if (RSym->isVariable() == false) 97 RSym->setVariableValue(MCConstantExpr::Create(RSymAddr, Ctx)); 98 99 const MCExpr *RHS = MCSymbolRefExpr::Create(RSym, Ctx); 100 101 Expr = MCBinaryExpr::CreateSub(LHS, RHS, Ctx); 102 break; 103 } 104 default: 105 Expr = MCSymbolRefExpr::Create(Sym, Ctx); 106 break; 107 } 108 return Expr; 109 } 110}; 111} // End unnamed namespace 112 113/// createX86_64MachORelocationInfo - Construct an X86-64 Mach-O RelocationInfo. 114MCRelocationInfo *llvm::createX86_64MachORelocationInfo(MCContext &Ctx) { 115 return new X86_64MachORelocationInfo(Ctx); 116} 117