LLVM API Documentation

X86MachORelocationInfo.cpp
Go to the documentation of this file.
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 }