LLVM  3.7.0
X86ELFRelocationInfo.cpp
Go to the documentation of this file.
1 //===-- X86ELFRelocationInfo.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 
11 #include "llvm/MC/MCContext.h"
12 #include "llvm/MC/MCExpr.h"
13 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCSymbol.h"
17 #include "llvm/Support/ELF.h"
18 
19 using namespace llvm;
20 using namespace object;
21 using namespace ELF;
22 
23 namespace {
24 class X86_64ELFRelocationInfo : public MCRelocationInfo {
25 public:
26  X86_64ELFRelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {}
27 
28  const MCExpr *createExprForRelocation(RelocationRef Rel) override {
29  uint64_t RelType = Rel.getType();
30  elf_symbol_iterator SymI = Rel.getSymbol();
31 
32  ErrorOr<StringRef> SymNameOrErr = SymI->getName();
33  if (std::error_code EC = SymNameOrErr.getError())
34  report_fatal_error(EC.message());
35  StringRef SymName = *SymNameOrErr;
36 
37  ErrorOr<uint64_t> SymAddr = SymI->getAddress();
38  if (std::error_code EC = SymAddr.getError())
39  report_fatal_error(EC.message());
40  uint64_t SymSize = SymI->getSize();
41  int64_t Addend = *ELFRelocationRef(Rel).getAddend();
42 
43  MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
44  // FIXME: check that the value is actually the same.
45  if (!Sym->isVariable())
46  Sym->setVariableValue(MCConstantExpr::create(*SymAddr, Ctx));
47 
48  const MCExpr *Expr = nullptr;
49  // If hasAddend is true, then we need to add Addend (r_addend) to Expr.
50  bool hasAddend = false;
51 
52  // The AMD64 SysV ABI says:
53  // A: the addend used to compute the value of the relocatable field.
54  // B: the base address at which a shared object has been loaded into memory
55  // during execution. Generally, a shared object is built with a 0 base
56  // virtual address, but the execution address will be different.
57  // G: the offset into the global offset table at which the relocation
58  // entry's symbol will reside during execution.
59  // GOT: the address of the global offset table.
60  // L: the place (section offset or address) of the Procedure Linkage Table
61  // entry for a symbol.
62  // P: the place (section offset or address) of the storage unit being
63  // relocated (computed using r_offset).
64  // S: the value of the symbol whose index resides in the relocation entry.
65  // Z: the size of the symbol whose index resides in the relocation entry.
66 
67  switch(RelType) {
68  case R_X86_64_NONE:
69  case R_X86_64_COPY:
70  // none
71  break;
72  case R_X86_64_64:
73  case R_X86_64_16:
74  case R_X86_64_8:
75  // S + A
76  case R_X86_64_32:
77  case R_X86_64_32S:
78  // S + A (We don't care about the result not fitting in 32 bits.)
79  case R_X86_64_PC32:
80  case R_X86_64_PC16:
81  case R_X86_64_PC8:
82  case R_X86_64_PC64:
83  // S + A - P (P/pcrel is implicit)
84  hasAddend = true;
85  Expr = MCSymbolRefExpr::create(Sym, Ctx);
86  break;
87  case R_X86_64_GOT32:
88  case R_X86_64_GOT64:
89  case R_X86_64_GOTPC32:
90  case R_X86_64_GOTPC64:
91  case R_X86_64_GOTPLT64:
92  // G + A
93  hasAddend = true;
95  break;
96  case R_X86_64_PLT32:
97  // L + A - P -> S@PLT + A
98  hasAddend = true;
100  break;
101  case R_X86_64_GLOB_DAT:
102  case R_X86_64_JUMP_SLOT:
103  // S
104  Expr = MCSymbolRefExpr::create(Sym, Ctx);
105  break;
106  case R_X86_64_GOTPCREL:
107  case R_X86_64_GOTPCREL64:
108  // G + GOT + A - P -> S@GOTPCREL + A
109  hasAddend = true;
111  break;
112  case R_X86_64_GOTOFF64:
113  // S + A - GOT
115  break;
116  case R_X86_64_PLTOFF64:
117  // L + A - GOT
118  break;
119  case R_X86_64_SIZE32:
120  case R_X86_64_SIZE64:
121  // Z + A
122  Expr = MCConstantExpr::create(SymSize, Ctx);
123  break;
124  default:
125  Expr = MCSymbolRefExpr::create(Sym, Ctx);
126  break;
127  }
128  if (Expr && hasAddend && Addend != 0)
129  Expr = MCBinaryExpr::createAdd(Expr,
130  MCConstantExpr::create(Addend, Ctx),
131  Ctx);
132  return Expr;
133  }
134 };
135 } // End unnamed namespace
136 
137 /// createX86ELFRelocationInfo - Construct an X86 Mach-O RelocationInfo.
139  // We only handle x86-64 for now.
140  return new X86_64ELFRelocationInfo(Ctx);
141 }
std::error_code getError() const
Definition: ErrorOr.h:178
Represents either an error or a value T.
Definition: ErrorOr.h:82
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:40
uint64_t getSize() const
Context object for machine code objects.
Definition: MCContext.h:48
MCRelocationInfo * createX86_64ELFRelocationInfo(MCContext &Ctx)
Construct X86-64 ELF relocation info.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:446
symbol_iterator getSymbol() const
Definition: ObjectFile.h:436
Create MCExprs from relocations found in an object file.
ErrorOr< int64_t > getAddend() const
void setVariableValue(const MCExpr *Value)
Definition: MCSymbol.cpp:40
uint64_t getType() const
Definition: ObjectFile.h:440
ErrorOr< StringRef > getName() const
Definition: ObjectFile.h:306
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:294
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
ErrorOr< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Definition: ObjectFile.h:310
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:150