Return ErrorOr from SymbolRef::getName.
[oota-llvm.git] / lib / Target / X86 / MCTargetDesc / X86MachORelocationInfo.cpp
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->getAddress(SymAddr);
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;
94         RSymI->getAddress(RSymAddr);
95         ErrorOr<StringRef> RSymName = RSymI->getName();
96         if (std::error_code EC = RSymName.getError())
97           report_fatal_error(EC.message());
98
99         MCSymbol *RSym = Ctx.getOrCreateSymbol(*RSymName);
100         if (!RSym->isVariable())
101           RSym->setVariableValue(MCConstantExpr::create(RSymAddr, Ctx));
102
103         const MCExpr *RHS = MCSymbolRefExpr::create(RSym, Ctx);
104
105         Expr = MCBinaryExpr::createSub(LHS, RHS, Ctx);
106         break;
107       }
108     default:
109       Expr = MCSymbolRefExpr::create(Sym, Ctx);
110       break;
111     }
112     return Expr;
113   }
114 };
115 } // End unnamed namespace
116
117 /// createX86_64MachORelocationInfo - Construct an X86-64 Mach-O RelocationInfo.
118 MCRelocationInfo *llvm::createX86_64MachORelocationInfo(MCContext &Ctx) {
119   return new X86_64MachORelocationInfo(Ctx);
120 }