[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / ARM / MCTargetDesc / ARMELFObjectWriter.cpp
blob37d81e4b0af13dd0c450849d2a24ab33a5b0c6d1
1 //===-- ARMELFObjectWriter.cpp - ARM 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 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/ARMFixupKinds.h"
10 #include "MCTargetDesc/ARMMCTargetDesc.h"
11 #include "llvm/BinaryFormat/ELF.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCELFObjectWriter.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCFixup.h"
16 #include "llvm/MC/MCObjectFileInfo.h"
17 #include "llvm/MC/MCObjectWriter.h"
18 #include "llvm/MC/MCValue.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <cstdint>
23 using namespace llvm;
25 namespace {
27 class ARMELFObjectWriter : public MCELFObjectTargetWriter {
28 enum { DefaultEABIVersion = 0x05000000U };
30 unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
31 bool IsPCRel, MCContext &Ctx) const;
33 public:
34 ARMELFObjectWriter(uint8_t OSABI);
36 ~ARMELFObjectWriter() override = default;
38 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
39 const MCFixup &Fixup, bool IsPCRel) const override;
41 bool needsRelocateWithSymbol(const MCSymbol &Sym,
42 unsigned Type) const override;
44 void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
47 } // end anonymous namespace
49 ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
50 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
51 ELF::EM_ARM,
52 /*HasRelocationAddend*/ false) {}
54 bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
55 unsigned Type) const {
56 // FIXME: This is extremely conservative. This really needs to use an
57 // explicit list with a clear explanation for why each realocation needs to
58 // point to the symbol, not to the section.
59 switch (Type) {
60 default:
61 return true;
63 case ELF::R_ARM_PREL31:
64 case ELF::R_ARM_ABS32:
65 return false;
69 // Need to examine the Fixup when determining whether to
70 // emit the relocation as an explicit symbol or as a section relative
71 // offset
72 unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
73 const MCFixup &Fixup,
74 bool IsPCRel) const {
75 return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
78 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
79 const MCFixup &Fixup,
80 bool IsPCRel,
81 MCContext &Ctx) const {
82 unsigned Kind = Fixup.getTargetKind();
83 if (Kind >= FirstLiteralRelocationKind)
84 return Kind - FirstLiteralRelocationKind;
85 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
87 if (IsPCRel) {
88 switch (Fixup.getTargetKind()) {
89 default:
90 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
91 return ELF::R_ARM_NONE;
92 case FK_Data_4:
93 switch (Modifier) {
94 default:
95 Ctx.reportError(Fixup.getLoc(),
96 "invalid fixup for 4-byte pc-relative data relocation");
97 return ELF::R_ARM_NONE;
98 case MCSymbolRefExpr::VK_None: {
99 if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
100 // For GNU AS compatibility expressions such as
101 // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
102 if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
103 return ELF::R_ARM_BASE_PREL;
105 return ELF::R_ARM_REL32;
107 case MCSymbolRefExpr::VK_GOTTPOFF:
108 return ELF::R_ARM_TLS_IE32;
109 case MCSymbolRefExpr::VK_ARM_GOT_PREL:
110 return ELF::R_ARM_GOT_PREL;
111 case MCSymbolRefExpr::VK_ARM_PREL31:
112 return ELF::R_ARM_PREL31;
114 case ARM::fixup_arm_blx:
115 case ARM::fixup_arm_uncondbl:
116 switch (Modifier) {
117 case MCSymbolRefExpr::VK_PLT:
118 return ELF::R_ARM_CALL;
119 case MCSymbolRefExpr::VK_TLSCALL:
120 return ELF::R_ARM_TLS_CALL;
121 default:
122 return ELF::R_ARM_CALL;
124 case ARM::fixup_arm_condbl:
125 case ARM::fixup_arm_condbranch:
126 case ARM::fixup_arm_uncondbranch:
127 return ELF::R_ARM_JUMP24;
128 case ARM::fixup_t2_condbranch:
129 return ELF::R_ARM_THM_JUMP19;
130 case ARM::fixup_t2_uncondbranch:
131 return ELF::R_ARM_THM_JUMP24;
132 case ARM::fixup_arm_movt_hi16:
133 return ELF::R_ARM_MOVT_PREL;
134 case ARM::fixup_arm_movw_lo16:
135 return ELF::R_ARM_MOVW_PREL_NC;
136 case ARM::fixup_t2_movt_hi16:
137 return ELF::R_ARM_THM_MOVT_PREL;
138 case ARM::fixup_t2_movw_lo16:
139 return ELF::R_ARM_THM_MOVW_PREL_NC;
140 case ARM::fixup_arm_thumb_br:
141 return ELF::R_ARM_THM_JUMP11;
142 case ARM::fixup_arm_thumb_bcc:
143 return ELF::R_ARM_THM_JUMP8;
144 case ARM::fixup_arm_thumb_bl:
145 case ARM::fixup_arm_thumb_blx:
146 switch (Modifier) {
147 case MCSymbolRefExpr::VK_TLSCALL:
148 return ELF::R_ARM_THM_TLS_CALL;
149 default:
150 return ELF::R_ARM_THM_CALL;
152 case ARM::fixup_bf_target:
153 return ELF::R_ARM_THM_BF16;
154 case ARM::fixup_bfc_target:
155 return ELF::R_ARM_THM_BF12;
156 case ARM::fixup_bfl_target:
157 return ELF::R_ARM_THM_BF18;
160 switch (Kind) {
161 default:
162 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
163 return ELF::R_ARM_NONE;
164 case FK_Data_1:
165 switch (Modifier) {
166 default:
167 Ctx.reportError(Fixup.getLoc(),
168 "invalid fixup for 1-byte data relocation");
169 return ELF::R_ARM_NONE;
170 case MCSymbolRefExpr::VK_None:
171 return ELF::R_ARM_ABS8;
173 case FK_Data_2:
174 switch (Modifier) {
175 default:
176 Ctx.reportError(Fixup.getLoc(),
177 "invalid fixup for 2-byte data relocation");
178 return ELF::R_ARM_NONE;
179 case MCSymbolRefExpr::VK_None:
180 return ELF::R_ARM_ABS16;
182 case FK_Data_4:
183 switch (Modifier) {
184 default:
185 Ctx.reportError(Fixup.getLoc(),
186 "invalid fixup for 4-byte data relocation");
187 return ELF::R_ARM_NONE;
188 case MCSymbolRefExpr::VK_ARM_NONE:
189 return ELF::R_ARM_NONE;
190 case MCSymbolRefExpr::VK_GOT:
191 return ELF::R_ARM_GOT_BREL;
192 case MCSymbolRefExpr::VK_TLSGD:
193 return ELF::R_ARM_TLS_GD32;
194 case MCSymbolRefExpr::VK_TPOFF:
195 return ELF::R_ARM_TLS_LE32;
196 case MCSymbolRefExpr::VK_GOTTPOFF:
197 return ELF::R_ARM_TLS_IE32;
198 case MCSymbolRefExpr::VK_None:
199 return ELF::R_ARM_ABS32;
200 case MCSymbolRefExpr::VK_GOTOFF:
201 return ELF::R_ARM_GOTOFF32;
202 case MCSymbolRefExpr::VK_ARM_GOT_PREL:
203 return ELF::R_ARM_GOT_PREL;
204 case MCSymbolRefExpr::VK_ARM_TARGET1:
205 return ELF::R_ARM_TARGET1;
206 case MCSymbolRefExpr::VK_ARM_TARGET2:
207 return ELF::R_ARM_TARGET2;
208 case MCSymbolRefExpr::VK_ARM_PREL31:
209 return ELF::R_ARM_PREL31;
210 case MCSymbolRefExpr::VK_ARM_SBREL:
211 return ELF::R_ARM_SBREL32;
212 case MCSymbolRefExpr::VK_ARM_TLSLDO:
213 return ELF::R_ARM_TLS_LDO32;
214 case MCSymbolRefExpr::VK_TLSCALL:
215 return ELF::R_ARM_TLS_CALL;
216 case MCSymbolRefExpr::VK_TLSDESC:
217 return ELF::R_ARM_TLS_GOTDESC;
218 case MCSymbolRefExpr::VK_TLSLDM:
219 return ELF::R_ARM_TLS_LDM32;
220 case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
221 return ELF::R_ARM_TLS_DESCSEQ;
223 case ARM::fixup_arm_condbranch:
224 case ARM::fixup_arm_uncondbranch:
225 return ELF::R_ARM_JUMP24;
226 case ARM::fixup_arm_movt_hi16:
227 switch (Modifier) {
228 default:
229 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction");
230 return ELF::R_ARM_NONE;
231 case MCSymbolRefExpr::VK_None:
232 return ELF::R_ARM_MOVT_ABS;
233 case MCSymbolRefExpr::VK_ARM_SBREL:
234 return ELF::R_ARM_MOVT_BREL;
236 case ARM::fixup_arm_movw_lo16:
237 switch (Modifier) {
238 default:
239 Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction");
240 return ELF::R_ARM_NONE;
241 case MCSymbolRefExpr::VK_None:
242 return ELF::R_ARM_MOVW_ABS_NC;
243 case MCSymbolRefExpr::VK_ARM_SBREL:
244 return ELF::R_ARM_MOVW_BREL_NC;
246 case ARM::fixup_t2_movt_hi16:
247 switch (Modifier) {
248 default:
249 Ctx.reportError(Fixup.getLoc(),
250 "invalid fixup for Thumb MOVT instruction");
251 return ELF::R_ARM_NONE;
252 case MCSymbolRefExpr::VK_None:
253 return ELF::R_ARM_THM_MOVT_ABS;
254 case MCSymbolRefExpr::VK_ARM_SBREL:
255 return ELF::R_ARM_THM_MOVT_BREL;
257 case ARM::fixup_t2_movw_lo16:
258 switch (Modifier) {
259 default:
260 Ctx.reportError(Fixup.getLoc(),
261 "invalid fixup for Thumb MOVW instruction");
262 return ELF::R_ARM_NONE;
263 case MCSymbolRefExpr::VK_None:
264 return ELF::R_ARM_THM_MOVW_ABS_NC;
265 case MCSymbolRefExpr::VK_ARM_SBREL:
266 return ELF::R_ARM_THM_MOVW_BREL_NC;
271 void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
272 MCSectionELF &Sec) {
273 // The mix of execute-only and non-execute-only at link time is
274 // non-execute-only. To avoid the empty implicitly created .text
275 // section from making the whole .text section non-execute-only, we
276 // mark it execute-only if it is empty and there is at least one
277 // execute-only section in the object.
278 MCSectionELF *TextSection =
279 static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
280 if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions()) {
281 for (auto &F : TextSection->getFragmentList())
282 if (auto *DF = dyn_cast<MCDataFragment>(&F))
283 if (!DF->getContents().empty())
284 return;
285 TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
289 std::unique_ptr<MCObjectTargetWriter>
290 llvm::createARMELFObjectWriter(uint8_t OSABI) {
291 return std::make_unique<ARMELFObjectWriter>(OSABI);