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.getObject());
     29 
     30     uint64_t RelType = Rel.getType();
     31     symbol_iterator SymI = Rel.getSymbol();
     32 
     33     ErrorOr<StringRef> SymNameOrErr = SymI->getName();
     34     if (std::error_code EC = SymNameOrErr.getError())
     35       report_fatal_error(EC.message());
     36     StringRef SymName = *SymNameOrErr;
     37     uint64_t SymAddr = SymI->getValue();
     38 
     39     any_relocation_info RE = Obj->getRelocation(Rel.getRawDataRefImpl());
     40     bool isPCRel = Obj->getAnyRelocationPCRel(RE);
     41 
     42     MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
     43     // FIXME: check that the value is actually the same.
     44     if (!Sym->isVariable())
     45       Sym->setVariableValue(MCConstantExpr::create(SymAddr, Ctx));
     46     const MCExpr *Expr = nullptr;
     47 
     48     switch(RelType) {
     49     case X86_64_RELOC_TLV:
     50       Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
     51       break;
     52     case X86_64_RELOC_SIGNED_4:
     53       Expr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Sym, Ctx),
     54                                      MCConstantExpr::create(4, Ctx),
     55                                      Ctx);
     56       break;
     57     case X86_64_RELOC_SIGNED_2:
     58       Expr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Sym, Ctx),
     59                                      MCConstantExpr::create(2, Ctx),
     60                                      Ctx);
     61       break;
     62     case X86_64_RELOC_SIGNED_1:
     63       Expr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Sym, Ctx),
     64                                      MCConstantExpr::create(1, Ctx),
     65                                      Ctx);
     66       break;
     67     case X86_64_RELOC_GOT_LOAD:
     68       Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx);
     69       break;
     70     case X86_64_RELOC_GOT:
     71       Expr = MCSymbolRefExpr::create(Sym, isPCRel ?
     72                                      MCSymbolRefExpr::VK_GOTPCREL :
     73                                      MCSymbolRefExpr::VK_GOT,
     74                                      Ctx);
     75       break;
     76     case X86_64_RELOC_SUBTRACTOR:
     77       {
     78         Rel.moveNext();
     79         any_relocation_info RENext =
     80             Obj->getRelocation(Rel.getRawDataRefImpl());
     81 
     82         // X86_64_SUBTRACTOR must be followed by a relocation of type
     83         // X86_64_RELOC_UNSIGNED.
     84         // NOTE: Scattered relocations don't exist on x86_64.
     85         unsigned RType = Obj->getAnyRelocationType(RENext);
     86         if (RType != X86_64_RELOC_UNSIGNED)
     87           report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
     88                              "X86_64_RELOC_SUBTRACTOR.");
     89 
     90         const MCExpr *LHS = MCSymbolRefExpr::create(Sym, Ctx);
     91 
     92         symbol_iterator RSymI = Rel.getSymbol();
     93         uint64_t RSymAddr = RSymI->getValue();
     94         ErrorOr<StringRef> RSymName = RSymI->getName();
     95         if (std::error_code EC = RSymName.getError())
     96           report_fatal_error(EC.message());
     97 
     98         MCSymbol *RSym = Ctx.getOrCreateSymbol(*RSymName);
     99         if (!RSym->isVariable())
    100           RSym->setVariableValue(MCConstantExpr::create(RSymAddr, Ctx));
    101 
    102         const MCExpr *RHS = MCSymbolRefExpr::create(RSym, Ctx);
    103 
    104         Expr = MCBinaryExpr::createSub(LHS, RHS, Ctx);
    105         break;
    106       }
    107     default:
    108       Expr = MCSymbolRefExpr::create(Sym, Ctx);
    109       break;
    110     }
    111     return Expr;
    112   }
    113 };
    114 } // End unnamed namespace
    115 
    116 /// createX86_64MachORelocationInfo - Construct an X86-64 Mach-O RelocationInfo.
    117 MCRelocationInfo *llvm::createX86_64MachORelocationInfo(MCContext &Ctx) {
    118   return new X86_64MachORelocationInfo(Ctx);
    119 }
    120