LLVM  8.0.0svn
PPCELFObjectWriter.cpp
Go to the documentation of this file.
1 //===-- PPCELFObjectWriter.cpp - PPC 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 
11 #include "MCTargetDesc/PPCMCExpr.h"
13 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCObjectWriter.h"
17 #include "llvm/MC/MCSymbolELF.h"
18 #include "llvm/MC/MCValue.h"
20 
21 using namespace llvm;
22 
23 namespace {
24  class PPCELFObjectWriter : public MCELFObjectTargetWriter {
25  public:
26  PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
27 
28  protected:
29  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
30  const MCFixup &Fixup, bool IsPCRel) const override;
31 
32  bool needsRelocateWithSymbol(const MCSymbol &Sym,
33  unsigned Type) const override;
34  };
35 }
36 
37 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
38  : MCELFObjectTargetWriter(Is64Bit, OSABI,
39  Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC,
40  /*HasRelocationAddend*/ true) {}
41 
43  const MCFixup &Fixup) {
44  const MCExpr *Expr = Fixup.getValue();
45 
46  if (Expr->getKind() != MCExpr::Target)
47  return Target.getAccessVariant();
48 
49  switch (cast<PPCMCExpr>(Expr)->getKind()) {
70  }
71  llvm_unreachable("unknown PPCMCExpr kind");
72 }
73 
75  const MCFixup &Fixup,
76  bool IsPCRel) const {
77  MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
78 
79  // determine the type of the relocation
80  unsigned Type;
81  if (IsPCRel) {
82  switch ((unsigned)Fixup.getKind()) {
83  default:
84  llvm_unreachable("Unimplemented");
87  switch (Modifier) {
88  default: llvm_unreachable("Unsupported Modifier");
90  Type = ELF::R_PPC_REL24;
91  break;
93  Type = ELF::R_PPC_PLTREL24;
94  break;
96  Type = ELF::R_PPC_LOCAL24PC;
97  break;
98  }
99  break;
102  Type = ELF::R_PPC_REL14;
103  break;
105  switch (Modifier) {
106  default: llvm_unreachable("Unsupported Modifier");
108  Type = ELF::R_PPC_REL16;
109  break;
111  Type = ELF::R_PPC_REL16_LO;
112  break;
114  Type = ELF::R_PPC_REL16_HI;
115  break;
117  Type = ELF::R_PPC_REL16_HA;
118  break;
119  }
120  break;
122  Target.print(errs());
123  errs() << '\n';
124  report_fatal_error("Invalid PC-relative half16ds relocation");
125  case FK_Data_4:
126  case FK_PCRel_4:
127  Type = ELF::R_PPC_REL32;
128  break;
129  case FK_Data_8:
130  case FK_PCRel_8:
131  Type = ELF::R_PPC64_REL64;
132  break;
133  }
134  } else {
135  switch ((unsigned)Fixup.getKind()) {
136  default: llvm_unreachable("invalid fixup kind!");
138  Type = ELF::R_PPC_ADDR24;
139  break;
141  Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
142  break;
144  switch (Modifier) {
145  default: llvm_unreachable("Unsupported Modifier");
147  Type = ELF::R_PPC_ADDR16;
148  break;
150  Type = ELF::R_PPC_ADDR16_LO;
151  break;
153  Type = ELF::R_PPC_ADDR16_HI;
154  break;
156  Type = ELF::R_PPC_ADDR16_HA;
157  break;
159  Type = ELF::R_PPC64_ADDR16_HIGH;
160  break;
162  Type = ELF::R_PPC64_ADDR16_HIGHA;
163  break;
165  Type = ELF::R_PPC64_ADDR16_HIGHER;
166  break;
168  Type = ELF::R_PPC64_ADDR16_HIGHERA;
169  break;
171  Type = ELF::R_PPC64_ADDR16_HIGHEST;
172  break;
174  Type = ELF::R_PPC64_ADDR16_HIGHESTA;
175  break;
177  Type = ELF::R_PPC_GOT16;
178  break;
180  Type = ELF::R_PPC_GOT16_LO;
181  break;
183  Type = ELF::R_PPC_GOT16_HI;
184  break;
186  Type = ELF::R_PPC_GOT16_HA;
187  break;
189  Type = ELF::R_PPC64_TOC16;
190  break;
192  Type = ELF::R_PPC64_TOC16_LO;
193  break;
195  Type = ELF::R_PPC64_TOC16_HI;
196  break;
198  Type = ELF::R_PPC64_TOC16_HA;
199  break;
201  Type = ELF::R_PPC_TPREL16;
202  break;
204  Type = ELF::R_PPC_TPREL16_LO;
205  break;
207  Type = ELF::R_PPC_TPREL16_HI;
208  break;
210  Type = ELF::R_PPC_TPREL16_HA;
211  break;
213  Type = ELF::R_PPC64_TPREL16_HIGH;
214  break;
216  Type = ELF::R_PPC64_TPREL16_HIGHA;
217  break;
219  Type = ELF::R_PPC64_TPREL16_HIGHER;
220  break;
222  Type = ELF::R_PPC64_TPREL16_HIGHERA;
223  break;
225  Type = ELF::R_PPC64_TPREL16_HIGHEST;
226  break;
228  Type = ELF::R_PPC64_TPREL16_HIGHESTA;
229  break;
231  Type = ELF::R_PPC64_DTPREL16;
232  break;
234  Type = ELF::R_PPC64_DTPREL16_LO;
235  break;
237  Type = ELF::R_PPC64_DTPREL16_HI;
238  break;
240  Type = ELF::R_PPC64_DTPREL16_HA;
241  break;
243  Type = ELF::R_PPC64_DTPREL16_HIGH;
244  break;
246  Type = ELF::R_PPC64_DTPREL16_HIGHA;
247  break;
249  Type = ELF::R_PPC64_DTPREL16_HIGHER;
250  break;
252  Type = ELF::R_PPC64_DTPREL16_HIGHERA;
253  break;
255  Type = ELF::R_PPC64_DTPREL16_HIGHEST;
256  break;
258  Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
259  break;
261  if (is64Bit())
262  Type = ELF::R_PPC64_GOT_TLSGD16;
263  else
264  Type = ELF::R_PPC_GOT_TLSGD16;
265  break;
267  Type = ELF::R_PPC64_GOT_TLSGD16_LO;
268  break;
270  Type = ELF::R_PPC64_GOT_TLSGD16_HI;
271  break;
273  Type = ELF::R_PPC64_GOT_TLSGD16_HA;
274  break;
276  if (is64Bit())
277  Type = ELF::R_PPC64_GOT_TLSLD16;
278  else
279  Type = ELF::R_PPC_GOT_TLSLD16;
280  break;
282  Type = ELF::R_PPC64_GOT_TLSLD16_LO;
283  break;
285  Type = ELF::R_PPC64_GOT_TLSLD16_HI;
286  break;
288  Type = ELF::R_PPC64_GOT_TLSLD16_HA;
289  break;
291  /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
292  are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */
293  Type = ELF::R_PPC64_GOT_TPREL16_DS;
294  break;
296  /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
297  are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */
298  Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
299  break;
301  Type = ELF::R_PPC64_GOT_TPREL16_HI;
302  break;
304  /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
305  are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */
306  Type = ELF::R_PPC64_GOT_DTPREL16_DS;
307  break;
309  /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
310  are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */
311  Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
312  break;
314  Type = ELF::R_PPC64_GOT_TPREL16_HA;
315  break;
317  Type = ELF::R_PPC64_GOT_DTPREL16_HI;
318  break;
320  Type = ELF::R_PPC64_GOT_DTPREL16_HA;
321  break;
322  }
323  break;
325  switch (Modifier) {
326  default: llvm_unreachable("Unsupported Modifier");
328  Type = ELF::R_PPC64_ADDR16_DS;
329  break;
331  Type = ELF::R_PPC64_ADDR16_LO_DS;
332  break;
334  Type = ELF::R_PPC64_GOT16_DS;
335  break;
337  Type = ELF::R_PPC64_GOT16_LO_DS;
338  break;
340  Type = ELF::R_PPC64_TOC16_DS;
341  break;
343  Type = ELF::R_PPC64_TOC16_LO_DS;
344  break;
346  Type = ELF::R_PPC64_TPREL16_DS;
347  break;
349  Type = ELF::R_PPC64_TPREL16_LO_DS;
350  break;
352  Type = ELF::R_PPC64_DTPREL16_DS;
353  break;
355  Type = ELF::R_PPC64_DTPREL16_LO_DS;
356  break;
358  Type = ELF::R_PPC64_GOT_TPREL16_DS;
359  break;
361  Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
362  break;
364  Type = ELF::R_PPC64_GOT_DTPREL16_DS;
365  break;
367  Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
368  break;
369  }
370  break;
372  switch (Modifier) {
373  default: llvm_unreachable("Unsupported Modifier");
375  if (is64Bit())
376  Type = ELF::R_PPC64_TLSGD;
377  else
378  Type = ELF::R_PPC_TLSGD;
379  break;
381  if (is64Bit())
382  Type = ELF::R_PPC64_TLSLD;
383  else
384  Type = ELF::R_PPC_TLSLD;
385  break;
387  if (is64Bit())
388  Type = ELF::R_PPC64_TLS;
389  else
390  Type = ELF::R_PPC_TLS;
391  break;
392  }
393  break;
394  case FK_Data_8:
395  switch (Modifier) {
396  default: llvm_unreachable("Unsupported Modifier");
398  Type = ELF::R_PPC64_TOC;
399  break;
401  Type = ELF::R_PPC64_ADDR64;
402  break;
404  Type = ELF::R_PPC64_DTPMOD64;
405  break;
407  Type = ELF::R_PPC64_TPREL64;
408  break;
410  Type = ELF::R_PPC64_DTPREL64;
411  break;
412  }
413  break;
414  case FK_Data_4:
415  Type = ELF::R_PPC_ADDR32;
416  break;
417  case FK_Data_2:
418  Type = ELF::R_PPC_ADDR16;
419  break;
420  }
421  }
422  return Type;
423 }
424 
425 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
426  unsigned Type) const {
427  switch (Type) {
428  default:
429  return false;
430 
431  case ELF::R_PPC_REL24:
432  // If the target symbol has a local entry point, we must keep the
433  // target symbol to preserve that information for the linker.
434  // The "other" values are stored in the last 6 bits of the second byte.
435  // The traditional defines for STO values assume the full byte and thus
436  // the shift to pack it.
437  unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
438  return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
439  }
440 }
441 
442 std::unique_ptr<MCObjectTargetWriter>
443 llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
444  return llvm::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
445 }
A eight-byte pc relative fixup.
Definition: MCFixup.h:31
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
This represents an "assembler immediate".
Definition: MCValue.h:40
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
14-bit absolute relocation for conditional branches.
Definition: PPCFixupKinds.h:30
block Block Frequency true
MCSymbolRefExpr::VariantKind getAccessVariant() const
Definition: MCValue.cpp:47
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:74
A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like &#39;li&#39; or &#39;addis&#39;.
Definition: PPCFixupKinds.h:34
24-bit absolute relocation for direct branches like &#39;ba&#39; and &#39;bla&#39;.
Definition: PPCFixupKinds.h:27
std::unique_ptr< MCObjectTargetWriter > createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
Construct an PPC ELF object writer.
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
Not a true fixup, but ties a symbol to a call to __tls_get_addr for the TLS general and local dynamic...
Definition: PPCFixupKinds.h:43
static unsigned getRelocType(const MCValue &Target, const MCFixupKind FixupKind, const bool IsPCRel)
Translates generic PPC fixup kind to Mach-O/PPC relocation type enum.
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:773
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:63
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static bool is64Bit(const char *name)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
PowerPC TLS Dynamic Call Fixup
void print(raw_ostream &OS) const
Print the value to the stream OS.
Definition: MCValue.cpp:19
A four-byte pc relative fixup.
Definition: MCFixup.h:30
ExprKind getKind() const
Definition: MCExpr.h:73
Target - Wrapper for Target specific information.
A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for instrs like &#39;std&#39;...
Definition: PPCFixupKinds.h:38
static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, const MCFixup &Fixup)
A eight-byte fixup.
Definition: MCFixup.h:27
const MCExpr * getValue() const
Definition: MCFixup.h:128
Target specific expression.
Definition: MCExpr.h:43
14-bit PC relative relocation for conditional branches.
Definition: PPCFixupKinds.h:24
A two-byte fixup.
Definition: MCFixup.h:25
MCFixupKind getKind() const
Definition: MCFixup.h:123