LLVM 24.0.0git
SparcELFObjectWriter.cpp
Go to the documentation of this file.
1//===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCValue.h"
19
20using namespace llvm;
21
22namespace {
23 class SparcELFObjectWriter : public MCELFObjectTargetWriter {
24 public:
25 SparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI)
26 : MCELFObjectTargetWriter(
27 Is64Bit, OSABI,
28 Is64Bit ? ELF::EM_SPARCV9
29 : (IsV8Plus ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC),
30 /*HasRelocationAddend*/ true) {}
31
32 ~SparcELFObjectWriter() override = default;
33
34 protected:
35 unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target,
36 bool IsPCRel) const override;
37
38 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;
39 };
40}
41
42unsigned SparcELFObjectWriter::getRelocType(const MCFixup &Fixup,
43 const MCValue &Target,
44 bool IsPCRel) const {
45 auto Kind = Fixup.getKind();
46 auto Spec = Target.getSpecifier();
47 switch (Spec) {
48 case ELF::R_SPARC_TLS_GD_HI22:
49 case ELF::R_SPARC_TLS_GD_LO10:
50 case ELF::R_SPARC_TLS_GD_ADD:
51 case ELF::R_SPARC_TLS_LDM_HI22:
52 case ELF::R_SPARC_TLS_LDM_LO10:
53 case ELF::R_SPARC_TLS_LDM_ADD:
54 case ELF::R_SPARC_TLS_LDO_HIX22:
55 case ELF::R_SPARC_TLS_LDO_LOX10:
56 case ELF::R_SPARC_TLS_LDO_ADD:
57 case ELF::R_SPARC_TLS_IE_HI22:
58 case ELF::R_SPARC_TLS_IE_LO10:
59 case ELF::R_SPARC_TLS_IE_LD:
60 case ELF::R_SPARC_TLS_IE_LDX:
61 case ELF::R_SPARC_TLS_IE_ADD:
62 case ELF::R_SPARC_TLS_LE_HIX22:
63 case ELF::R_SPARC_TLS_LE_LOX10:
64 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))
65 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);
66 break;
67 case ELF::R_SPARC_DISP32:
68 if (Kind == FK_Data_4)
69 return ELF::R_SPARC_DISP32;
70 reportError(Fixup.getLoc(), "%" + Sparc::getSpecifierName(Spec) +
71 " can only be used in a .word directive");
72 return ELF::R_SPARC_NONE;
73 default:
74 break;
75 }
76
77 // Extract the relocation type from the fixup kind, after applying STT_TLS as
78 // needed.
79 if (mc::isRelocation(Fixup.getKind()))
80 return Kind;
81
82 if (IsPCRel) {
83 switch (Kind) {
84 default:
85 llvm_unreachable("Unimplemented fixup -> relocation");
86 case FK_Data_1: return ELF::R_SPARC_DISP8;
87 case FK_Data_2: return ELF::R_SPARC_DISP16;
88 case FK_Data_4: return ELF::R_SPARC_DISP32;
89 case FK_Data_8: return ELF::R_SPARC_DISP64;
91 if (getContext().getObjectFileInfo()->isPositionIndependent())
92 return ELF::R_SPARC_WPLT30;
93 return ELF::R_SPARC_WDISP30;
94 }
95 }
96
97 // clang-format off
98 switch(Fixup.getKind()) {
99 default:
100 llvm_unreachable("Unimplemented fixup -> relocation");
101 case FK_NONE: return ELF::R_SPARC_NONE;
102 case FK_Data_1: return ELF::R_SPARC_8;
103 case FK_Data_2: return ((Fixup.getOffset() % 2)
104 ? ELF::R_SPARC_UA16
105 : ELF::R_SPARC_16);
106 case FK_Data_4: return ((Fixup.getOffset() % 4)
107 ? ELF::R_SPARC_UA32
108 : ELF::R_SPARC_32);
109 case FK_Data_8: return ((Fixup.getOffset() % 8)
110 ? ELF::R_SPARC_UA64
111 : ELF::R_SPARC_64);
113 if (getContext().getObjectFileInfo()->isPositionIndependent())
114 return ELF::R_SPARC_GOT13;
115 return ELF::R_SPARC_13;
116 }
117 // clang-format on
118
119 return ELF::R_SPARC_NONE;
120}
121
122bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
123 unsigned Type) const {
124 switch (Type) {
125 default:
126 return false;
127
128 // All relocations that use a GOT need a symbol, not an offset, as
129 // the offset of the symbol within the section is irrelevant to
130 // where the GOT entry is. Don't need to list all the TLS entries,
131 // as they're all marked as requiring a symbol anyways.
132 case ELF::R_SPARC_GOT10:
133 case ELF::R_SPARC_GOT13:
134 case ELF::R_SPARC_GOT22:
135 case ELF::R_SPARC_GOTDATA_HIX22:
136 case ELF::R_SPARC_GOTDATA_LOX10:
137 case ELF::R_SPARC_GOTDATA_OP_HIX22:
138 case ELF::R_SPARC_GOTDATA_OP_LOX10:
139 return true;
140 }
141}
142
143std::unique_ptr<MCObjectTargetWriter>
144llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI) {
145 return std::make_unique<SparcELFObjectWriter>(Is64Bit, IsV8Plus, OSABI);
146}
basic Basic Alias true
static Error reportError(StringRef Message)
PowerPC TLS Dynamic Call Fixup
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition MCFixup.h:61
Target - Wrapper for Target specific information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ EM_SPARC
Definition ELF.h:140
@ EM_SPARC32PLUS
Definition ELF.h:151
@ EM_SPARCV9
Definition ELF.h:164
@ STT_TLS
Definition ELF.h:1432
@ fixup_sparc_13
fixup_sparc_13 - 13-bit fixup
StringRef getSpecifierName(uint16_t S)
bool isRelocation(MCFixupKind FixupKind)
Definition MCFixup.h:130
This is an optimization pass for GlobalISel generic memory operations.
std::unique_ptr< MCObjectTargetWriter > createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI)
@ FK_Data_8
A eight-byte fixup.
Definition MCFixup.h:37
@ FK_Data_1
A one-byte fixup.
Definition MCFixup.h:34
@ FK_Data_4
A four-byte fixup.
Definition MCFixup.h:36
@ FK_NONE
A no-op fixup.
Definition MCFixup.h:33
@ FK_Data_2
A two-byte fixup.
Definition MCFixup.h:35