blob: e1fa2457182024b4c50d2b38856c72dedd6e05e3 [file] [log] [blame]
Rafael Espindola4449b212011-12-22 01:06:53 +00001//===-- ARMELFObjectWriter.cpp - ARM ELF Writer ---------------------------===//
Rafael Espindolaa0124052011-12-22 00:37:50 +00002//
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
Chandler Carruthed0881b2012-12-03 16:50:05 +000010#include "MCTargetDesc/ARMFixupKinds.h"
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000011#include "MCTargetDesc/ARMMCTargetDesc.h"
Alex Bradbury866113c2017-04-05 10:16:14 +000012#include "llvm/MC/MCContext.h"
Rafael Espindolaa0124052011-12-22 00:37:50 +000013#include "llvm/MC/MCELFObjectWriter.h"
14#include "llvm/MC/MCExpr.h"
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000015#include "llvm/MC/MCFixup.h"
Rafael Espindolaa0124052011-12-22 00:37:50 +000016#include "llvm/MC/MCValue.h"
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000017#include "llvm/Support/ELF.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000018#include "llvm/Support/ErrorHandling.h"
19#include "llvm/Support/raw_ostream.h"
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000020#include <cstdint>
Rafael Espindolaa0124052011-12-22 00:37:50 +000021
22using namespace llvm;
23
24namespace {
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000025
Rafael Espindolaa0124052011-12-22 00:37:50 +000026 class ARMELFObjectWriter : public MCELFObjectTargetWriter {
27 enum { DefaultEABIVersion = 0x05000000U };
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000028
Alex Bradbury866113c2017-04-05 10:16:14 +000029 unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
30 bool IsPCRel, MCContext &Ctx) const;
Rafael Espindolaa0124052011-12-22 00:37:50 +000031
Rafael Espindolaa0124052011-12-22 00:37:50 +000032 public:
33 ARMELFObjectWriter(uint8_t OSABI);
34
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000035 ~ARMELFObjectWriter() override = default;
Rafael Espindola84d00f12011-12-22 02:58:12 +000036
Rafael Espindola8340f942016-01-13 22:56:57 +000037 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
38 const MCFixup &Fixup, bool IsPCRel) const override;
Rafael Espindola5904e122014-03-29 06:26:49 +000039
Rafael Espindolaece40ca2015-05-29 18:26:09 +000040 bool needsRelocateWithSymbol(const MCSymbol &Sym,
Ulrich Weigand46797c62014-07-20 23:15:06 +000041 unsigned Type) const override;
Rafael Espindolaa0124052011-12-22 00:37:50 +000042 };
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000043
44} // end anonymous namespace
Rafael Espindolaa0124052011-12-22 00:37:50 +000045
46ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
47 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
48 ELF::EM_ARM,
49 /*HasRelocationAddend*/ false) {}
50
Rafael Espindolaece40ca2015-05-29 18:26:09 +000051bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
Ulrich Weigand46797c62014-07-20 23:15:06 +000052 unsigned Type) const {
Kumar Sukhanifb60e772014-12-11 08:33:36 +000053 // FIXME: This is extremely conservative. This really needs to use a
Rafael Espindola5904e122014-03-29 06:26:49 +000054 // whitelist with a clear explanation for why each realocation needs to
55 // point to the symbol, not to the section.
56 switch (Type) {
57 default:
58 return true;
Rafael Espindolaa0124052011-12-22 00:37:50 +000059
Rafael Espindola5904e122014-03-29 06:26:49 +000060 case ELF::R_ARM_PREL31:
61 case ELF::R_ARM_ABS32:
62 return false;
Rafael Espindolaa0124052011-12-22 00:37:50 +000063 }
Rafael Espindolaa0124052011-12-22 00:37:50 +000064}
65
66// Need to examine the Fixup when determining whether to
67// emit the relocation as an explicit symbol or as a section relative
68// offset
Rafael Espindola8340f942016-01-13 22:56:57 +000069unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
Rafael Espindolaa0124052011-12-22 00:37:50 +000070 const MCFixup &Fixup,
Rafael Espindolac03f44c2014-03-27 20:49:35 +000071 bool IsPCRel) const {
Alex Bradbury866113c2017-04-05 10:16:14 +000072 return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
Rafael Espindolaa0124052011-12-22 00:37:50 +000073}
74
75unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
76 const MCFixup &Fixup,
Alex Bradbury866113c2017-04-05 10:16:14 +000077 bool IsPCRel,
78 MCContext &Ctx) const {
Rafael Espindola3d082fa2014-05-03 19:57:04 +000079 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
Rafael Espindolaa0124052011-12-22 00:37:50 +000080
81 unsigned Type = 0;
82 if (IsPCRel) {
83 switch ((unsigned)Fixup.getKind()) {
Tim Northover42335572015-04-06 18:44:42 +000084 default:
Alex Bradbury866113c2017-04-05 10:16:14 +000085 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
Tim Northover42335572015-04-06 18:44:42 +000086 return ELF::R_ARM_NONE;
Rafael Espindolaa0124052011-12-22 00:37:50 +000087 case FK_Data_4:
88 switch (Modifier) {
89 default: llvm_unreachable("Unsupported Modifier");
90 case MCSymbolRefExpr::VK_None:
91 Type = ELF::R_ARM_REL32;
92 break;
David Peixotto8ad70b32013-12-04 22:43:20 +000093 case MCSymbolRefExpr::VK_TLSGD:
Craig Toppere55c5562012-02-07 02:50:20 +000094 llvm_unreachable("unimplemented");
David Peixotto8ad70b32013-12-04 22:43:20 +000095 case MCSymbolRefExpr::VK_GOTTPOFF:
Rafael Espindolaa0124052011-12-22 00:37:50 +000096 Type = ELF::R_ARM_TLS_IE32;
97 break;
Peter Collingbourne97aae402015-10-26 18:23:16 +000098 case MCSymbolRefExpr::VK_ARM_GOT_PREL:
Joerg Sonnenbergerdd18d5b2014-04-29 13:42:02 +000099 Type = ELF::R_ARM_GOT_PREL;
100 break;
Peter Collingbourneaba16fc2016-03-10 19:30:18 +0000101 case MCSymbolRefExpr::VK_ARM_PREL31:
102 Type = ELF::R_ARM_PREL31;
103 break;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000104 }
105 break;
Jim Grosbach7b811d32012-02-27 21:36:23 +0000106 case ARM::fixup_arm_blx:
Jan Wen Voung7f5d79f2012-06-19 16:03:02 +0000107 case ARM::fixup_arm_uncondbl:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000108 switch (Modifier) {
David Peixotto8ad70b32013-12-04 22:43:20 +0000109 case MCSymbolRefExpr::VK_PLT:
Jyoti Allur5b9f3522014-11-20 05:58:11 +0000110 Type = ELF::R_ARM_CALL;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000111 break;
Davide Italiano249c45d2016-03-15 00:25:22 +0000112 case MCSymbolRefExpr::VK_TLSCALL:
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000113 Type = ELF::R_ARM_TLS_CALL;
114 break;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000115 default:
116 Type = ELF::R_ARM_CALL;
117 break;
118 }
119 break;
James Molloyfb5cd602012-03-30 09:15:32 +0000120 case ARM::fixup_arm_condbl:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000121 case ARM::fixup_arm_condbranch:
Jan Wen Voung7f5d79f2012-06-19 16:03:02 +0000122 case ARM::fixup_arm_uncondbranch:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000123 Type = ELF::R_ARM_JUMP24;
124 break;
Logan Chiencea03542012-09-01 15:06:36 +0000125 case ARM::fixup_t2_condbranch:
Peter Smith353a2282016-06-07 10:34:33 +0000126 Type = ELF::R_ARM_THM_JUMP19;
127 break;
Logan Chiencea03542012-09-01 15:06:36 +0000128 case ARM::fixup_t2_uncondbranch:
129 Type = ELF::R_ARM_THM_JUMP24;
130 break;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000131 case ARM::fixup_arm_movt_hi16:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000132 Type = ELF::R_ARM_MOVT_PREL;
133 break;
134 case ARM::fixup_arm_movw_lo16:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000135 Type = ELF::R_ARM_MOVW_PREL_NC;
136 break;
137 case ARM::fixup_t2_movt_hi16:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000138 Type = ELF::R_ARM_THM_MOVT_PREL;
139 break;
140 case ARM::fixup_t2_movw_lo16:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000141 Type = ELF::R_ARM_THM_MOVW_PREL_NC;
142 break;
James Molloy728cf852016-09-05 08:29:15 +0000143 case ARM::fixup_arm_thumb_br:
144 Type = ELF::R_ARM_THM_JUMP11;
145 break;
146 case ARM::fixup_arm_thumb_bcc:
147 Type = ELF::R_ARM_THM_JUMP8;
148 break;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000149 case ARM::fixup_arm_thumb_bl:
150 case ARM::fixup_arm_thumb_blx:
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000151 switch (Modifier) {
Davide Italiano249c45d2016-03-15 00:25:22 +0000152 case MCSymbolRefExpr::VK_TLSCALL:
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000153 Type = ELF::R_ARM_THM_TLS_CALL;
154 break;
155 default:
156 Type = ELF::R_ARM_THM_CALL;
157 break;
158 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000159 break;
160 }
161 } else {
162 switch ((unsigned)Fixup.getKind()) {
Tim Northover42335572015-04-06 18:44:42 +0000163 default:
Alex Bradbury866113c2017-04-05 10:16:14 +0000164 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
Tim Northover42335572015-04-06 18:44:42 +0000165 return ELF::R_ARM_NONE;
Saleem Abdulrasool3c0f78a2015-01-09 05:59:12 +0000166 case FK_Data_1:
167 switch (Modifier) {
168 default: llvm_unreachable("unsupported Modifier");
169 case MCSymbolRefExpr::VK_None:
170 Type = ELF::R_ARM_ABS8;
171 break;
172 }
173 break;
Saleem Abdulrasoolb68fa3b2015-01-09 06:57:24 +0000174 case FK_Data_2:
175 switch (Modifier) {
176 default: llvm_unreachable("unsupported modifier");
177 case MCSymbolRefExpr::VK_None:
178 Type = ELF::R_ARM_ABS16;
179 break;
180 }
181 break;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000182 case FK_Data_4:
183 switch (Modifier) {
David Blaikie46a9f012012-01-20 21:51:11 +0000184 default: llvm_unreachable("Unsupported Modifier");
Logan Chien4dd14fb2012-12-12 07:14:46 +0000185 case MCSymbolRefExpr::VK_ARM_NONE:
186 Type = ELF::R_ARM_NONE;
187 break;
David Peixotto8ad70b32013-12-04 22:43:20 +0000188 case MCSymbolRefExpr::VK_GOT:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000189 Type = ELF::R_ARM_GOT_BREL;
190 break;
David Peixotto8ad70b32013-12-04 22:43:20 +0000191 case MCSymbolRefExpr::VK_TLSGD:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000192 Type = ELF::R_ARM_TLS_GD32;
193 break;
David Peixotto8ad70b32013-12-04 22:43:20 +0000194 case MCSymbolRefExpr::VK_TPOFF:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000195 Type = ELF::R_ARM_TLS_LE32;
196 break;
David Peixotto8ad70b32013-12-04 22:43:20 +0000197 case MCSymbolRefExpr::VK_GOTTPOFF:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000198 Type = ELF::R_ARM_TLS_IE32;
199 break;
200 case MCSymbolRefExpr::VK_None:
201 Type = ELF::R_ARM_ABS32;
202 break;
David Peixotto8ad70b32013-12-04 22:43:20 +0000203 case MCSymbolRefExpr::VK_GOTOFF:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000204 Type = ELF::R_ARM_GOTOFF32;
205 break;
Peter Collingbourne97aae402015-10-26 18:23:16 +0000206 case MCSymbolRefExpr::VK_ARM_GOT_PREL:
Joerg Sonnenbergerdd18d5b2014-04-29 13:42:02 +0000207 Type = ELF::R_ARM_GOT_PREL;
208 break;
James Molloy6685c082012-01-26 09:25:43 +0000209 case MCSymbolRefExpr::VK_ARM_TARGET1:
210 Type = ELF::R_ARM_TARGET1;
211 break;
Anton Korobeynikova305ea52012-11-09 20:20:12 +0000212 case MCSymbolRefExpr::VK_ARM_TARGET2:
213 Type = ELF::R_ARM_TARGET2;
214 break;
Logan Chien4dd14fb2012-12-12 07:14:46 +0000215 case MCSymbolRefExpr::VK_ARM_PREL31:
216 Type = ELF::R_ARM_PREL31;
217 break;
Saleem Abdulrasoolfe781972015-01-11 04:39:18 +0000218 case MCSymbolRefExpr::VK_ARM_SBREL:
219 Type = ELF::R_ARM_SBREL32;
220 break;
Kai Nackee51c8132014-01-20 11:00:40 +0000221 case MCSymbolRefExpr::VK_ARM_TLSLDO:
222 Type = ELF::R_ARM_TLS_LDO32;
223 break;
Davide Italiano249c45d2016-03-15 00:25:22 +0000224 case MCSymbolRefExpr::VK_TLSCALL:
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000225 Type = ELF::R_ARM_TLS_CALL;
226 break;
Davide Italianodfdf2782016-03-15 17:29:52 +0000227 case MCSymbolRefExpr::VK_TLSDESC:
Saleem Abdulrasoola3f12bd2014-01-30 04:02:38 +0000228 Type = ELF::R_ARM_TLS_GOTDESC;
229 break;
Peter Smithcbcecca2016-07-19 14:15:33 +0000230 case MCSymbolRefExpr::VK_TLSLDM:
231 Type = ELF::R_ARM_TLS_LDM32;
232 break;
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +0000233 case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
234 Type = ELF::R_ARM_TLS_DESCSEQ;
235 break;
Logan Chien4dd14fb2012-12-12 07:14:46 +0000236 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000237 break;
238 case ARM::fixup_arm_ldst_pcrel_12:
239 case ARM::fixup_arm_pcrel_10:
240 case ARM::fixup_arm_adr_pcrel_12:
241 case ARM::fixup_arm_thumb_bl:
242 case ARM::fixup_arm_thumb_cb:
243 case ARM::fixup_arm_thumb_cp:
244 case ARM::fixup_arm_thumb_br:
Craig Toppere55c5562012-02-07 02:50:20 +0000245 llvm_unreachable("Unimplemented");
Rafael Espindolaa0124052011-12-22 00:37:50 +0000246 case ARM::fixup_arm_condbranch:
Jan Wen Voung7f5d79f2012-06-19 16:03:02 +0000247 case ARM::fixup_arm_uncondbranch:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000248 Type = ELF::R_ARM_JUMP24;
249 break;
250 case ARM::fixup_arm_movt_hi16:
Oliver Stannard8331aae2016-08-08 15:28:31 +0000251 switch (Modifier) {
252 default: llvm_unreachable("Unsupported Modifier");
253 case MCSymbolRefExpr::VK_None:
254 Type = ELF::R_ARM_MOVT_ABS;
255 break;
256 case MCSymbolRefExpr::VK_ARM_SBREL:
257 Type = ELF:: R_ARM_MOVT_BREL;
258 break;
259 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000260 break;
261 case ARM::fixup_arm_movw_lo16:
Oliver Stannard8331aae2016-08-08 15:28:31 +0000262 switch (Modifier) {
263 default: llvm_unreachable("Unsupported Modifier");
264 case MCSymbolRefExpr::VK_None:
265 Type = ELF::R_ARM_MOVW_ABS_NC;
266 break;
267 case MCSymbolRefExpr::VK_ARM_SBREL:
268 Type = ELF:: R_ARM_MOVW_BREL_NC;
269 break;
270 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000271 break;
272 case ARM::fixup_t2_movt_hi16:
Christof Doumad3ed8382017-02-07 13:07:12 +0000273 switch (Modifier) {
274 default: llvm_unreachable("Unsupported Modifier");
275 case MCSymbolRefExpr::VK_None:
276 Type = ELF::R_ARM_THM_MOVT_ABS;
277 break;
278 case MCSymbolRefExpr::VK_ARM_SBREL:
279 Type = ELF:: R_ARM_THM_MOVT_BREL;
280 break;
281 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000282 break;
283 case ARM::fixup_t2_movw_lo16:
Christof Doumad3ed8382017-02-07 13:07:12 +0000284 switch (Modifier) {
285 default: llvm_unreachable("Unsupported Modifier");
286 case MCSymbolRefExpr::VK_None:
287 Type = ELF::R_ARM_THM_MOVW_ABS_NC;
288 break;
289 case MCSymbolRefExpr::VK_ARM_SBREL:
290 Type = ELF:: R_ARM_THM_MOVW_BREL_NC;
291 break;
292 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000293 break;
294 }
295 }
296
297 return Type;
298}
299
Rafael Espindola5560a4c2015-04-14 22:14:34 +0000300MCObjectWriter *llvm::createARMELFObjectWriter(raw_pwrite_stream &OS,
Christian Pirker2a111602014-03-28 14:35:30 +0000301 uint8_t OSABI,
302 bool IsLittleEndian) {
Rafael Espindolaa0124052011-12-22 00:37:50 +0000303 MCELFObjectTargetWriter *MOTW = new ARMELFObjectWriter(OSABI);
Christian Pirker2a111602014-03-28 14:35:30 +0000304 return createELFObjectWriter(MOTW, OS, IsLittleEndian);
Rafael Espindolaa0124052011-12-22 00:37:50 +0000305}