LLVM 18.0.0git
SystemZMCObjectWriter.cpp
Go to the documentation of this file.
1//===-- SystemZMCObjectWriter.cpp - SystemZ 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"
15#include "llvm/MC/MCFixup.h"
17#include "llvm/MC/MCValue.h"
19#include <cassert>
20#include <cstdint>
21
22using namespace llvm;
23
24namespace {
25
26class SystemZObjectWriter : public MCELFObjectTargetWriter {
27public:
28 SystemZObjectWriter(uint8_t OSABI);
29 ~SystemZObjectWriter() override = default;
30
31protected:
32 // Override MCELFObjectTargetWriter.
33 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
34 const MCFixup &Fixup, bool IsPCRel) const override;
35};
36
37} // end anonymous namespace
38
39SystemZObjectWriter::SystemZObjectWriter(uint8_t OSABI)
40 : MCELFObjectTargetWriter(/*Is64Bit_=*/true, OSABI, ELF::EM_S390,
41 /*HasRelocationAddend_=*/ true) {}
42
43// Return the relocation type for an absolute value of MCFixupKind Kind.
44static unsigned getAbsoluteReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind) {
45 switch (Kind) {
46 case FK_Data_1:
49 return ELF::R_390_8;
51 return ELF::R_390_12;
52 case FK_Data_2:
55 return ELF::R_390_16;
57 return ELF::R_390_20;
58 case FK_Data_4:
61 return ELF::R_390_32;
62 case FK_Data_8:
63 return ELF::R_390_64;
64 }
65 Ctx.reportError(Loc, "Unsupported absolute address");
66 return 0;
67}
68
69// Return the relocation type for a PC-relative value of MCFixupKind Kind.
70static unsigned getPCRelReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind) {
71 switch (Kind) {
72 case FK_Data_2:
75 return ELF::R_390_PC16;
76 case FK_Data_4:
79 return ELF::R_390_PC32;
80 case FK_Data_8:
81 return ELF::R_390_PC64;
83 return ELF::R_390_PC12DBL;
85 return ELF::R_390_PC16DBL;
87 return ELF::R_390_PC24DBL;
89 return ELF::R_390_PC32DBL;
90 }
91 Ctx.reportError(Loc, "Unsupported PC-relative address");
92 return 0;
93}
94
95// Return the R_390_TLS_LE* relocation type for MCFixupKind Kind.
96static unsigned getTLSLEReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind) {
97 switch (Kind) {
98 case FK_Data_4: return ELF::R_390_TLS_LE32;
99 case FK_Data_8: return ELF::R_390_TLS_LE64;
100 }
101 Ctx.reportError(Loc, "Unsupported thread-local address (local-exec)");
102 return 0;
103}
104
105// Return the R_390_TLS_LDO* relocation type for MCFixupKind Kind.
106static unsigned getTLSLDOReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind) {
107 switch (Kind) {
108 case FK_Data_4: return ELF::R_390_TLS_LDO32;
109 case FK_Data_8: return ELF::R_390_TLS_LDO64;
110 }
111 Ctx.reportError(Loc, "Unsupported thread-local address (local-dynamic)");
112 return 0;
113}
114
115// Return the R_390_TLS_LDM* relocation type for MCFixupKind Kind.
116static unsigned getTLSLDMReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind) {
117 switch (Kind) {
118 case FK_Data_4: return ELF::R_390_TLS_LDM32;
119 case FK_Data_8: return ELF::R_390_TLS_LDM64;
120 case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_LDCALL;
121 }
122 Ctx.reportError(Loc, "Unsupported thread-local address (local-dynamic)");
123 return 0;
124}
125
126// Return the R_390_TLS_GD* relocation type for MCFixupKind Kind.
127static unsigned getTLSGDReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind) {
128 switch (Kind) {
129 case FK_Data_4: return ELF::R_390_TLS_GD32;
130 case FK_Data_8: return ELF::R_390_TLS_GD64;
131 case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_GDCALL;
132 }
133 Ctx.reportError(Loc, "Unsupported thread-local address (general-dynamic)");
134 return 0;
135}
136
137// Return the PLT relocation counterpart of MCFixupKind Kind.
138static unsigned getPLTReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind) {
139 switch (Kind) {
140 case SystemZ::FK_390_PC12DBL: return ELF::R_390_PLT12DBL;
141 case SystemZ::FK_390_PC16DBL: return ELF::R_390_PLT16DBL;
142 case SystemZ::FK_390_PC24DBL: return ELF::R_390_PLT24DBL;
143 case SystemZ::FK_390_PC32DBL: return ELF::R_390_PLT32DBL;
144 }
145 Ctx.reportError(Loc, "Unsupported PC-relative PLT address");
146 return 0;
147}
148
149unsigned SystemZObjectWriter::getRelocType(MCContext &Ctx,
150 const MCValue &Target,
151 const MCFixup &Fixup,
152 bool IsPCRel) const {
153 SMLoc Loc = Fixup.getLoc();
154 unsigned Kind = Fixup.getKind();
155 if (Kind >= FirstLiteralRelocationKind)
157 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
158 switch (Modifier) {
160 if (IsPCRel)
161 return getPCRelReloc(Ctx, Loc, Kind);
162 return getAbsoluteReloc(Ctx, Loc, Kind);
163
165 assert(!IsPCRel && "NTPOFF shouldn't be PC-relative");
166 return getTLSLEReloc(Ctx, Loc, Kind);
167
169 if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)
170 return ELF::R_390_TLS_IEENT;
171 Ctx.reportError(Loc, "Only PC-relative INDNTPOFF accesses are supported for now");
172 return 0;
173
175 assert(!IsPCRel && "DTPOFF shouldn't be PC-relative");
176 return getTLSLDOReloc(Ctx, Loc, Kind);
177
179 assert(!IsPCRel && "TLSLDM shouldn't be PC-relative");
180 return getTLSLDMReloc(Ctx, Loc, Kind);
181
183 assert(!IsPCRel && "TLSGD shouldn't be PC-relative");
184 return getTLSGDReloc(Ctx, Loc, Kind);
185
187 if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)
188 return ELF::R_390_GOTENT;
189 Ctx.reportError(Loc, "Only PC-relative GOT accesses are supported for now");
190 return 0;
191
193 assert(IsPCRel && "@PLT shouldn't be PC-relative");
194 return getPLTReloc(Ctx, Loc, Kind);
195
196 default:
197 llvm_unreachable("Modifier not supported");
198 }
199}
200
201std::unique_ptr<MCObjectTargetWriter>
203 return std::make_unique<SystemZObjectWriter>(OSABI);
204}
basic Basic Alias true
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static unsigned getPLTReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind)
static unsigned getTLSGDReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind)
static unsigned getPCRelReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind)
static unsigned getTLSLDOReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind)
static unsigned getTLSLDMReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind)
static unsigned getAbsoluteReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind)
static unsigned getTLSLEReloc(MCContext &Ctx, SMLoc Loc, unsigned Kind)
Context object for machine code objects.
Definition: MCContext.h:76
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1059
virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const =0
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:70
This represents an "assembler immediate".
Definition: MCValue.h:36
Represents a location in source code.
Definition: SMLoc.h:23
Target - Wrapper for Target specific information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ EM_S390
Definition: ELF.h:150
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::unique_ptr< MCObjectTargetWriter > createSystemZObjectWriter(uint8_t OSABI)
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:49
@ FK_Data_8
A eight-byte fixup.
Definition: MCFixup.h:26
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:24