12c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha//===-- X86MachORelocationInfo.cpp ----------------------------------------===// 22c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha// 32c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha// The LLVM Compiler Infrastructure 42c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha// 52c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha// This file is distributed under the University of Illinois Open Source 62c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha// License. See LICENSE.TXT for details. 72c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha// 82c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha//===----------------------------------------------------------------------===// 92c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 102c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "MCTargetDesc/X86MCTargetDesc.h" 112c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCContext.h" 122c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCExpr.h" 132c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCInst.h" 142c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCRelocationInfo.h" 1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSymbol.h" 162c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/Object/MachO.h" 172c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 182c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachausing namespace llvm; 192c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachausing namespace object; 205510728d28bb1ee04abc32da3d21b7df12948053Charles Davisusing namespace MachO; 212c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 222c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachanamespace { 232c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachaclass X86_64MachORelocationInfo : public MCRelocationInfo { 242c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachapublic: 252c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha X86_64MachORelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {} 262c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *createExprForRelocation(RelocationRef Rel) override { 282c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha const MachOObjectFile *Obj = cast<MachOObjectFile>(Rel.getObjectFile()); 292c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 302c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha uint64_t RelType; Rel.getType(RelType); 316c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola symbol_iterator SymI = Rel.getSymbol(); 322c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 336c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola StringRef SymName; SymI->getName(SymName); 346c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola uint64_t SymAddr; SymI->getAddress(SymAddr); 352c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 365510728d28bb1ee04abc32da3d21b7df12948053Charles Davis any_relocation_info RE = Obj->getRelocation(Rel.getRawDataRefImpl()); 372c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha bool isPCRel = Obj->getAnyRelocationPCRel(RE); 382c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 392c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName); 402c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha // FIXME: check that the value is actually the same. 412c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (Sym->isVariable() == false) 422c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Sym->setVariableValue(MCConstantExpr::Create(SymAddr, Ctx)); 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCExpr *Expr = nullptr; 442c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 452c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha switch(RelType) { 465510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case X86_64_RELOC_TLV: 472c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx); 482c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 495510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case X86_64_RELOC_SIGNED_4: 502c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 512c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha MCConstantExpr::Create(4, Ctx), 522c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Ctx); 532c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 545510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case X86_64_RELOC_SIGNED_2: 552c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 562c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha MCConstantExpr::Create(2, Ctx), 572c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Ctx); 582c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 595510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case X86_64_RELOC_SIGNED_1: 602c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 612c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha MCConstantExpr::Create(1, Ctx), 622c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Ctx); 632c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 645510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case X86_64_RELOC_GOT_LOAD: 652c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx); 662c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 675510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case X86_64_RELOC_GOT: 682c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCSymbolRefExpr::Create(Sym, isPCRel ? 692c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha MCSymbolRefExpr::VK_GOTPCREL : 702c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha MCSymbolRefExpr::VK_GOT, 712c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Ctx); 722c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 735510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case X86_64_RELOC_SUBTRACTOR: 742c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha { 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Rel.moveNext(); 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines any_relocation_info RENext = 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Obj->getRelocation(Rel.getRawDataRefImpl()); 782c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 792c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha // X86_64_SUBTRACTOR must be followed by a relocation of type 805510728d28bb1ee04abc32da3d21b7df12948053Charles Davis // X86_64_RELOC_UNSIGNED. 812c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha // NOTE: Scattered relocations don't exist on x86_64. 822c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha unsigned RType = Obj->getAnyRelocationType(RENext); 835510728d28bb1ee04abc32da3d21b7df12948053Charles Davis if (RType != X86_64_RELOC_UNSIGNED) 842c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " 852c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha "X86_64_RELOC_SUBTRACTOR."); 862c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 872c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha const MCExpr *LHS = MCSymbolRefExpr::Create(Sym, Ctx); 882c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines symbol_iterator RSymI = Rel.getSymbol(); 902c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha uint64_t RSymAddr; 916c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola RSymI->getAddress(RSymAddr); 922c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha StringRef RSymName; 936c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola RSymI->getName(RSymName); 942c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 952c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha MCSymbol *RSym = Ctx.GetOrCreateSymbol(RSymName); 962c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (RSym->isVariable() == false) 972c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha RSym->setVariableValue(MCConstantExpr::Create(RSymAddr, Ctx)); 982c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 992c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha const MCExpr *RHS = MCSymbolRefExpr::Create(RSym, Ctx); 1002c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 1012c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCBinaryExpr::CreateSub(LHS, RHS, Ctx); 1022c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 1032c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha } 1042c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha default: 1052c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Expr = MCSymbolRefExpr::Create(Sym, Ctx); 1062c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha break; 1072c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha } 1082c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha return Expr; 1092c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha } 1102c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha}; 1112c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha} // End unnamed namespace 1122c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 1132c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha/// createX86_64MachORelocationInfo - Construct an X86-64 Mach-O RelocationInfo. 1142c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed BougachaMCRelocationInfo *llvm::createX86_64MachORelocationInfo(MCContext &Ctx) { 1152c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha return new X86_64MachORelocationInfo(Ctx); 1162c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha} 117