LLVM  8.0.1
AArch64ELFObjectWriter.cpp
Go to the documentation of this file.
1 //===-- AArch64ELFObjectWriter.cpp - AArch64 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 //
10 // This file handles ELF-specific object emission, converting LLVM's internal
11 // fixups into the appropriate relocations.
12 //
13 //===----------------------------------------------------------------------===//
14 
18 #include "llvm/BinaryFormat/ELF.h"
19 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCFixup.h"
22 #include "llvm/MC/MCObjectWriter.h"
23 #include "llvm/MC/MCValue.h"
25 #include <cassert>
26 #include <cstdint>
27 
28 using namespace llvm;
29 
30 namespace {
31 
32 class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
33 public:
34  AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32);
35 
36  ~AArch64ELFObjectWriter() override = default;
37 
38 protected:
39  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
40  const MCFixup &Fixup, bool IsPCRel) const override;
41  bool IsILP32;
42 };
43 
44 } // end anonymous namespace
45 
46 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
47  : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64,
48  /*HasRelocationAddend*/ true),
49  IsILP32(IsILP32) {}
50 
51 #define R_CLS(rtype) \
52  IsILP32 ? ELF::R_AARCH64_P32_##rtype : ELF::R_AARCH64_##rtype
53 #define BAD_ILP32_MOV(lp64rtype) \
54  "ILP32 absolute MOV relocation not " \
55  "supported (LP64 eqv: " #lp64rtype ")"
56 
57 // assumes IsILP32 is true
58 static bool isNonILP32reloc(const MCFixup &Fixup,
60  MCContext &Ctx) {
61  if ((unsigned)Fixup.getKind() != AArch64::fixup_aarch64_movw)
62  return false;
63  switch (RefKind) {
65  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G3));
66  return true;
68  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2));
69  return true;
71  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G2));
72  return true;
74  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2_NC));
75  return true;
77  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G1));
78  return true;
80  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G1_NC));
81  return true;
83  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G2));
84  return true;
86  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G1_NC));
87  return true;
89  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G2));
90  return true;
92  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G1_NC));
93  return true;
95  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G1));
96  return true;
98  Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G0_NC));
99  return true;
100  default:
101  return false;
102  }
103  return false;
104 }
105 
107  const MCValue &Target,
108  const MCFixup &Fixup,
109  bool IsPCRel) const {
111  static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
113  bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
114 
115  assert((!Target.getSymA() ||
116  Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) &&
117  "Should only be expression-level modifiers here");
118 
119  assert((!Target.getSymB() ||
120  Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
121  "Should only be expression-level modifiers here");
122 
123  if (IsPCRel) {
124  switch ((unsigned)Fixup.getKind()) {
125  case FK_Data_1:
126  Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
127  return ELF::R_AARCH64_NONE;
128  case FK_Data_2:
129  return R_CLS(PREL16);
130  case FK_Data_4:
131  return R_CLS(PREL32);
132  case FK_Data_8:
133  if (IsILP32) {
134  Ctx.reportError(Fixup.getLoc(),
135  "ILP32 8 byte PC relative data "
136  "relocation not supported (LP64 eqv: PREL64)");
137  return ELF::R_AARCH64_NONE;
138  } else
139  return ELF::R_AARCH64_PREL64;
141  if (SymLoc != AArch64MCExpr::VK_ABS)
142  Ctx.reportError(Fixup.getLoc(),
143  "invalid symbol kind for ADR relocation");
144  return R_CLS(ADR_PREL_LO21);
146  if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
147  return R_CLS(ADR_PREL_PG_HI21);
148  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) {
149  if (IsILP32) {
150  Ctx.reportError(Fixup.getLoc(),
151  "invalid fixup for 32-bit pcrel ADRP instruction "
152  "VK_ABS VK_NC");
153  return ELF::R_AARCH64_NONE;
154  } else {
155  return ELF::R_AARCH64_ADR_PREL_PG_HI21_NC;
156  }
157  }
158  if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
159  return R_CLS(ADR_GOT_PAGE);
160  if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
161  return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
162  if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
163  return R_CLS(TLSDESC_ADR_PAGE21);
164  Ctx.reportError(Fixup.getLoc(),
165  "invalid symbol kind for ADRP relocation");
166  return ELF::R_AARCH64_NONE;
168  return R_CLS(JUMP26);
170  return R_CLS(CALL26);
172  if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
173  return R_CLS(TLSIE_LD_GOTTPREL_PREL19);
174  if (SymLoc == AArch64MCExpr::VK_GOT)
175  return R_CLS(GOT_LD_PREL19);
176  return R_CLS(LD_PREL_LO19);
178  return R_CLS(TSTBR14);
180  return R_CLS(CONDBR19);
181  default:
182  Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
183  return ELF::R_AARCH64_NONE;
184  }
185  } else {
186  if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx))
187  return ELF::R_AARCH64_NONE;
188  switch ((unsigned)Fixup.getKind()) {
189  case FK_Data_1:
190  Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
191  return ELF::R_AARCH64_NONE;
192  case FK_Data_2:
193  return R_CLS(ABS16);
194  case FK_Data_4:
195  return R_CLS(ABS32);
196  case FK_Data_8:
197  if (IsILP32) {
198  Ctx.reportError(Fixup.getLoc(),
199  "ILP32 8 byte absolute data "
200  "relocation not supported (LP64 eqv: ABS64)");
201  return ELF::R_AARCH64_NONE;
202  } else
203  return ELF::R_AARCH64_ABS64;
205  if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
206  return R_CLS(TLSLD_ADD_DTPREL_HI12);
207  if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
208  return R_CLS(TLSLE_ADD_TPREL_HI12);
209  if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
210  return R_CLS(TLSLD_ADD_DTPREL_LO12_NC);
211  if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
212  return R_CLS(TLSLD_ADD_DTPREL_LO12);
213  if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
214  return R_CLS(TLSLE_ADD_TPREL_LO12_NC);
215  if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
216  return R_CLS(TLSLE_ADD_TPREL_LO12);
217  if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
218  return R_CLS(TLSDESC_ADD_LO12);
219  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
220  return R_CLS(ADD_ABS_LO12_NC);
221 
222  Ctx.reportError(Fixup.getLoc(),
223  "invalid fixup for add (uimm12) instruction");
224  return ELF::R_AARCH64_NONE;
226  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
227  return R_CLS(LDST8_ABS_LO12_NC);
228  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
229  return R_CLS(TLSLD_LDST8_DTPREL_LO12);
230  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
231  return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC);
232  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
233  return R_CLS(TLSLE_LDST8_TPREL_LO12);
234  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
235  return R_CLS(TLSLE_LDST8_TPREL_LO12_NC);
236 
237  Ctx.reportError(Fixup.getLoc(),
238  "invalid fixup for 8-bit load/store instruction");
239  return ELF::R_AARCH64_NONE;
241  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
242  return R_CLS(LDST16_ABS_LO12_NC);
243  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
244  return R_CLS(TLSLD_LDST16_DTPREL_LO12);
245  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
246  return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC);
247  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
248  return R_CLS(TLSLE_LDST16_TPREL_LO12);
249  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
250  return R_CLS(TLSLE_LDST16_TPREL_LO12_NC);
251 
252  Ctx.reportError(Fixup.getLoc(),
253  "invalid fixup for 16-bit load/store instruction");
254  return ELF::R_AARCH64_NONE;
256  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
257  return R_CLS(LDST32_ABS_LO12_NC);
258  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
259  return R_CLS(TLSLD_LDST32_DTPREL_LO12);
260  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
261  return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC);
262  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
263  return R_CLS(TLSLE_LDST32_TPREL_LO12);
264  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
265  return R_CLS(TLSLE_LDST32_TPREL_LO12_NC);
266  if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
267  if (IsILP32) {
268  return ELF::R_AARCH64_P32_LD32_GOT_LO12_NC;
269  } else {
270  Ctx.reportError(Fixup.getLoc(),
271  "LP64 4 byte unchecked GOT load/store relocation "
272  "not supported (ILP32 eqv: LD32_GOT_LO12_NC");
273  return ELF::R_AARCH64_NONE;
274  }
275  }
276  if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) {
277  if (IsILP32) {
278  Ctx.reportError(Fixup.getLoc(),
279  "ILP32 4 byte checked GOT load/store relocation "
280  "not supported (unchecked eqv: LD32_GOT_LO12_NC)");
281  } else {
282  Ctx.reportError(Fixup.getLoc(),
283  "LP64 4 byte checked GOT load/store relocation "
284  "not supported (unchecked/ILP32 eqv: "
285  "LD32_GOT_LO12_NC)");
286  }
287  return ELF::R_AARCH64_NONE;
288  }
289  if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
290  if (IsILP32) {
291  return ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC;
292  } else {
293  Ctx.reportError(Fixup.getLoc(),
294  "LP64 32-bit load/store "
295  "relocation not supported (ILP32 eqv: "
296  "TLSIE_LD32_GOTTPREL_LO12_NC)");
297  return ELF::R_AARCH64_NONE;
298  }
299  }
300  if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) {
301  if (IsILP32) {
302  return ELF::R_AARCH64_P32_TLSDESC_LD32_LO12;
303  } else {
304  Ctx.reportError(Fixup.getLoc(),
305  "LP64 4 byte TLSDESC load/store relocation "
306  "not supported (ILP32 eqv: TLSDESC_LD64_LO12)");
307  return ELF::R_AARCH64_NONE;
308  }
309  }
310 
311  Ctx.reportError(Fixup.getLoc(),
312  "invalid fixup for 32-bit load/store instruction "
313  "fixup_aarch64_ldst_imm12_scale4");
314  return ELF::R_AARCH64_NONE;
316  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
317  return R_CLS(LDST64_ABS_LO12_NC);
318  if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
319  if (!IsILP32) {
320  return ELF::R_AARCH64_LD64_GOT_LO12_NC;
321  } else {
322  Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
323  "relocation not supported (LP64 eqv: "
324  "LD64_GOT_LO12_NC)");
325  return ELF::R_AARCH64_NONE;
326  }
327  }
328  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
329  return R_CLS(TLSLD_LDST64_DTPREL_LO12);
330  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
331  return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC);
332  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
333  return R_CLS(TLSLE_LDST64_TPREL_LO12);
334  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
335  return R_CLS(TLSLE_LDST64_TPREL_LO12_NC);
336  if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) {
337  if (!IsILP32) {
338  return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
339  } else {
340  Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
341  "relocation not supported (LP64 eqv: "
342  "TLSIE_LD64_GOTTPREL_LO12_NC)");
343  return ELF::R_AARCH64_NONE;
344  }
345  }
346  if (SymLoc == AArch64MCExpr::VK_TLSDESC) {
347  if (!IsILP32) {
348  return ELF::R_AARCH64_TLSDESC_LD64_LO12;
349  } else {
350  Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
351  "relocation not supported (LP64 eqv: "
352  "TLSDESC_LD64_LO12)");
353  return ELF::R_AARCH64_NONE;
354  }
355  }
356  Ctx.reportError(Fixup.getLoc(),
357  "invalid fixup for 64-bit load/store instruction");
358  return ELF::R_AARCH64_NONE;
360  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
361  return R_CLS(LDST128_ABS_LO12_NC);
362  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
363  return R_CLS(TLSLD_LDST128_DTPREL_LO12);
364  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
365  return R_CLS(TLSLD_LDST128_DTPREL_LO12_NC);
366  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
367  return R_CLS(TLSLE_LDST128_TPREL_LO12);
368  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
369  return R_CLS(TLSLE_LDST128_TPREL_LO12_NC);
370 
371  Ctx.reportError(Fixup.getLoc(),
372  "invalid fixup for 128-bit load/store instruction");
373  return ELF::R_AARCH64_NONE;
374  // ILP32 case not reached here, tested with isNonILP32reloc
376  if (RefKind == AArch64MCExpr::VK_ABS_G3)
377  return ELF::R_AARCH64_MOVW_UABS_G3;
378  if (RefKind == AArch64MCExpr::VK_ABS_G2)
379  return ELF::R_AARCH64_MOVW_UABS_G2;
380  if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
381  return ELF::R_AARCH64_MOVW_SABS_G2;
382  if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
383  return ELF::R_AARCH64_MOVW_UABS_G2_NC;
384  if (RefKind == AArch64MCExpr::VK_ABS_G1)
385  return R_CLS(MOVW_UABS_G1);
386  if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
387  return ELF::R_AARCH64_MOVW_SABS_G1;
388  if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
389  return ELF::R_AARCH64_MOVW_UABS_G1_NC;
390  if (RefKind == AArch64MCExpr::VK_ABS_G0)
391  return R_CLS(MOVW_UABS_G0);
392  if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
393  return R_CLS(MOVW_SABS_G0);
394  if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
395  return R_CLS(MOVW_UABS_G0_NC);
396  if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
397  return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
398  if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
399  return R_CLS(TLSLD_MOVW_DTPREL_G1);
400  if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
401  return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
402  if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
403  return R_CLS(TLSLD_MOVW_DTPREL_G0);
404  if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
405  return R_CLS(TLSLD_MOVW_DTPREL_G0_NC);
406  if (RefKind == AArch64MCExpr::VK_TPREL_G2)
407  return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
408  if (RefKind == AArch64MCExpr::VK_TPREL_G1)
409  return R_CLS(TLSLE_MOVW_TPREL_G1);
410  if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
411  return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
412  if (RefKind == AArch64MCExpr::VK_TPREL_G0)
413  return R_CLS(TLSLE_MOVW_TPREL_G0);
414  if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
415  return R_CLS(TLSLE_MOVW_TPREL_G0_NC);
416  if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
417  return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
418  if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
419  return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
420  Ctx.reportError(Fixup.getLoc(),
421  "invalid fixup for movz/movk instruction");
422  return ELF::R_AARCH64_NONE;
424  return R_CLS(TLSDESC_CALL);
425  default:
426  Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
427  return ELF::R_AARCH64_NONE;
428  }
429  }
430 
431  llvm_unreachable("Unimplemented fixup -> relocation");
432 }
433 
434 std::unique_ptr<MCObjectTargetWriter>
435 llvm::createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32) {
436  return llvm::make_unique<AArch64ELFObjectWriter>(OSABI, IsILP32);
437 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
This represents an "assembler immediate".
Definition: MCValue.h:40
VariantKind getKind() const
Definition: MCExpr.h:338
#define BAD_ILP32_MOV(lp64rtype)
#define R_CLS(rtype)
block Block Frequency true
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:74
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:49
static unsigned getRelocType(const MCValue &Target, const MCFixupKind FixupKind, const bool IsPCRel)
Translates generic PPC fixup kind to Mach-O/PPC relocation type enum.
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:63
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:48
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:612
std::unique_ptr< MCObjectTargetWriter > createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
static bool isNonILP32reloc(const MCFixup &Fixup, AArch64MCExpr::VariantKind RefKind, MCContext &Ctx)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A one-byte fixup.
Definition: MCFixup.h:24
PowerPC TLS Dynamic Call Fixup
SMLoc getLoc() const
Definition: MCFixup.h:166
Target - Wrapper for Target specific information.
static bool isNotChecked(VariantKind Kind)
A eight-byte fixup.
Definition: MCFixup.h:27
uint32_t getRefKind() const
Definition: MCValue.h:50
static VariantKind getSymbolLoc(VariantKind Kind)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A two-byte fixup.
Definition: MCFixup.h:25
MCFixupKind getKind() const
Definition: MCFixup.h:123