LLVM 22.0.0git
SystemZELFObjectWriter.cpp
Go to the documentation of this file.
1//===-- SystemZELFObjectWriter.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
13#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCFixup.h"
18#include "llvm/MC/MCValue.h"
20#include <cassert>
21#include <cstdint>
22#include <memory>
23
24using namespace llvm;
25
26namespace {
27
28class SystemZELFObjectWriter : public MCELFObjectTargetWriter {
29public:
30 SystemZELFObjectWriter(uint8_t OSABI);
31 ~SystemZELFObjectWriter() override = default;
32
33protected:
34 // Override MCELFObjectTargetWriter.
35 unsigned getRelocType(const MCFixup &, const MCValue &,
36 bool IsPCRel) const override;
37 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;
38 unsigned getAbsoluteReloc(SMLoc Loc, unsigned Kind) const;
39 unsigned getPCRelReloc(SMLoc Loc, unsigned Kind) const;
40};
41
42} // end anonymous namespace
43
44SystemZELFObjectWriter::SystemZELFObjectWriter(uint8_t OSABI)
45 : MCELFObjectTargetWriter(/*Is64Bit_=*/true, OSABI, ELF::EM_S390,
46 /*HasRelocationAddend_=*/true) {}
47
48// Return the relocation type for an absolute value of MCFixupKind Kind.
49unsigned SystemZELFObjectWriter::getAbsoluteReloc(SMLoc Loc,
50 unsigned Kind) const {
51 switch (Kind) {
52 case FK_Data_1:
55 return ELF::R_390_8;
57 return ELF::R_390_12;
58 case FK_Data_2:
61 return ELF::R_390_16;
63 return ELF::R_390_20;
64 case FK_Data_4:
67 return ELF::R_390_32;
68 case FK_Data_8:
69 return ELF::R_390_64;
70 }
71 reportError(Loc, "Unsupported absolute address");
72 return 0;
73}
74
75// Return the relocation type for a PC-relative value of MCFixupKind Kind.
76unsigned SystemZELFObjectWriter::getPCRelReloc(SMLoc Loc, unsigned Kind) const {
77 switch (Kind) {
78 case FK_Data_2:
81 return ELF::R_390_PC16;
82 case FK_Data_4:
85 return ELF::R_390_PC32;
86 case FK_Data_8:
87 return ELF::R_390_PC64;
89 return ELF::R_390_PC12DBL;
91 return ELF::R_390_PC16DBL;
93 return ELF::R_390_PC24DBL;
95 return ELF::R_390_PC32DBL;
96 }
97 reportError(Loc, "Unsupported PC-relative address");
98 return 0;
99}
100
101unsigned SystemZELFObjectWriter::getRelocType(const MCFixup &Fixup,
102 const MCValue &Target,
103 bool IsPCRel) const {
104 SMLoc Loc = Fixup.getLoc();
105 unsigned Kind = Fixup.getKind();
106 auto Specifier = SystemZ::Specifier(Target.getSpecifier());
107 switch (Specifier) {
110 case SystemZ::S_TLSGD:
111 case SystemZ::S_TLSLD:
114 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))
115 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);
116 break;
117 default:
118 break;
119 }
120
121 switch (Specifier) {
122 case SystemZ::S_None:
123 if (IsPCRel)
124 return getPCRelReloc(Loc, Kind);
125 return getAbsoluteReloc(Loc, Kind);
126
128 assert(!IsPCRel && "NTPOFF shouldn't be PC-relative");
129 switch (Kind) {
130 case FK_Data_4:
131 return ELF::R_390_TLS_LE32;
132 case FK_Data_8:
133 return ELF::R_390_TLS_LE64;
134 }
135 reportError(Loc, "Unsupported thread-local address (local-exec)");
136 return 0;
137
139 if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)
140 return ELF::R_390_TLS_IEENT;
141 reportError(Loc,
142 "Only PC-relative INDNTPOFF accesses are supported for now");
143 return 0;
144
146 assert(!IsPCRel && "DTPOFF shouldn't be PC-relative");
147 switch (Kind) {
148 case FK_Data_4:
149 return ELF::R_390_TLS_LDO32;
150 case FK_Data_8:
151 return ELF::R_390_TLS_LDO64;
152 }
153 reportError(Loc, "Unsupported thread-local address (local-dynamic)");
154 return 0;
155
157 assert(!IsPCRel && "TLSLDM shouldn't be PC-relative");
158 switch (Kind) {
159 case FK_Data_4:
160 return ELF::R_390_TLS_LDM32;
161 case FK_Data_8:
162 return ELF::R_390_TLS_LDM64;
164 return ELF::R_390_TLS_LDCALL;
165 }
166 reportError(Loc, "Unsupported thread-local address (local-dynamic)");
167 return 0;
168
169 case SystemZ::S_TLSGD:
170 assert(!IsPCRel && "TLSGD shouldn't be PC-relative");
171 switch (Kind) {
172 case FK_Data_4:
173 return ELF::R_390_TLS_GD32;
174 case FK_Data_8:
175 return ELF::R_390_TLS_GD64;
177 return ELF::R_390_TLS_GDCALL;
178 }
179 reportError(Loc, "Unsupported thread-local address (general-dynamic)");
180 return 0;
181
182 case SystemZ::S_GOT:
184 if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)
185 return ELF::R_390_GOTENT;
186 reportError(Loc, "Only PC-relative GOT accesses are supported for now");
187 return 0;
188
189 case SystemZ::S_PLT:
190 assert(IsPCRel && "@PLT shouldn't be PC-relative");
191 switch (Kind) {
193 return ELF::R_390_PLT12DBL;
195 return ELF::R_390_PLT16DBL;
197 return ELF::R_390_PLT24DBL;
199 return ELF::R_390_PLT32DBL;
200 }
201 reportError(Loc, "Unsupported PC-relative PLT address");
202 return 0;
203
204 default:
205 llvm_unreachable("Modifier not supported");
206 }
207}
208
209bool SystemZELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,
210 unsigned Type) const {
211 switch (V.getSpecifier()) {
212 case SystemZ::S_GOT:
213 case SystemZ::S_PLT:
214 return true;
215 default:
216 return false;
217 }
218}
219
220std::unique_ptr<MCObjectTargetWriter>
222 return std::make_unique<SystemZELFObjectWriter>(OSABI);
223}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Error reportError(StringRef Message)
PowerPC TLS Dynamic Call Fixup
Represents a location in source code.
Definition SMLoc.h:23
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ EM_S390
Definition ELF.h:155
@ STT_TLS
Definition ELF.h:1414
This is an optimization pass for GlobalISel generic memory operations.
@ 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_Data_2
A two-byte fixup.
Definition MCFixup.h:35
std::unique_ptr< MCObjectTargetWriter > createSystemZELFObjectWriter(uint8_t OSABI)