LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
X86ELFObjectWriter.cpp
Go to the documentation of this file.
1 //===-- X86ELFObjectWriter.cpp - X86 ELF Writer ---------------------------===//
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 
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCValue.h"
15 #include "llvm/Support/ELF.h"
17 
18 using namespace llvm;
19 
20 namespace {
21  class X86ELFObjectWriter : public MCELFObjectTargetWriter {
22  public:
23  X86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine);
24 
25  virtual ~X86ELFObjectWriter();
26  protected:
27  virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
28  bool IsPCRel, bool IsRelocWithSymbol,
29  int64_t Addend) const;
30  };
31 }
32 
33 X86ELFObjectWriter::X86ELFObjectWriter(bool IsELF64, uint8_t OSABI,
34  uint16_t EMachine)
35  : MCELFObjectTargetWriter(IsELF64, OSABI, EMachine,
36  // Only i386 uses Rel instead of RelA.
37  /*HasRelocationAddend*/ EMachine != ELF::EM_386) {}
38 
39 X86ELFObjectWriter::~X86ELFObjectWriter()
40 {}
41 
42 unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
43  const MCFixup &Fixup,
44  bool IsPCRel,
45  bool IsRelocWithSymbol,
46  int64_t Addend) const {
47  // determine the type of the relocation
48 
49  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
50  MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
51  unsigned Type;
52  if (getEMachine() == ELF::EM_X86_64) {
53  if (IsPCRel) {
54  switch ((unsigned)Fixup.getKind()) {
55  default: llvm_unreachable("invalid fixup kind!");
56 
57  case FK_Data_8: Type = ELF::R_X86_64_PC64; break;
58  case FK_Data_4: Type = ELF::R_X86_64_PC32; break;
59  case FK_Data_2: Type = ELF::R_X86_64_PC16; break;
60 
61  case FK_PCRel_8:
62  assert(Modifier == MCSymbolRefExpr::VK_None);
63  Type = ELF::R_X86_64_PC64;
64  break;
68  case FK_PCRel_4:
69  switch (Modifier) {
70  default:
71  llvm_unreachable("Unimplemented");
72  case MCSymbolRefExpr::VK_None:
73  Type = ELF::R_X86_64_PC32;
74  break;
75  case MCSymbolRefExpr::VK_PLT:
76  Type = ELF::R_X86_64_PLT32;
77  break;
78  case MCSymbolRefExpr::VK_GOTPCREL:
80  break;
81  case MCSymbolRefExpr::VK_GOTTPOFF:
83  break;
84  case MCSymbolRefExpr::VK_TLSGD:
85  Type = ELF::R_X86_64_TLSGD;
86  break;
87  case MCSymbolRefExpr::VK_TLSLD:
88  Type = ELF::R_X86_64_TLSLD;
89  break;
90  }
91  break;
92  case FK_PCRel_2:
93  assert(Modifier == MCSymbolRefExpr::VK_None);
94  Type = ELF::R_X86_64_PC16;
95  break;
96  case FK_PCRel_1:
97  assert(Modifier == MCSymbolRefExpr::VK_None);
98  Type = ELF::R_X86_64_PC8;
99  break;
100  }
101  } else {
102  switch ((unsigned)Fixup.getKind()) {
103  default: llvm_unreachable("invalid fixup kind!");
104  case FK_Data_8:
105  switch (Modifier) {
106  default:
107  llvm_unreachable("Unimplemented");
108  case MCSymbolRefExpr::VK_None:
109  Type = ELF::R_X86_64_64;
110  break;
111  case MCSymbolRefExpr::VK_GOT:
112  Type = ELF::R_X86_64_GOT64;
113  break;
114  case MCSymbolRefExpr::VK_GOTOFF:
115  Type = ELF::R_X86_64_GOTOFF64;
116  break;
117  case MCSymbolRefExpr::VK_TPOFF:
118  Type = ELF::R_X86_64_TPOFF64;
119  break;
120  case MCSymbolRefExpr::VK_DTPOFF:
121  Type = ELF::R_X86_64_DTPOFF64;
122  break;
123  }
124  break;
126  switch (Modifier) {
127  default:
128  llvm_unreachable("Unimplemented");
129  case MCSymbolRefExpr::VK_None:
130  Type = ELF::R_X86_64_32S;
131  break;
132  case MCSymbolRefExpr::VK_GOT:
133  Type = ELF::R_X86_64_GOT32;
134  break;
135  case MCSymbolRefExpr::VK_GOTPCREL:
136  Type = ELF::R_X86_64_GOTPCREL;
137  break;
138  case MCSymbolRefExpr::VK_TPOFF:
139  Type = ELF::R_X86_64_TPOFF32;
140  break;
141  case MCSymbolRefExpr::VK_DTPOFF:
142  Type = ELF::R_X86_64_DTPOFF32;
143  break;
144  }
145  break;
146  case FK_Data_4:
147  Type = ELF::R_X86_64_32;
148  break;
149  case FK_Data_2: Type = ELF::R_X86_64_16; break;
150  case FK_PCRel_1:
151  case FK_Data_1: Type = ELF::R_X86_64_8; break;
152  }
153  }
154  } else if (getEMachine() == ELF::EM_386) {
155  if (IsPCRel) {
156  switch ((unsigned)Fixup.getKind()) {
157  default: llvm_unreachable("invalid fixup kind!");
158 
160  Type = ELF::R_386_GOTPC;
161  break;
162 
164  case FK_PCRel_4:
165  case FK_Data_4:
166  switch (Modifier) {
167  default:
168  llvm_unreachable("Unimplemented");
169  case MCSymbolRefExpr::VK_None:
170  Type = ELF::R_386_PC32;
171  break;
172  case MCSymbolRefExpr::VK_PLT:
173  Type = ELF::R_386_PLT32;
174  break;
175  }
176  break;
177  }
178  } else {
179  switch ((unsigned)Fixup.getKind()) {
180  default: llvm_unreachable("invalid fixup kind!");
181 
183  Type = ELF::R_386_GOTPC;
184  break;
185 
186  // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
187  // instead?
189  case FK_PCRel_4:
190  case FK_Data_4:
191  switch (Modifier) {
192  default:
193  llvm_unreachable("Unimplemented");
194  case MCSymbolRefExpr::VK_None:
195  Type = ELF::R_386_32;
196  break;
197  case MCSymbolRefExpr::VK_GOT:
198  Type = ELF::R_386_GOT32;
199  break;
200  case MCSymbolRefExpr::VK_GOTOFF:
201  Type = ELF::R_386_GOTOFF;
202  break;
203  case MCSymbolRefExpr::VK_TLSGD:
204  Type = ELF::R_386_TLS_GD;
205  break;
206  case MCSymbolRefExpr::VK_TPOFF:
207  Type = ELF::R_386_TLS_LE_32;
208  break;
209  case MCSymbolRefExpr::VK_INDNTPOFF:
210  Type = ELF::R_386_TLS_IE;
211  break;
212  case MCSymbolRefExpr::VK_NTPOFF:
213  Type = ELF::R_386_TLS_LE;
214  break;
215  case MCSymbolRefExpr::VK_GOTNTPOFF:
216  Type = ELF::R_386_TLS_GOTIE;
217  break;
218  case MCSymbolRefExpr::VK_TLSLDM:
219  Type = ELF::R_386_TLS_LDM;
220  break;
221  case MCSymbolRefExpr::VK_DTPOFF:
222  Type = ELF::R_386_TLS_LDO_32;
223  break;
224  case MCSymbolRefExpr::VK_GOTTPOFF:
225  Type = ELF::R_386_TLS_IE_32;
226  break;
227  }
228  break;
229  case FK_Data_2: Type = ELF::R_386_16; break;
230  case FK_PCRel_1:
231  case FK_Data_1: Type = ELF::R_386_8; break;
232  }
233  }
234  } else
235  llvm_unreachable("Unsupported ELF machine type.");
236 
237  return Type;
238 }
239 
241  bool IsELF64,
242  uint8_t OSABI,
243  uint16_t EMachine) {
245  new X86ELFObjectWriter(IsELF64, OSABI, EMachine);
246  return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
247 }
COFF::RelocationTypeX86 Type
Definition: COFFYAML.cpp:227
A eight-byte pc relative fixup.
Definition: MCFixup.h:30
A one-byte pc relative fixup.
Definition: MCFixup.h:27
#define llvm_unreachable(msg)
A four-byte fixup.
Definition: MCFixup.h:25
bool isAbsolute() const
isAbsolute - Is this an absolute (as opposed to relocatable) value.
Definition: MCValue.h:47
MCFixupKind getKind() const
Definition: MCFixup.h:88
MCObjectWriter * createELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &OS, bool IsLittleEndian)
Construct a new ELF writer instance.
A one-byte fixup.
Definition: MCFixup.h:23
A two-byte pc relative fixup.
Definition: MCFixup.h:28
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:43
A four-byte pc relative fixup.
Definition: MCFixup.h:29
MCObjectWriter * createX86ELFObjectWriter(raw_ostream &OS, bool IsELF64, uint8_t OSABI, uint16_t EMachine)
createX86ELFObjectWriter - Construct an X86 ELF object writer.
A eight-byte fixup.
Definition: MCFixup.h:26
VariantKind getKind() const
Definition: MCExpr.h:285
A two-byte fixup.
Definition: MCFixup.h:24