LLVM  3.7.0
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 
19 #include "llvm/MC/MCValue.h"
21 
22 using namespace llvm;
23 
24 namespace {
25 class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
26 public:
27  AArch64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian);
28 
29  ~AArch64ELFObjectWriter() override;
30 
31 protected:
32  unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
33  bool IsPCRel) const override;
34 
35 private:
36 };
37 }
38 
39 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI,
40  bool IsLittleEndian)
41  : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64,
42  /*HasRelocationAddend*/ true) {}
43 
44 AArch64ELFObjectWriter::~AArch64ELFObjectWriter() {}
45 
46 unsigned AArch64ELFObjectWriter::GetRelocType(const MCValue &Target,
47  const MCFixup &Fixup,
48  bool IsPCRel) const {
50  static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
52  bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
53 
54  assert((!Target.getSymA() ||
55  Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) &&
56  "Should only be expression-level modifiers here");
57 
58  assert((!Target.getSymB() ||
59  Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
60  "Should only be expression-level modifiers here");
61 
62  if (IsPCRel) {
63  switch ((unsigned)Fixup.getKind()) {
64  case FK_Data_2:
65  return ELF::R_AARCH64_PREL16;
66  case FK_Data_4:
67  return ELF::R_AARCH64_PREL32;
68  case FK_Data_8:
69  return ELF::R_AARCH64_PREL64;
71  assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation");
72  return ELF::R_AARCH64_ADR_PREL_LO21;
74  if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
75  return ELF::R_AARCH64_ADR_PREL_PG_HI21;
76  if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
77  return ELF::R_AARCH64_ADR_GOT_PAGE;
78  if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
79  return ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21;
80  if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
81  return ELF::R_AARCH64_TLSDESC_ADR_PAGE21;
82  llvm_unreachable("invalid symbol kind for ADRP relocation");
84  return ELF::R_AARCH64_JUMP26;
86  return ELF::R_AARCH64_CALL26;
88  if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
89  return ELF::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19;
90  return ELF::R_AARCH64_LD_PREL_LO19;
92  return ELF::R_AARCH64_TSTBR14;
94  return ELF::R_AARCH64_CONDBR19;
95  default:
96  llvm_unreachable("Unsupported pc-relative fixup kind");
97  }
98  } else {
99  switch ((unsigned)Fixup.getKind()) {
100  case FK_Data_2:
101  return ELF::R_AARCH64_ABS16;
102  case FK_Data_4:
103  return ELF::R_AARCH64_ABS32;
104  case FK_Data_8:
105  return ELF::R_AARCH64_ABS64;
107  if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
108  return ELF::R_AARCH64_TLSLD_ADD_DTPREL_HI12;
109  if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
110  return ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12;
111  if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
112  return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC;
113  if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
114  return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12;
115  if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
116  return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC;
117  if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
118  return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12;
119  if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
120  return ELF::R_AARCH64_TLSDESC_ADD_LO12_NC;
121  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
122  return ELF::R_AARCH64_ADD_ABS_LO12_NC;
123 
124  report_fatal_error("invalid fixup for add (uimm12) instruction");
125  return 0;
127  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
128  return ELF::R_AARCH64_LDST8_ABS_LO12_NC;
129  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
130  return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12;
131  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
132  return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC;
133  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
134  return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12;
135  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
136  return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC;
137 
138  report_fatal_error("invalid fixup for 8-bit load/store instruction");
139  return 0;
141  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
142  return ELF::R_AARCH64_LDST16_ABS_LO12_NC;
143  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
144  return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12;
145  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
146  return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC;
147  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
148  return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12;
149  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
150  return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC;
151 
152  report_fatal_error("invalid fixup for 16-bit load/store instruction");
153  return 0;
155  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
156  return ELF::R_AARCH64_LDST32_ABS_LO12_NC;
157  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
158  return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12;
159  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
160  return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC;
161  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
162  return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12;
163  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
164  return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC;
165 
166  report_fatal_error("invalid fixup for 32-bit load/store instruction");
167  return 0;
169  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
170  return ELF::R_AARCH64_LDST64_ABS_LO12_NC;
171  if (SymLoc == AArch64MCExpr::VK_GOT && IsNC)
172  return ELF::R_AARCH64_LD64_GOT_LO12_NC;
173  if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
174  return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12;
175  if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
176  return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC;
177  if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
178  return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12;
179  if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
180  return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC;
181  if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC)
182  return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
183  if (SymLoc == AArch64MCExpr::VK_TLSDESC && IsNC)
184  return ELF::R_AARCH64_TLSDESC_LD64_LO12_NC;
185 
186  report_fatal_error("invalid fixup for 64-bit load/store instruction");
187  return 0;
189  if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
190  return ELF::R_AARCH64_LDST128_ABS_LO12_NC;
191 
192  report_fatal_error("invalid fixup for 128-bit load/store instruction");
193  return 0;
195  if (RefKind == AArch64MCExpr::VK_ABS_G3)
196  return ELF::R_AARCH64_MOVW_UABS_G3;
197  if (RefKind == AArch64MCExpr::VK_ABS_G2)
198  return ELF::R_AARCH64_MOVW_UABS_G2;
199  if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
200  return ELF::R_AARCH64_MOVW_SABS_G2;
201  if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
202  return ELF::R_AARCH64_MOVW_UABS_G2_NC;
203  if (RefKind == AArch64MCExpr::VK_ABS_G1)
204  return ELF::R_AARCH64_MOVW_UABS_G1;
205  if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
206  return ELF::R_AARCH64_MOVW_SABS_G1;
207  if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
208  return ELF::R_AARCH64_MOVW_UABS_G1_NC;
209  if (RefKind == AArch64MCExpr::VK_ABS_G0)
210  return ELF::R_AARCH64_MOVW_UABS_G0;
211  if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
212  return ELF::R_AARCH64_MOVW_SABS_G0;
213  if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
214  return ELF::R_AARCH64_MOVW_UABS_G0_NC;
215  if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
216  return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
217  if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
218  return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1;
219  if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
220  return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
221  if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
222  return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0;
223  if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
224  return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC;
225  if (RefKind == AArch64MCExpr::VK_TPREL_G2)
226  return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
227  if (RefKind == AArch64MCExpr::VK_TPREL_G1)
228  return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1;
229  if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
230  return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
231  if (RefKind == AArch64MCExpr::VK_TPREL_G0)
232  return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0;
233  if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
234  return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC;
235  if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
236  return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
237  if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
238  return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
239  report_fatal_error("invalid fixup for movz/movk instruction");
240  return 0;
242  return ELF::R_AARCH64_TLSDESC_CALL;
243  default:
244  llvm_unreachable("Unknown ELF relocation type");
245  }
246  }
247 
248  llvm_unreachable("Unimplemented fixup -> relocation");
249 }
250 
252  uint8_t OSABI,
253  bool IsLittleEndian) {
255  new AArch64ELFObjectWriter(OSABI, IsLittleEndian);
256  return createELFObjectWriter(MOTW, OS, IsLittleEndian);
257 }
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...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:62
#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
#define true
Definition: ConvertUTF.c:66
MCObjectWriter * createAArch64ELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool IsLittleEndian)
MCFixupKind getKind() const
Definition: MCFixup.h:89
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:52
PowerPC TLS Dynamic Call Fixup
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:51
uint32_t getRefKind() const
Definition: MCValue.h:53
Target - Wrapper for Target specific information.
MCObjectWriter * createELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new ELF writer instance.
static bool isNotChecked(VariantKind Kind)
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
static VariantKind getSymbolLoc(VariantKind Kind)
VariantKind getKind() const
Definition: MCExpr.h:330
A two-byte fixup.
Definition: MCFixup.h:25