blob: 6f825a3d0a60fd687d25821245cea5d62621d0f3 [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"
Zachary Turner264b5d92017-06-07 03:48:56 +000012#include "llvm/BinaryFormat/ELF.h"
Alex Bradbury866113c2017-04-05 10:16:14 +000013#include "llvm/MC/MCContext.h"
Rafael Espindolaa0124052011-12-22 00:37:50 +000014#include "llvm/MC/MCELFObjectWriter.h"
15#include "llvm/MC/MCExpr.h"
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000016#include "llvm/MC/MCFixup.h"
Rafael Espindolaa0124052011-12-22 00:37:50 +000017#include "llvm/MC/MCValue.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
Rafael Espindolaa0124052011-12-22 00:37:50 +000081 if (IsPCRel) {
82 switch ((unsigned)Fixup.getKind()) {
Tim Northover42335572015-04-06 18:44:42 +000083 default:
Alex Bradbury866113c2017-04-05 10:16:14 +000084 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
Tim Northover42335572015-04-06 18:44:42 +000085 return ELF::R_ARM_NONE;
Rafael Espindolaa0124052011-12-22 00:37:50 +000086 case FK_Data_4:
87 switch (Modifier) {
Rafael Espindolae06e4df2017-07-26 17:27:27 +000088 default:
89 llvm_unreachable("Unsupported Modifier");
Rafael Espindolaa0124052011-12-22 00:37:50 +000090 case MCSymbolRefExpr::VK_None:
Rafael Espindolae06e4df2017-07-26 17:27:27 +000091 return ELF::R_ARM_REL32;
David Peixotto8ad70b32013-12-04 22:43:20 +000092 case MCSymbolRefExpr::VK_GOTTPOFF:
Rafael Espindolae06e4df2017-07-26 17:27:27 +000093 return ELF::R_ARM_TLS_IE32;
Peter Collingbourne97aae402015-10-26 18:23:16 +000094 case MCSymbolRefExpr::VK_ARM_GOT_PREL:
Rafael Espindolae06e4df2017-07-26 17:27:27 +000095 return ELF::R_ARM_GOT_PREL;
Peter Collingbourneaba16fc2016-03-10 19:30:18 +000096 case MCSymbolRefExpr::VK_ARM_PREL31:
Rafael Espindolae06e4df2017-07-26 17:27:27 +000097 return ELF::R_ARM_PREL31;
Rafael Espindolaa0124052011-12-22 00:37:50 +000098 }
Jim Grosbach7b811d32012-02-27 21:36:23 +000099 case ARM::fixup_arm_blx:
Jan Wen Voung7f5d79f2012-06-19 16:03:02 +0000100 case ARM::fixup_arm_uncondbl:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000101 switch (Modifier) {
David Peixotto8ad70b32013-12-04 22:43:20 +0000102 case MCSymbolRefExpr::VK_PLT:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000103 return ELF::R_ARM_CALL;
Davide Italiano249c45d2016-03-15 00:25:22 +0000104 case MCSymbolRefExpr::VK_TLSCALL:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000105 return ELF::R_ARM_TLS_CALL;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000106 default:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000107 return ELF::R_ARM_CALL;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000108 }
James Molloyfb5cd602012-03-30 09:15:32 +0000109 case ARM::fixup_arm_condbl:
Rafael Espindolaa0124052011-12-22 00:37:50 +0000110 case ARM::fixup_arm_condbranch:
Jan Wen Voung7f5d79f2012-06-19 16:03:02 +0000111 case ARM::fixup_arm_uncondbranch:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000112 return ELF::R_ARM_JUMP24;
Logan Chiencea03542012-09-01 15:06:36 +0000113 case ARM::fixup_t2_condbranch:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000114 return ELF::R_ARM_THM_JUMP19;
Logan Chiencea03542012-09-01 15:06:36 +0000115 case ARM::fixup_t2_uncondbranch:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000116 return ELF::R_ARM_THM_JUMP24;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000117 case ARM::fixup_arm_movt_hi16:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000118 return ELF::R_ARM_MOVT_PREL;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000119 case ARM::fixup_arm_movw_lo16:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000120 return ELF::R_ARM_MOVW_PREL_NC;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000121 case ARM::fixup_t2_movt_hi16:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000122 return ELF::R_ARM_THM_MOVT_PREL;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000123 case ARM::fixup_t2_movw_lo16:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000124 return ELF::R_ARM_THM_MOVW_PREL_NC;
James Molloy728cf852016-09-05 08:29:15 +0000125 case ARM::fixup_arm_thumb_br:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000126 return ELF::R_ARM_THM_JUMP11;
James Molloy728cf852016-09-05 08:29:15 +0000127 case ARM::fixup_arm_thumb_bcc:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000128 return ELF::R_ARM_THM_JUMP8;
Rafael Espindolaa0124052011-12-22 00:37:50 +0000129 case ARM::fixup_arm_thumb_bl:
130 case ARM::fixup_arm_thumb_blx:
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000131 switch (Modifier) {
Davide Italiano249c45d2016-03-15 00:25:22 +0000132 case MCSymbolRefExpr::VK_TLSCALL:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000133 return ELF::R_ARM_THM_TLS_CALL;
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000134 default:
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000135 return ELF::R_ARM_THM_CALL;
Saleem Abdulrasool6e00ca82014-01-30 04:02:31 +0000136 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000137 }
138 }
Rafael Espindolae06e4df2017-07-26 17:27:27 +0000139 switch ((unsigned)Fixup.getKind()) {
140 default:
141 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
142 return ELF::R_ARM_NONE;
143 case FK_Data_1:
144 switch (Modifier) {
145 default:
146 llvm_unreachable("unsupported Modifier");
147 case MCSymbolRefExpr::VK_None:
148 return ELF::R_ARM_ABS8;
149 }
150 case FK_Data_2:
151 switch (Modifier) {
152 default:
153 llvm_unreachable("unsupported modifier");
154 case MCSymbolRefExpr::VK_None:
155 return ELF::R_ARM_ABS16;
156 }
157 case FK_Data_4:
158 switch (Modifier) {
159 default:
160 llvm_unreachable("Unsupported Modifier");
161 case MCSymbolRefExpr::VK_ARM_NONE:
162 return ELF::R_ARM_NONE;
163 case MCSymbolRefExpr::VK_GOT:
164 return ELF::R_ARM_GOT_BREL;
165 case MCSymbolRefExpr::VK_TLSGD:
166 return ELF::R_ARM_TLS_GD32;
167 case MCSymbolRefExpr::VK_TPOFF:
168 return ELF::R_ARM_TLS_LE32;
169 case MCSymbolRefExpr::VK_GOTTPOFF:
170 return ELF::R_ARM_TLS_IE32;
171 case MCSymbolRefExpr::VK_None:
172 return ELF::R_ARM_ABS32;
173 case MCSymbolRefExpr::VK_GOTOFF:
174 return ELF::R_ARM_GOTOFF32;
175 case MCSymbolRefExpr::VK_ARM_GOT_PREL:
176 return ELF::R_ARM_GOT_PREL;
177 case MCSymbolRefExpr::VK_ARM_TARGET1:
178 return ELF::R_ARM_TARGET1;
179 case MCSymbolRefExpr::VK_ARM_TARGET2:
180 return ELF::R_ARM_TARGET2;
181 case MCSymbolRefExpr::VK_ARM_PREL31:
182 return ELF::R_ARM_PREL31;
183 case MCSymbolRefExpr::VK_ARM_SBREL:
184 return ELF::R_ARM_SBREL32;
185 case MCSymbolRefExpr::VK_ARM_TLSLDO:
186 return ELF::R_ARM_TLS_LDO32;
187 case MCSymbolRefExpr::VK_TLSCALL:
188 return ELF::R_ARM_TLS_CALL;
189 case MCSymbolRefExpr::VK_TLSDESC:
190 return ELF::R_ARM_TLS_GOTDESC;
191 case MCSymbolRefExpr::VK_TLSLDM:
192 return ELF::R_ARM_TLS_LDM32;
193 case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
194 return ELF::R_ARM_TLS_DESCSEQ;
195 }
196 case ARM::fixup_arm_condbranch:
197 case ARM::fixup_arm_uncondbranch:
198 return ELF::R_ARM_JUMP24;
199 case ARM::fixup_arm_movt_hi16:
200 switch (Modifier) {
201 default:
202 llvm_unreachable("Unsupported Modifier");
203 case MCSymbolRefExpr::VK_None:
204 return ELF::R_ARM_MOVT_ABS;
205 case MCSymbolRefExpr::VK_ARM_SBREL:
206 return ELF::R_ARM_MOVT_BREL;
207 }
208 case ARM::fixup_arm_movw_lo16:
209 switch (Modifier) {
210 default:
211 llvm_unreachable("Unsupported Modifier");
212 case MCSymbolRefExpr::VK_None:
213 return ELF::R_ARM_MOVW_ABS_NC;
214 case MCSymbolRefExpr::VK_ARM_SBREL:
215 return ELF::R_ARM_MOVW_BREL_NC;
216 }
217 case ARM::fixup_t2_movt_hi16:
218 switch (Modifier) {
219 default:
220 llvm_unreachable("Unsupported Modifier");
221 case MCSymbolRefExpr::VK_None:
222 return ELF::R_ARM_THM_MOVT_ABS;
223 case MCSymbolRefExpr::VK_ARM_SBREL:
224 return ELF::R_ARM_THM_MOVT_BREL;
225 }
226 case ARM::fixup_t2_movw_lo16:
227 switch (Modifier) {
228 default:
229 llvm_unreachable("Unsupported Modifier");
230 case MCSymbolRefExpr::VK_None:
231 return ELF::R_ARM_THM_MOVW_ABS_NC;
232 case MCSymbolRefExpr::VK_ARM_SBREL:
233 return ELF::R_ARM_THM_MOVW_BREL_NC;
234 }
235 }
Rafael Espindolaa0124052011-12-22 00:37:50 +0000236}
237
Rafael Espindola5560a4c2015-04-14 22:14:34 +0000238MCObjectWriter *llvm::createARMELFObjectWriter(raw_pwrite_stream &OS,
Christian Pirker2a111602014-03-28 14:35:30 +0000239 uint8_t OSABI,
240 bool IsLittleEndian) {
Lang Hamesdcb312b2017-10-09 23:53:15 +0000241 return createELFObjectWriter(llvm::make_unique<ARMELFObjectWriter>(OSABI), OS,
242 IsLittleEndian);
Rafael Espindolaa0124052011-12-22 00:37:50 +0000243}