1 //===-- X86MachORelocationInfo.cpp ----------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
19 using namespace object
;
20 using namespace MachO
;
23 class X86_64MachORelocationInfo
: public MCRelocationInfo
{
25 X86_64MachORelocationInfo(MCContext
&Ctx
) : MCRelocationInfo(Ctx
) {}
27 const MCExpr
*createExprForRelocation(RelocationRef Rel
) override
{
28 const MachOObjectFile
*Obj
= cast
<MachOObjectFile
>(Rel
.getObjectFile());
30 uint64_t RelType
; Rel
.getType(RelType
);
31 symbol_iterator SymI
= Rel
.getSymbol();
33 StringRef SymName
; SymI
->getName(SymName
);
34 uint64_t SymAddr
; SymI
->getAddress(SymAddr
);
36 any_relocation_info RE
= Obj
->getRelocation(Rel
.getRawDataRefImpl());
37 bool isPCRel
= Obj
->getAnyRelocationPCRel(RE
);
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;
46 case X86_64_RELOC_TLV
:
47 Expr
= MCSymbolRefExpr::Create(Sym
, MCSymbolRefExpr::VK_TLVP
, Ctx
);
49 case X86_64_RELOC_SIGNED_4
:
50 Expr
= MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym
, Ctx
),
51 MCConstantExpr::Create(4, Ctx
),
54 case X86_64_RELOC_SIGNED_2
:
55 Expr
= MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym
, Ctx
),
56 MCConstantExpr::Create(2, Ctx
),
59 case X86_64_RELOC_SIGNED_1
:
60 Expr
= MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym
, Ctx
),
61 MCConstantExpr::Create(1, Ctx
),
64 case X86_64_RELOC_GOT_LOAD
:
65 Expr
= MCSymbolRefExpr::Create(Sym
, MCSymbolRefExpr::VK_GOTPCREL
, Ctx
);
67 case X86_64_RELOC_GOT
:
68 Expr
= MCSymbolRefExpr::Create(Sym
, isPCRel
?
69 MCSymbolRefExpr::VK_GOTPCREL
:
70 MCSymbolRefExpr::VK_GOT
,
73 case X86_64_RELOC_SUBTRACTOR
:
76 any_relocation_info RENext
=
77 Obj
->getRelocation(Rel
.getRawDataRefImpl());
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.");
87 const MCExpr
*LHS
= MCSymbolRefExpr::Create(Sym
, Ctx
);
89 symbol_iterator RSymI
= Rel
.getSymbol();
91 RSymI
->getAddress(RSymAddr
);
93 RSymI
->getName(RSymName
);
95 MCSymbol
*RSym
= Ctx
.GetOrCreateSymbol(RSymName
);
96 if (RSym
->isVariable() == false)
97 RSym
->setVariableValue(MCConstantExpr::Create(RSymAddr
, Ctx
));
99 const MCExpr
*RHS
= MCSymbolRefExpr::Create(RSym
, Ctx
);
101 Expr
= MCBinaryExpr::CreateSub(LHS
, RHS
, Ctx
);
105 Expr
= MCSymbolRefExpr::Create(Sym
, Ctx
);
111 } // End unnamed namespace
113 /// createX86_64MachORelocationInfo - Construct an X86-64 Mach-O RelocationInfo.
114 MCRelocationInfo
*llvm::createX86_64MachORelocationInfo(MCContext
&Ctx
) {
115 return new X86_64MachORelocationInfo(Ctx
);