LLVM API Documentation
00001 //===-- X86MachORelocationInfo.cpp ----------------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MCTargetDesc/X86MCTargetDesc.h" 00011 #include "llvm/MC/MCContext.h" 00012 #include "llvm/MC/MCExpr.h" 00013 #include "llvm/MC/MCInst.h" 00014 #include "llvm/MC/MCRelocationInfo.h" 00015 #include "llvm/MC/MCSymbol.h" 00016 #include "llvm/Object/MachO.h" 00017 00018 using namespace llvm; 00019 using namespace object; 00020 using namespace MachO; 00021 00022 namespace { 00023 class X86_64MachORelocationInfo : public MCRelocationInfo { 00024 public: 00025 X86_64MachORelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {} 00026 00027 const MCExpr *createExprForRelocation(RelocationRef Rel) override { 00028 const MachOObjectFile *Obj = cast<MachOObjectFile>(Rel.getObjectFile()); 00029 00030 uint64_t RelType; Rel.getType(RelType); 00031 symbol_iterator SymI = Rel.getSymbol(); 00032 00033 StringRef SymName; SymI->getName(SymName); 00034 uint64_t SymAddr; SymI->getAddress(SymAddr); 00035 00036 any_relocation_info RE = Obj->getRelocation(Rel.getRawDataRefImpl()); 00037 bool isPCRel = Obj->getAnyRelocationPCRel(RE); 00038 00039 MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName); 00040 // FIXME: check that the value is actually the same. 00041 if (Sym->isVariable() == false) 00042 Sym->setVariableValue(MCConstantExpr::Create(SymAddr, Ctx)); 00043 const MCExpr *Expr = nullptr; 00044 00045 switch(RelType) { 00046 case X86_64_RELOC_TLV: 00047 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx); 00048 break; 00049 case X86_64_RELOC_SIGNED_4: 00050 Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 00051 MCConstantExpr::Create(4, Ctx), 00052 Ctx); 00053 break; 00054 case X86_64_RELOC_SIGNED_2: 00055 Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 00056 MCConstantExpr::Create(2, Ctx), 00057 Ctx); 00058 break; 00059 case X86_64_RELOC_SIGNED_1: 00060 Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx), 00061 MCConstantExpr::Create(1, Ctx), 00062 Ctx); 00063 break; 00064 case X86_64_RELOC_GOT_LOAD: 00065 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx); 00066 break; 00067 case X86_64_RELOC_GOT: 00068 Expr = MCSymbolRefExpr::Create(Sym, isPCRel ? 00069 MCSymbolRefExpr::VK_GOTPCREL : 00070 MCSymbolRefExpr::VK_GOT, 00071 Ctx); 00072 break; 00073 case X86_64_RELOC_SUBTRACTOR: 00074 { 00075 Rel.moveNext(); 00076 any_relocation_info RENext = 00077 Obj->getRelocation(Rel.getRawDataRefImpl()); 00078 00079 // X86_64_SUBTRACTOR must be followed by a relocation of type 00080 // X86_64_RELOC_UNSIGNED. 00081 // NOTE: Scattered relocations don't exist on x86_64. 00082 unsigned RType = Obj->getAnyRelocationType(RENext); 00083 if (RType != X86_64_RELOC_UNSIGNED) 00084 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " 00085 "X86_64_RELOC_SUBTRACTOR."); 00086 00087 const MCExpr *LHS = MCSymbolRefExpr::Create(Sym, Ctx); 00088 00089 symbol_iterator RSymI = Rel.getSymbol(); 00090 uint64_t RSymAddr; 00091 RSymI->getAddress(RSymAddr); 00092 StringRef RSymName; 00093 RSymI->getName(RSymName); 00094 00095 MCSymbol *RSym = Ctx.GetOrCreateSymbol(RSymName); 00096 if (RSym->isVariable() == false) 00097 RSym->setVariableValue(MCConstantExpr::Create(RSymAddr, Ctx)); 00098 00099 const MCExpr *RHS = MCSymbolRefExpr::Create(RSym, Ctx); 00100 00101 Expr = MCBinaryExpr::CreateSub(LHS, RHS, Ctx); 00102 break; 00103 } 00104 default: 00105 Expr = MCSymbolRefExpr::Create(Sym, Ctx); 00106 break; 00107 } 00108 return Expr; 00109 } 00110 }; 00111 } // End unnamed namespace 00112 00113 /// createX86_64MachORelocationInfo - Construct an X86-64 Mach-O RelocationInfo. 00114 MCRelocationInfo *llvm::createX86_64MachORelocationInfo(MCContext &Ctx) { 00115 return new X86_64MachORelocationInfo(Ctx); 00116 }