LLVM  3.7.0
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  ~X86ELFObjectWriter() override;
26 
27  protected:
28  unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
29  bool IsPCRel) const override;
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 
43 
44 static X86_64RelType getType64(unsigned Kind,
46  bool &IsPCRel) {
47  switch (Kind) {
48  default:
49  llvm_unreachable("Unimplemented");
51  Modifier = MCSymbolRefExpr::VK_GOT;
52  IsPCRel = true;
53  return RT64_64;
54  case FK_Data_8:
55  return RT64_64;
57  if (Modifier == MCSymbolRefExpr::VK_None && !IsPCRel)
58  return RT64_32S;
59  return RT64_32;
61  Modifier = MCSymbolRefExpr::VK_GOT;
62  IsPCRel = true;
63  return RT64_32;
64  case FK_Data_4:
65  case FK_PCRel_4:
68  return RT64_32;
69  case FK_PCRel_2:
70  case FK_Data_2:
71  return RT64_16;
72  case FK_PCRel_1:
73  case FK_Data_1:
74  return RT64_8;
75  }
76 }
77 
79  X86_64RelType Type, bool IsPCRel) {
80  switch (Modifier) {
81  default:
82  llvm_unreachable("Unimplemented");
84  switch (Type) {
85  case RT64_64:
86  return IsPCRel ? ELF::R_X86_64_PC64 : ELF::R_X86_64_64;
87  case RT64_32:
88  return IsPCRel ? ELF::R_X86_64_PC32 : ELF::R_X86_64_32;
89  case RT64_32S:
90  return ELF::R_X86_64_32S;
91  case RT64_16:
92  return IsPCRel ? ELF::R_X86_64_PC16 : ELF::R_X86_64_16;
93  case RT64_8:
94  return IsPCRel ? ELF::R_X86_64_PC8 : ELF::R_X86_64_8;
95  }
97  switch (Type) {
98  case RT64_64:
99  return IsPCRel ? ELF::R_X86_64_GOTPC64 : ELF::R_X86_64_GOT64;
100  case RT64_32:
101  return IsPCRel ? ELF::R_X86_64_GOTPC32 : ELF::R_X86_64_GOT32;
102  case RT64_32S:
103  case RT64_16:
104  case RT64_8:
105  llvm_unreachable("Unimplemented");
106  }
108  assert(Type == RT64_64);
109  assert(!IsPCRel);
110  return ELF::R_X86_64_GOTOFF64;
112  assert(!IsPCRel);
113  switch (Type) {
114  case RT64_64:
115  return ELF::R_X86_64_TPOFF64;
116  case RT64_32:
117  return ELF::R_X86_64_TPOFF32;
118  case RT64_32S:
119  case RT64_16:
120  case RT64_8:
121  llvm_unreachable("Unimplemented");
122  }
124  assert(!IsPCRel);
125  switch (Type) {
126  case RT64_64:
127  return ELF::R_X86_64_DTPOFF64;
128  case RT64_32:
129  return ELF::R_X86_64_DTPOFF32;
130  case RT64_32S:
131  case RT64_16:
132  case RT64_8:
133  llvm_unreachable("Unimplemented");
134  }
136  assert(!IsPCRel);
137  switch (Type) {
138  case RT64_64:
139  return ELF::R_X86_64_SIZE64;
140  case RT64_32:
141  return ELF::R_X86_64_SIZE32;
142  case RT64_32S:
143  case RT64_16:
144  case RT64_8:
145  llvm_unreachable("Unimplemented");
146  }
148  assert(Type == RT64_32);
149  return ELF::R_X86_64_TLSGD;
151  assert(Type == RT64_32);
152  return ELF::R_X86_64_GOTTPOFF;
154  assert(Type == RT64_32);
155  return ELF::R_X86_64_TLSLD;
157  assert(Type == RT64_32);
158  return ELF::R_X86_64_PLT32;
160  assert(Type == RT64_32);
161  return ELF::R_X86_64_GOTPCREL;
162  }
163 }
164 
166 
168  switch (T) {
169  case RT64_64:
170  llvm_unreachable("Unimplemented");
171  case RT64_32:
172  case RT64_32S:
173  return RT32_32;
174  case RT64_16:
175  return RT32_16;
176  case RT64_8:
177  return RT32_8;
178  }
179  llvm_unreachable("unexpected relocation type!");
180 }
181 
183  X86_32RelType Type, bool IsPCRel) {
184  switch (Modifier) {
185  default:
186  llvm_unreachable("Unimplemented");
188  switch (Type) {
189  case RT32_32:
190  return IsPCRel ? ELF::R_386_PC32 : ELF::R_386_32;
191  case RT32_16:
192  return IsPCRel ? ELF::R_386_PC16 : ELF::R_386_16;
193  case RT32_8:
194  return IsPCRel ? ELF::R_386_PC8 : ELF::R_386_8;
195  }
197  assert(Type == RT32_32);
198  return IsPCRel ? ELF::R_386_GOTPC : ELF::R_386_GOT32;
200  assert(Type == RT32_32);
201  assert(!IsPCRel);
202  return ELF::R_386_GOTOFF;
204  assert(Type == RT32_32);
205  assert(!IsPCRel);
206  return ELF::R_386_TLS_LE_32;
208  assert(Type == RT32_32);
209  assert(!IsPCRel);
210  return ELF::R_386_TLS_LDO_32;
212  assert(Type == RT32_32);
213  assert(!IsPCRel);
214  return ELF::R_386_TLS_GD;
216  assert(Type == RT32_32);
217  assert(!IsPCRel);
218  return ELF::R_386_TLS_IE_32;
220  assert(Type == RT32_32);
221  return ELF::R_386_PLT32;
223  assert(Type == RT32_32);
224  assert(!IsPCRel);
225  return ELF::R_386_TLS_IE;
227  assert(Type == RT32_32);
228  assert(!IsPCRel);
229  return ELF::R_386_TLS_LE;
231  assert(Type == RT32_32);
232  assert(!IsPCRel);
233  return ELF::R_386_TLS_GOTIE;
235  assert(Type == RT32_32);
236  assert(!IsPCRel);
237  return ELF::R_386_TLS_LDM;
238  }
239 }
240 
241 unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
242  const MCFixup &Fixup,
243  bool IsPCRel) const {
245  X86_64RelType Type = getType64(Fixup.getKind(), Modifier, IsPCRel);
246  if (getEMachine() == ELF::EM_X86_64)
247  return getRelocType64(Modifier, Type, IsPCRel);
248 
249  assert(getEMachine() == ELF::EM_386 && "Unsupported ELF machine type.");
250  return getRelocType32(Modifier, getType32(Type), IsPCRel);
251 }
252 
254  bool IsELF64, uint8_t OSABI,
255  uint16_t EMachine) {
257  new X86ELFObjectWriter(IsELF64, OSABI, EMachine);
258  return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
259 }
This represents an "assembler immediate".
Definition: MCValue.h:44
Defines the object file and target independent interfaces used by the assembler backend to write nati...
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:62
A one-byte pc relative fixup.
Definition: MCFixup.h:28
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
A four-byte fixup.
Definition: MCFixup.h:26
static X86_64RelType getType64(unsigned Kind, MCSymbolRefExpr::VariantKind &Modifier, bool &IsPCRel)
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
static X86_32RelType getType32(X86_64RelType T)
MCSymbolRefExpr::VariantKind getAccessVariant() const
Definition: MCValue.cpp:46
MCFixupKind getKind() const
Definition: MCFixup.h:89
A one-byte fixup.
Definition: MCFixup.h:24
PowerPC TLS Dynamic Call Fixup
A two-byte pc relative fixup.
Definition: MCFixup.h:29
A four-byte pc relative fixup.
Definition: MCFixup.h:30
static unsigned getRelocType32(MCSymbolRefExpr::VariantKind Modifier, X86_32RelType Type, bool IsPCRel)
MCObjectWriter * createX86ELFObjectWriter(raw_pwrite_stream &OS, bool IsELF64, uint8_t OSABI, uint16_t EMachine)
Construct an X86 ELF object writer.
Target - Wrapper for Target specific information.
MCObjectWriter * createELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new ELF writer instance.
static unsigned getRelocType64(MCSymbolRefExpr::VariantKind Modifier, X86_64RelType Type, bool IsPCRel)
A eight-byte fixup.
Definition: MCFixup.h:27
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:321
const ARM::ArchExtKind Kind
A two-byte fixup.
Definition: MCFixup.h:25