Home | History | Annotate | Download | only in MCTargetDesc
      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/MCRelocationInfo.h"
     15 #include "llvm/MC/MCSymbol.h"
     16 #include "llvm/Object/MachO.h"
     17 
     18 using namespace llvm;
     19 using namespace object;
     20 using namespace MachO;
     21 
     22 namespace {
     23 class X86_64MachORelocationInfo : public MCRelocationInfo {
     24 public:
     25   X86_64MachORelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {}
     26 
     27   const MCExpr *createExprForRelocation(RelocationRef Rel) override {
     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     any_relocation_info 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 = nullptr;
     44 
     45     switch(RelType) {
     46     case X86_64_RELOC_TLV:
     47       Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
     48       break;
     49     case X86_64_RELOC_SIGNED_4:
     50       Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx),
     51                                      MCConstantExpr::Create(4, Ctx),
     52                                      Ctx);
     53       break;
     54     case X86_64_RELOC_SIGNED_2:
     55       Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx),
     56                                      MCConstantExpr::Create(2, Ctx),
     57                                      Ctx);
     58       break;
     59     case X86_64_RELOC_SIGNED_1:
     60       Expr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, Ctx),
     61                                      MCConstantExpr::Create(1, Ctx),
     62                                      Ctx);
     63       break;
     64     case X86_64_RELOC_GOT_LOAD:
     65       Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx);
     66       break;
     67     case X86_64_RELOC_GOT:
     68       Expr = MCSymbolRefExpr::Create(Sym, isPCRel ?
     69                                      MCSymbolRefExpr::VK_GOTPCREL :
     70                                      MCSymbolRefExpr::VK_GOT,
     71                                      Ctx);
     72       break;
     73     case X86_64_RELOC_SUBTRACTOR:
     74       {
     75         Rel.moveNext();
     76         any_relocation_info RENext =
     77             Obj->getRelocation(Rel.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 != X86_64_RELOC_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 = Rel.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.
    114 MCRelocationInfo *llvm::createX86_64MachORelocationInfo(MCContext &Ctx) {
    115   return new X86_64MachORelocationInfo(Ctx);
    116 }
    117