blob: 795c1ba6314a25c6421fa606311c6f604d687849 [file] [log] [blame]
Tim Northover5cc3dc82012-12-07 16:50:23 +00001//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
2//
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//
10// This file assembles .s files and emits ARM ELF .o object files. Different
11// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
12// delimit regions of data and code.
13//
14//===----------------------------------------------------------------------===//
15
Logan Chiend8bb4b72013-04-16 12:02:21 +000016#include "ARMRegisterInfo.h"
Logan Chiend8bb4b72013-04-16 12:02:21 +000017#include "ARMUnwindOpAsm.h"
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +000018#include "llvm/ADT/StringExtras.h"
Benjamin Kramerf242d8c2012-12-08 10:45:24 +000019#include "llvm/ADT/Twine.h"
20#include "llvm/MC/MCAsmBackend.h"
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +000021#include "llvm/MC/MCAsmInfo.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000022#include "llvm/MC/MCAssembler.h"
23#include "llvm/MC/MCCodeEmitter.h"
24#include "llvm/MC/MCContext.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000025#include "llvm/MC/MCELF.h"
26#include "llvm/MC/MCELFStreamer.h"
27#include "llvm/MC/MCELFSymbolFlags.h"
28#include "llvm/MC/MCExpr.h"
29#include "llvm/MC/MCInst.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000030#include "llvm/MC/MCInstPrinter.h"
Rafael Espindola4c6f6132014-04-27 17:10:46 +000031#include "llvm/MC/MCObjectFileInfo.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000032#include "llvm/MC/MCObjectStreamer.h"
Logan Chiend8bb4b72013-04-16 12:02:21 +000033#include "llvm/MC/MCRegisterInfo.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000034#include "llvm/MC/MCSection.h"
Benjamin Kramerf242d8c2012-12-08 10:45:24 +000035#include "llvm/MC/MCSectionELF.h"
36#include "llvm/MC/MCStreamer.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000037#include "llvm/MC/MCSymbol.h"
38#include "llvm/MC/MCValue.h"
Saleem Abdulrasool278a9f42014-01-19 08:25:27 +000039#include "llvm/Support/ARMBuildAttributes.h"
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +000040#include "llvm/Support/ARMEHABI.h"
Renato Golinf5f373f2015-05-08 21:04:27 +000041#include "llvm/Support/TargetParser.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000042#include "llvm/Support/Debug.h"
43#include "llvm/Support/ELF.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000044#include "llvm/Support/FormattedStream.h"
Logan Chien5b776b72014-02-22 14:00:39 +000045#include "llvm/Support/LEB128.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000046#include "llvm/Support/raw_ostream.h"
Logan Chien8cbb80d2013-10-28 17:51:12 +000047#include <algorithm>
Tim Northover5cc3dc82012-12-07 16:50:23 +000048
49using namespace llvm;
50
Logan Chiend8bb4b72013-04-16 12:02:21 +000051static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +000052 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
53 "Invalid personality index");
Logan Chiend8bb4b72013-04-16 12:02:21 +000054 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
55}
56
Tim Northover5cc3dc82012-12-07 16:50:23 +000057namespace {
58
Rafael Espindolaa17151a2013-10-08 13:08:17 +000059class ARMELFStreamer;
60
61class ARMTargetAsmStreamer : public ARMTargetStreamer {
62 formatted_raw_ostream &OS;
63 MCInstPrinter &InstPrinter;
Saleem Abdulrasoolf16e68a2014-01-07 02:28:50 +000064 bool IsVerboseAsm;
Rafael Espindolaa17151a2013-10-08 13:08:17 +000065
Craig Topperca7e3e52014-03-10 03:19:03 +000066 void emitFnStart() override;
67 void emitFnEnd() override;
68 void emitCantUnwind() override;
69 void emitPersonality(const MCSymbol *Personality) override;
70 void emitPersonalityIndex(unsigned Index) override;
71 void emitHandlerData() override;
72 void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
73 void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
74 void emitPad(int64_t Offset) override;
75 void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
76 bool isVector) override;
77 void emitUnwindRaw(int64_t Offset,
78 const SmallVectorImpl<uint8_t> &Opcodes) override;
Rafael Espindolaa17151a2013-10-08 13:08:17 +000079
Craig Topperca7e3e52014-03-10 03:19:03 +000080 void switchVendor(StringRef Vendor) override;
81 void emitAttribute(unsigned Attribute, unsigned Value) override;
82 void emitTextAttribute(unsigned Attribute, StringRef String) override;
83 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
84 StringRef StrinValue) override;
85 void emitArch(unsigned Arch) override;
Sumanth Gundapanenia9049ea2015-02-26 18:07:35 +000086 void emitArchExtension(unsigned ArchExt) override;
Craig Topperca7e3e52014-03-10 03:19:03 +000087 void emitObjectArch(unsigned Arch) override;
88 void emitFPU(unsigned FPU) override;
89 void emitInst(uint32_t Inst, char Suffix = '\0') override;
90 void finishAttributeSection() override;
Logan Chien8cbb80d2013-10-28 17:51:12 +000091
Craig Topperca7e3e52014-03-10 03:19:03 +000092 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
Rafael Espindola466d6632014-04-27 20:23:58 +000093 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +000094
Rafael Espindolaa17151a2013-10-08 13:08:17 +000095public:
Rafael Espindola24ea09e2014-01-26 06:06:37 +000096 ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
97 MCInstPrinter &InstPrinter, bool VerboseAsm);
Rafael Espindolaa17151a2013-10-08 13:08:17 +000098};
99
Rafael Espindola24ea09e2014-01-26 06:06:37 +0000100ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
101 formatted_raw_ostream &OS,
Saleem Abdulrasoolf16e68a2014-01-07 02:28:50 +0000102 MCInstPrinter &InstPrinter,
103 bool VerboseAsm)
Rafael Espindola24ea09e2014-01-26 06:06:37 +0000104 : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
105 IsVerboseAsm(VerboseAsm) {}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000106void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
107void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
108void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
109void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
110 OS << "\t.personality " << Personality->getName() << '\n';
111}
Saleem Abdulrasool662f5c12014-01-21 02:33:02 +0000112void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
113 OS << "\t.personalityindex " << Index << '\n';
114}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000115void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
116void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
117 int64_t Offset) {
118 OS << "\t.setfp\t";
119 InstPrinter.printRegName(OS, FpReg);
120 OS << ", ";
121 InstPrinter.printRegName(OS, SpReg);
122 if (Offset)
123 OS << ", #" << Offset;
124 OS << '\n';
125}
Saleem Abdulrasool5d962d32014-01-30 04:46:24 +0000126void ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
127 assert((Reg != ARM::SP && Reg != ARM::PC) &&
128 "the operand of .movsp cannot be either sp or pc");
129
130 OS << "\t.movsp\t";
131 InstPrinter.printRegName(OS, Reg);
132 if (Offset)
133 OS << ", #" << Offset;
134 OS << '\n';
135}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000136void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
137 OS << "\t.pad\t#" << Offset << '\n';
138}
139void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
140 bool isVector) {
141 assert(RegList.size() && "RegList should not be empty");
142 if (isVector)
143 OS << "\t.vsave\t{";
144 else
145 OS << "\t.save\t{";
146
147 InstPrinter.printRegName(OS, RegList[0]);
148
149 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
150 OS << ", ";
151 InstPrinter.printRegName(OS, RegList[i]);
152 }
153
154 OS << "}\n";
155}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000156void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {
157}
158void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
Saleem Abdulrasoolf16e68a2014-01-07 02:28:50 +0000159 OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
160 if (IsVerboseAsm) {
161 StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
162 if (!Name.empty())
163 OS << "\t@ " << Name;
164 }
165 OS << "\n";
Logan Chien8cbb80d2013-10-28 17:51:12 +0000166}
167void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
168 StringRef String) {
169 switch (Attribute) {
Logan Chien8cbb80d2013-10-28 17:51:12 +0000170 case ARMBuildAttrs::CPU_name:
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000171 OS << "\t.cpu\t" << String.lower();
172 break;
173 default:
174 OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
Saleem Abdulrasoolf16e68a2014-01-07 02:28:50 +0000175 if (IsVerboseAsm) {
176 StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
177 if (!Name.empty())
178 OS << "\t@ " << Name;
179 }
Logan Chien8cbb80d2013-10-28 17:51:12 +0000180 break;
181 }
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000182 OS << "\n";
183}
184void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
185 unsigned IntValue,
186 StringRef StringValue) {
187 switch (Attribute) {
188 default: llvm_unreachable("unsupported multi-value attribute in asm mode");
189 case ARMBuildAttrs::compatibility:
190 OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
191 if (!StringValue.empty())
192 OS << ", \"" << StringValue << "\"";
Saleem Abdulrasoolf16e68a2014-01-07 02:28:50 +0000193 if (IsVerboseAsm)
194 OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute);
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000195 break;
196 }
197 OS << "\n";
Logan Chien8cbb80d2013-10-28 17:51:12 +0000198}
Logan Chien439e8f92013-12-11 17:16:25 +0000199void ARMTargetAsmStreamer::emitArch(unsigned Arch) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000200 OS << "\t.arch\t" << ARMTargetParser::getArchName(Arch) << "\n";
Logan Chien439e8f92013-12-11 17:16:25 +0000201}
Sumanth Gundapanenia9049ea2015-02-26 18:07:35 +0000202void ARMTargetAsmStreamer::emitArchExtension(unsigned ArchExt) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000203 OS << "\t.arch_extension\t" << ARMTargetParser::getArchExtName(ArchExt) << "\n";
Sumanth Gundapanenia9049ea2015-02-26 18:07:35 +0000204}
Saleem Abdulrasool4c4789b2014-01-30 04:46:41 +0000205void ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000206 OS << "\t.object_arch\t" << ARMTargetParser::getArchName(Arch) << '\n';
Saleem Abdulrasool4c4789b2014-01-30 04:46:41 +0000207}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000208void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000209 OS << "\t.fpu\t" << ARMTargetParser::getFPUName(FPU) << "\n";
Logan Chien8cbb80d2013-10-28 17:51:12 +0000210}
211void ARMTargetAsmStreamer::finishAttributeSection() {
212}
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +0000213void
214ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
215 OS << "\t.tlsdescseq\t" << S->getSymbol().getName();
216}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000217
Rafael Espindola466d6632014-04-27 20:23:58 +0000218void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
219 OS << "\t.thumb_set\t" << *Symbol << ", " << *Value << '\n';
220}
221
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000222void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
223 OS << "\t.inst";
224 if (Suffix)
225 OS << "." << Suffix;
Benjamin Kramerbe48c402015-05-23 16:39:10 +0000226 OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000227}
228
Saleem Abdulrasoold9f08602014-01-21 02:33:10 +0000229void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
230 const SmallVectorImpl<uint8_t> &Opcodes) {
231 OS << "\t.unwind_raw " << Offset;
232 for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
233 OCE = Opcodes.end();
234 OCI != OCE; ++OCI)
Benjamin Kramerbe48c402015-05-23 16:39:10 +0000235 OS << ", 0x" << Twine::utohexstr(*OCI);
Saleem Abdulrasoold9f08602014-01-21 02:33:10 +0000236 OS << '\n';
237}
238
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000239class ARMTargetELFStreamer : public ARMTargetStreamer {
Logan Chien8cbb80d2013-10-28 17:51:12 +0000240private:
241 // This structure holds all attributes, accounting for
242 // their string/numeric value, so we can later emmit them
243 // in declaration order, keeping all in the same vector
244 struct AttributeItem {
245 enum {
246 HiddenAttribute = 0,
247 NumericAttribute,
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000248 TextAttribute,
249 NumericAndTextAttributes
Logan Chien8cbb80d2013-10-28 17:51:12 +0000250 } Type;
251 unsigned Tag;
252 unsigned IntValue;
253 StringRef StringValue;
254
255 static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
Charlie Turner8b2caa42015-01-05 13:12:17 +0000256 // The conformance tag must be emitted first when serialised
257 // into an object file. Specifically, the addenda to the ARM ABI
258 // states that (2.3.7.4):
259 //
260 // "To simplify recognition by consumers in the common case of
261 // claiming conformity for the whole file, this tag should be
262 // emitted first in a file-scope sub-subsection of the first
263 // public subsection of the attributes section."
264 //
265 // So it is special-cased in this comparison predicate when the
266 // attributes are sorted in finishAttributeSection().
267 return (RHS.Tag != ARMBuildAttrs::conformance) &&
268 ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
Logan Chien8cbb80d2013-10-28 17:51:12 +0000269 }
270 };
271
272 StringRef CurrentVendor;
273 unsigned FPU;
Logan Chien439e8f92013-12-11 17:16:25 +0000274 unsigned Arch;
Saleem Abdulrasool4c4789b2014-01-30 04:46:41 +0000275 unsigned EmittedArch;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000276 SmallVector<AttributeItem, 64> Contents;
277
Rafael Espindola0709a7b2015-05-21 19:20:38 +0000278 MCSection *AttributeSection;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000279
Logan Chien8cbb80d2013-10-28 17:51:12 +0000280 AttributeItem *getAttributeItem(unsigned Attribute) {
281 for (size_t i = 0; i < Contents.size(); ++i)
282 if (Contents[i].Tag == Attribute)
283 return &Contents[i];
Craig Topper062a2ba2014-04-25 05:30:21 +0000284 return nullptr;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000285 }
286
287 void setAttributeItem(unsigned Attribute, unsigned Value,
288 bool OverwriteExisting) {
289 // Look for existing attribute item
290 if (AttributeItem *Item = getAttributeItem(Attribute)) {
291 if (!OverwriteExisting)
292 return;
Saleem Abdulrasool93900052014-01-19 08:25:41 +0000293 Item->Type = AttributeItem::NumericAttribute;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000294 Item->IntValue = Value;
295 return;
296 }
297
298 // Create new attribute item
299 AttributeItem Item = {
300 AttributeItem::NumericAttribute,
301 Attribute,
302 Value,
303 StringRef("")
304 };
305 Contents.push_back(Item);
306 }
307
308 void setAttributeItem(unsigned Attribute, StringRef Value,
309 bool OverwriteExisting) {
310 // Look for existing attribute item
311 if (AttributeItem *Item = getAttributeItem(Attribute)) {
312 if (!OverwriteExisting)
313 return;
Saleem Abdulrasool93900052014-01-19 08:25:41 +0000314 Item->Type = AttributeItem::TextAttribute;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000315 Item->StringValue = Value;
316 return;
317 }
318
319 // Create new attribute item
320 AttributeItem Item = {
321 AttributeItem::TextAttribute,
322 Attribute,
323 0,
324 Value
325 };
326 Contents.push_back(Item);
327 }
328
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000329 void setAttributeItems(unsigned Attribute, unsigned IntValue,
330 StringRef StringValue, bool OverwriteExisting) {
331 // Look for existing attribute item
332 if (AttributeItem *Item = getAttributeItem(Attribute)) {
333 if (!OverwriteExisting)
334 return;
Saleem Abdulrasool93900052014-01-19 08:25:41 +0000335 Item->Type = AttributeItem::NumericAndTextAttributes;
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000336 Item->IntValue = IntValue;
337 Item->StringValue = StringValue;
338 return;
339 }
340
341 // Create new attribute item
342 AttributeItem Item = {
343 AttributeItem::NumericAndTextAttributes,
344 Attribute,
345 IntValue,
346 StringValue
347 };
348 Contents.push_back(Item);
349 }
350
Logan Chien439e8f92013-12-11 17:16:25 +0000351 void emitArchDefaultAttributes();
Logan Chien8cbb80d2013-10-28 17:51:12 +0000352 void emitFPUDefaultAttributes();
353
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000354 ARMELFStreamer &getStreamer();
Logan Chien8cbb80d2013-10-28 17:51:12 +0000355
Craig Topperca7e3e52014-03-10 03:19:03 +0000356 void emitFnStart() override;
357 void emitFnEnd() override;
358 void emitCantUnwind() override;
359 void emitPersonality(const MCSymbol *Personality) override;
360 void emitPersonalityIndex(unsigned Index) override;
361 void emitHandlerData() override;
362 void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
363 void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
364 void emitPad(int64_t Offset) override;
365 void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
366 bool isVector) override;
367 void emitUnwindRaw(int64_t Offset,
368 const SmallVectorImpl<uint8_t> &Opcodes) override;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000369
Craig Topperca7e3e52014-03-10 03:19:03 +0000370 void switchVendor(StringRef Vendor) override;
371 void emitAttribute(unsigned Attribute, unsigned Value) override;
372 void emitTextAttribute(unsigned Attribute, StringRef String) override;
373 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
374 StringRef StringValue) override;
375 void emitArch(unsigned Arch) override;
376 void emitObjectArch(unsigned Arch) override;
377 void emitFPU(unsigned FPU) override;
378 void emitInst(uint32_t Inst, char Suffix = '\0') override;
379 void finishAttributeSection() override;
Rafael Espindola4c6f6132014-04-27 17:10:46 +0000380 void emitLabel(MCSymbol *Symbol) override;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000381
Craig Topperca7e3e52014-03-10 03:19:03 +0000382 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
Rafael Espindola466d6632014-04-27 20:23:58 +0000383 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +0000384
Logan Chien8cbb80d2013-10-28 17:51:12 +0000385 size_t calculateContentSize() const;
386
387public:
Rafael Espindola24ea09e2014-01-26 06:06:37 +0000388 ARMTargetELFStreamer(MCStreamer &S)
Renato Golin35de35d2015-05-12 10:33:58 +0000389 : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::FK_INVALID),
390 Arch(ARM::AK_INVALID), EmittedArch(ARM::AK_INVALID),
Craig Topper062a2ba2014-04-25 05:30:21 +0000391 AttributeSection(nullptr) {}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000392};
393
Tim Northover5cc3dc82012-12-07 16:50:23 +0000394/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
395/// the appropriate points in the object files. These symbols are defined in the
396/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
397///
398/// In brief: $a, $t or $d should be emitted at the start of each contiguous
399/// region of ARM code, Thumb code or data in a section. In practice, this
400/// emission does not rely on explicit assembler directives but on inherent
401/// properties of the directives doing the emission (e.g. ".byte" is data, "add
402/// r0, r0, r0" an instruction).
403///
404/// As a result this system is orthogonal to the DataRegion infrastructure used
405/// by MachO. Beware!
406class ARMELFStreamer : public MCELFStreamer {
407public:
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000408 friend class ARMTargetELFStreamer;
409
Rafael Espindola5560a4c2015-04-14 22:14:34 +0000410 ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
Rafael Espindola24ea09e2014-01-26 06:06:37 +0000411 MCCodeEmitter *Emitter, bool IsThumb)
412 : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb),
413 MappingSymbolCounter(0), LastEMS(EMS_None) {
Logan Chiend8bb4b72013-04-16 12:02:21 +0000414 Reset();
415 }
Tim Northover5cc3dc82012-12-07 16:50:23 +0000416
417 ~ARMELFStreamer() {}
418
Craig Topperca7e3e52014-03-10 03:19:03 +0000419 void FinishImpl() override;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000420
Logan Chien2bcc42c2013-01-30 15:39:04 +0000421 // ARM exception handling directives
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000422 void emitFnStart();
423 void emitFnEnd();
424 void emitCantUnwind();
425 void emitPersonality(const MCSymbol *Per);
Saleem Abdulrasool662f5c12014-01-21 02:33:02 +0000426 void emitPersonalityIndex(unsigned index);
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000427 void emitHandlerData();
428 void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
Saleem Abdulrasool5d962d32014-01-30 04:46:24 +0000429 void emitMovSP(unsigned Reg, int64_t Offset = 0);
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000430 void emitPad(int64_t Offset);
431 void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
Saleem Abdulrasoold9f08602014-01-21 02:33:10 +0000432 void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000433
Rafael Espindola0709a7b2015-05-21 19:20:38 +0000434 void ChangeSection(MCSection *Section, const MCExpr *Subsection) override {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000435 // We have to keep track of the mapping symbol state of any sections we
436 // use. Each one should start off as EMS_None, which is provided as the
437 // default constructor by DenseMap::lookup.
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000438 LastMappingSymbols[getPreviousSection().first] = LastEMS;
Tim Northover5cc3dc82012-12-07 16:50:23 +0000439 LastEMS = LastMappingSymbols.lookup(Section);
440
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000441 MCELFStreamer::ChangeSection(Section, Subsection);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000442 }
443
444 /// This function is the one used to emit instruction data into the ELF
445 /// streamer. We override it to add the appropriate mapping symbol if
446 /// necessary.
Craig Topperca7e3e52014-03-10 03:19:03 +0000447 void EmitInstruction(const MCInst& Inst,
448 const MCSubtargetInfo &STI) override {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000449 if (IsThumb)
450 EmitThumbMappingSymbol();
451 else
452 EmitARMMappingSymbol();
453
David Woodhousee6c13e42014-01-28 23:12:42 +0000454 MCELFStreamer::EmitInstruction(Inst, STI);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000455 }
456
Craig Topperd25ff6f2014-03-10 03:22:59 +0000457 void emitInst(uint32_t Inst, char Suffix) {
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000458 unsigned Size;
459 char Buffer[4];
460 const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
461
462 switch (Suffix) {
463 case '\0':
464 Size = 4;
465
466 assert(!IsThumb);
467 EmitARMMappingSymbol();
468 for (unsigned II = 0, IE = Size; II != IE; II++) {
469 const unsigned I = LittleEndian ? (Size - II - 1) : II;
470 Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
471 }
472
473 break;
474 case 'n':
475 case 'w':
476 Size = (Suffix == 'n' ? 2 : 4);
477
478 assert(IsThumb);
479 EmitThumbMappingSymbol();
480 for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
481 const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1);
482 const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2);
483 Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
484 Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
485 }
486
487 break;
488 default:
489 llvm_unreachable("Invalid Suffix");
490 }
491
492 MCELFStreamer::EmitBytes(StringRef(Buffer, Size));
493 }
494
Tim Northover5cc3dc82012-12-07 16:50:23 +0000495 /// This is one of the functions used to emit data into an ELF section, so the
496 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
497 /// necessary.
Craig Topperca7e3e52014-03-10 03:19:03 +0000498 void EmitBytes(StringRef Data) override {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000499 EmitDataMappingSymbol();
Rafael Espindola64e1af82013-07-02 15:49:13 +0000500 MCELFStreamer::EmitBytes(Data);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000501 }
502
503 /// This is one of the functions used to emit data into an ELF section, so the
504 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
505 /// necessary.
Kevin Enderby96918bc2014-04-22 17:27:29 +0000506 void EmitValueImpl(const MCExpr *Value, unsigned Size,
507 const SMLoc &Loc) override {
Saleem Abdulrasoolfe781972015-01-11 04:39:18 +0000508 if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value))
509 if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4))
Jim Grosbach6f482002015-05-18 18:43:14 +0000510 getContext().reportFatalError(Loc, "relocated expression must be 32-bit");
Saleem Abdulrasoolfe781972015-01-11 04:39:18 +0000511
Tim Northover5cc3dc82012-12-07 16:50:23 +0000512 EmitDataMappingSymbol();
Rafael Espindola64e1af82013-07-02 15:49:13 +0000513 MCELFStreamer::EmitValueImpl(Value, Size);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000514 }
515
Craig Topperca7e3e52014-03-10 03:19:03 +0000516 void EmitAssemblerFlag(MCAssemblerFlag Flag) override {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000517 MCELFStreamer::EmitAssemblerFlag(Flag);
518
519 switch (Flag) {
520 case MCAF_SyntaxUnified:
521 return; // no-op here.
522 case MCAF_Code16:
523 IsThumb = true;
524 return; // Change to Thumb mode
525 case MCAF_Code32:
526 IsThumb = false;
527 return; // Change to ARM mode
528 case MCAF_Code64:
529 return;
530 case MCAF_SubsectionsViaSymbols:
531 return;
532 }
533 }
534
535private:
536 enum ElfMappingSymbol {
537 EMS_None,
538 EMS_ARM,
539 EMS_Thumb,
540 EMS_Data
541 };
542
543 void EmitDataMappingSymbol() {
544 if (LastEMS == EMS_Data) return;
545 EmitMappingSymbol("$d");
546 LastEMS = EMS_Data;
547 }
548
549 void EmitThumbMappingSymbol() {
550 if (LastEMS == EMS_Thumb) return;
551 EmitMappingSymbol("$t");
552 LastEMS = EMS_Thumb;
553 }
554
555 void EmitARMMappingSymbol() {
556 if (LastEMS == EMS_ARM) return;
557 EmitMappingSymbol("$a");
558 LastEMS = EMS_ARM;
559 }
560
561 void EmitMappingSymbol(StringRef Name) {
Jim Grosbach6f482002015-05-18 18:43:14 +0000562 MCSymbol *Start = getContext().createTempSymbol();
Tim Northover5cc3dc82012-12-07 16:50:23 +0000563 EmitLabel(Start);
564
Chandler Carruth1d94e932012-12-08 03:10:14 +0000565 MCSymbol *Symbol =
Jim Grosbach6f482002015-05-18 18:43:14 +0000566 getContext().getOrCreateSymbol(Name + "." +
Benjamin Kramerf242d8c2012-12-08 10:45:24 +0000567 Twine(MappingSymbolCounter++));
Tim Northover5cc3dc82012-12-07 16:50:23 +0000568
Rafael Espindolab5d316b2015-05-29 20:21:02 +0000569 getAssembler().registerSymbol(*Symbol);
Rafael Espindolae3b2acf2015-05-29 18:47:23 +0000570 MCELF::SetType(*Symbol, ELF::STT_NOTYPE);
571 MCELF::SetBinding(*Symbol, ELF::STB_LOCAL);
Rafael Espindola4d37b2a2015-05-29 21:45:01 +0000572 Symbol->setExternal(false);
Richard Mitton21101b32013-09-19 23:21:01 +0000573 AssignSection(Symbol, getCurrentSection().first);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000574
Jim Grosbach13760bd2015-05-30 01:25:56 +0000575 const MCExpr *Value = MCSymbolRefExpr::create(Start, getContext());
Tim Northover5cc3dc82012-12-07 16:50:23 +0000576 Symbol->setVariableValue(Value);
577 }
578
Craig Topperca7e3e52014-03-10 03:19:03 +0000579 void EmitThumbFunc(MCSymbol *Func) override {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000580 getAssembler().setIsThumbFunc(Func);
Rafael Espindolab60c8292014-04-29 12:46:50 +0000581 EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000582 }
583
Logan Chien2bcc42c2013-01-30 15:39:04 +0000584 // Helper functions for ARM exception handling directives
585 void Reset();
586
587 void EmitPersonalityFixup(StringRef Name);
Logan Chien325823a2013-06-09 12:22:30 +0000588 void FlushPendingOffset();
Logan Chienc931fce2013-07-02 12:43:27 +0000589 void FlushUnwindOpcodes(bool NoHandlerData);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000590
591 void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,
592 SectionKind Kind, const MCSymbol &Fn);
593 void SwitchToExTabSection(const MCSymbol &FnStart);
594 void SwitchToExIdxSection(const MCSymbol &FnStart);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000595
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +0000596 void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
597
Tim Northover5cc3dc82012-12-07 16:50:23 +0000598 bool IsThumb;
599 int64_t MappingSymbolCounter;
600
601 DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
602 ElfMappingSymbol LastEMS;
603
Logan Chien2bcc42c2013-01-30 15:39:04 +0000604 // ARM Exception Handling Frame Information
605 MCSymbol *ExTab;
606 MCSymbol *FnStart;
607 const MCSymbol *Personality;
Logan Chien325823a2013-06-09 12:22:30 +0000608 unsigned PersonalityIndex;
609 unsigned FPReg; // Frame pointer register
610 int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
611 int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
612 int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
Logan Chiend8bb4b72013-04-16 12:02:21 +0000613 bool UsedFP;
Logan Chien2bcc42c2013-01-30 15:39:04 +0000614 bool CantUnwind;
Logan Chien325823a2013-06-09 12:22:30 +0000615 SmallVector<uint8_t, 64> Opcodes;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000616 UnwindOpcodeAssembler UnwindOpAsm;
Tim Northover5cc3dc82012-12-07 16:50:23 +0000617};
Logan Chiend8bb4b72013-04-16 12:02:21 +0000618} // end anonymous namespace
Tim Northover5cc3dc82012-12-07 16:50:23 +0000619
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000620ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
Rafael Espindola24ea09e2014-01-26 06:06:37 +0000621 return static_cast<ARMELFStreamer &>(Streamer);
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000622}
623
624void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
625void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
626void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
627void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
628 getStreamer().emitPersonality(Personality);
629}
Saleem Abdulrasool662f5c12014-01-21 02:33:02 +0000630void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
631 getStreamer().emitPersonalityIndex(Index);
632}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000633void ARMTargetELFStreamer::emitHandlerData() {
634 getStreamer().emitHandlerData();
635}
636void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
637 int64_t Offset) {
638 getStreamer().emitSetFP(FpReg, SpReg, Offset);
639}
Saleem Abdulrasool5d962d32014-01-30 04:46:24 +0000640void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
641 getStreamer().emitMovSP(Reg, Offset);
642}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000643void ARMTargetELFStreamer::emitPad(int64_t Offset) {
644 getStreamer().emitPad(Offset);
645}
646void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
647 bool isVector) {
648 getStreamer().emitRegSave(RegList, isVector);
649}
Saleem Abdulrasoold9f08602014-01-21 02:33:10 +0000650void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
651 const SmallVectorImpl<uint8_t> &Opcodes) {
652 getStreamer().emitUnwindRaw(Offset, Opcodes);
653}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000654void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
655 assert(!Vendor.empty() && "Vendor cannot be empty.");
656
657 if (CurrentVendor == Vendor)
658 return;
659
660 if (!CurrentVendor.empty())
661 finishAttributeSection();
662
663 assert(Contents.empty() &&
664 ".ARM.attributes should be flushed before changing vendor");
665 CurrentVendor = Vendor;
666
667}
668void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
669 setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
670}
671void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
672 StringRef Value) {
673 setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
674}
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000675void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
676 unsigned IntValue,
677 StringRef StringValue) {
678 setAttributeItems(Attribute, IntValue, StringValue,
679 /* OverwriteExisting= */ true);
680}
Logan Chien439e8f92013-12-11 17:16:25 +0000681void ARMTargetELFStreamer::emitArch(unsigned Value) {
682 Arch = Value;
683}
Saleem Abdulrasool4c4789b2014-01-30 04:46:41 +0000684void ARMTargetELFStreamer::emitObjectArch(unsigned Value) {
685 EmittedArch = Value;
686}
Logan Chien439e8f92013-12-11 17:16:25 +0000687void ARMTargetELFStreamer::emitArchDefaultAttributes() {
688 using namespace ARMBuildAttrs;
Saleem Abdulrasool4c4789b2014-01-30 04:46:41 +0000689
Renato Golinf5f373f2015-05-08 21:04:27 +0000690 setAttributeItem(CPU_name,
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000691 ARMTargetParser::getCPUAttr(Arch),
Renato Golinf5f373f2015-05-08 21:04:27 +0000692 false);
693
Renato Golin35de35d2015-05-12 10:33:58 +0000694 if (EmittedArch == ARM::AK_INVALID)
Renato Golinf5f373f2015-05-08 21:04:27 +0000695 setAttributeItem(CPU_arch,
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000696 ARMTargetParser::getArchAttr(Arch),
Renato Golinf5f373f2015-05-08 21:04:27 +0000697 false);
Saleem Abdulrasool4c4789b2014-01-30 04:46:41 +0000698 else
Renato Golinf5f373f2015-05-08 21:04:27 +0000699 setAttributeItem(CPU_arch,
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000700 ARMTargetParser::getArchAttr(EmittedArch),
Renato Golinf5f373f2015-05-08 21:04:27 +0000701 false);
Logan Chien439e8f92013-12-11 17:16:25 +0000702
703 switch (Arch) {
Renato Golin35de35d2015-05-12 10:33:58 +0000704 case ARM::AK_ARMV2:
705 case ARM::AK_ARMV2A:
706 case ARM::AK_ARMV3:
707 case ARM::AK_ARMV3M:
708 case ARM::AK_ARMV4:
709 case ARM::AK_ARMV5:
Logan Chien439e8f92013-12-11 17:16:25 +0000710 setAttributeItem(ARM_ISA_use, Allowed, false);
711 break;
712
Renato Golin35de35d2015-05-12 10:33:58 +0000713 case ARM::AK_ARMV4T:
714 case ARM::AK_ARMV5T:
715 case ARM::AK_ARMV5TE:
716 case ARM::AK_ARMV6:
717 case ARM::AK_ARMV6J:
Logan Chien439e8f92013-12-11 17:16:25 +0000718 setAttributeItem(ARM_ISA_use, Allowed, false);
719 setAttributeItem(THUMB_ISA_use, Allowed, false);
720 break;
721
Renato Golin35de35d2015-05-12 10:33:58 +0000722 case ARM::AK_ARMV6T2:
Logan Chien439e8f92013-12-11 17:16:25 +0000723 setAttributeItem(ARM_ISA_use, Allowed, false);
724 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
725 break;
726
Renato Golin35de35d2015-05-12 10:33:58 +0000727 case ARM::AK_ARMV6K:
728 case ARM::AK_ARMV6Z:
729 case ARM::AK_ARMV6ZK:
Logan Chien439e8f92013-12-11 17:16:25 +0000730 setAttributeItem(ARM_ISA_use, Allowed, false);
731 setAttributeItem(THUMB_ISA_use, Allowed, false);
732 setAttributeItem(Virtualization_use, AllowTZ, false);
733 break;
734
Renato Golin35de35d2015-05-12 10:33:58 +0000735 case ARM::AK_ARMV6M:
Logan Chien439e8f92013-12-11 17:16:25 +0000736 setAttributeItem(THUMB_ISA_use, Allowed, false);
737 break;
738
Renato Golin35de35d2015-05-12 10:33:58 +0000739 case ARM::AK_ARMV7:
Logan Chien439e8f92013-12-11 17:16:25 +0000740 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
741 break;
742
Renato Golin35de35d2015-05-12 10:33:58 +0000743 case ARM::AK_ARMV7A:
Logan Chien439e8f92013-12-11 17:16:25 +0000744 setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
745 setAttributeItem(ARM_ISA_use, Allowed, false);
746 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
747 break;
748
Renato Golin35de35d2015-05-12 10:33:58 +0000749 case ARM::AK_ARMV7R:
Logan Chien439e8f92013-12-11 17:16:25 +0000750 setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
751 setAttributeItem(ARM_ISA_use, Allowed, false);
752 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
753 break;
754
Renato Golin35de35d2015-05-12 10:33:58 +0000755 case ARM::AK_ARMV7M:
Logan Chien439e8f92013-12-11 17:16:25 +0000756 setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
757 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
758 break;
759
Renato Golin35de35d2015-05-12 10:33:58 +0000760 case ARM::AK_ARMV8A:
761 case ARM::AK_ARMV8_1A:
Logan Chien439e8f92013-12-11 17:16:25 +0000762 setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
763 setAttributeItem(ARM_ISA_use, Allowed, false);
764 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
765 setAttributeItem(MPextension_use, Allowed, false);
766 setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
767 break;
768
Renato Golin35de35d2015-05-12 10:33:58 +0000769 case ARM::AK_IWMMXT:
Logan Chien439e8f92013-12-11 17:16:25 +0000770 setAttributeItem(ARM_ISA_use, Allowed, false);
771 setAttributeItem(THUMB_ISA_use, Allowed, false);
772 setAttributeItem(WMMX_arch, AllowWMMXv1, false);
773 break;
774
Renato Golin35de35d2015-05-12 10:33:58 +0000775 case ARM::AK_IWMMXT2:
Logan Chien439e8f92013-12-11 17:16:25 +0000776 setAttributeItem(ARM_ISA_use, Allowed, false);
777 setAttributeItem(THUMB_ISA_use, Allowed, false);
778 setAttributeItem(WMMX_arch, AllowWMMXv2, false);
779 break;
780
781 default:
782 report_fatal_error("Unknown Arch: " + Twine(Arch));
783 break;
784 }
785}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000786void ARMTargetELFStreamer::emitFPU(unsigned Value) {
787 FPU = Value;
788}
789void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
790 switch (FPU) {
Renato Golin35de35d2015-05-12 10:33:58 +0000791 case ARM::FK_VFP:
792 case ARM::FK_VFPV2:
Logan Chiena39510a2013-12-18 17:23:15 +0000793 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000794 ARMBuildAttrs::AllowFPv2,
795 /* OverwriteExisting= */ false);
796 break;
797
Renato Golin35de35d2015-05-12 10:33:58 +0000798 case ARM::FK_VFPV3:
Logan Chiena39510a2013-12-18 17:23:15 +0000799 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000800 ARMBuildAttrs::AllowFPv3A,
801 /* OverwriteExisting= */ false);
802 break;
803
Renato Golin35de35d2015-05-12 10:33:58 +0000804 case ARM::FK_VFPV3_D16:
Logan Chiena39510a2013-12-18 17:23:15 +0000805 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000806 ARMBuildAttrs::AllowFPv3B,
807 /* OverwriteExisting= */ false);
808 break;
809
Renato Golin35de35d2015-05-12 10:33:58 +0000810 case ARM::FK_VFPV4:
Logan Chiena39510a2013-12-18 17:23:15 +0000811 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000812 ARMBuildAttrs::AllowFPv4A,
813 /* OverwriteExisting= */ false);
814 break;
815
Renato Golin35de35d2015-05-12 10:33:58 +0000816 case ARM::FK_VFPV4_D16:
Logan Chiena39510a2013-12-18 17:23:15 +0000817 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000818 ARMBuildAttrs::AllowFPv4B,
819 /* OverwriteExisting= */ false);
820 break;
821
Renato Golin35de35d2015-05-12 10:33:58 +0000822 case ARM::FK_FP_ARMV8:
Logan Chiena39510a2013-12-18 17:23:15 +0000823 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000824 ARMBuildAttrs::AllowFPARMv8A,
825 /* OverwriteExisting= */ false);
826 break;
827
Oliver Stannard37e4daa2014-10-01 09:02:17 +0000828 // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
829 // uses the FP_ARMV8_D16 build attribute.
Renato Golin35de35d2015-05-12 10:33:58 +0000830 case ARM::FK_FPV5_D16:
Oliver Stannard37e4daa2014-10-01 09:02:17 +0000831 setAttributeItem(ARMBuildAttrs::FP_arch,
832 ARMBuildAttrs::AllowFPARMv8B,
833 /* OverwriteExisting= */ false);
834 break;
835
Renato Golin35de35d2015-05-12 10:33:58 +0000836 case ARM::FK_NEON:
Logan Chiena39510a2013-12-18 17:23:15 +0000837 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000838 ARMBuildAttrs::AllowFPv3A,
839 /* OverwriteExisting= */ false);
840 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
841 ARMBuildAttrs::AllowNeon,
842 /* OverwriteExisting= */ false);
843 break;
844
Renato Golin35de35d2015-05-12 10:33:58 +0000845 case ARM::FK_NEON_VFPV4:
Logan Chiena39510a2013-12-18 17:23:15 +0000846 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000847 ARMBuildAttrs::AllowFPv4A,
848 /* OverwriteExisting= */ false);
849 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
850 ARMBuildAttrs::AllowNeon2,
851 /* OverwriteExisting= */ false);
852 break;
853
Renato Golin35de35d2015-05-12 10:33:58 +0000854 case ARM::FK_NEON_FP_ARMV8:
855 case ARM::FK_CRYPTO_NEON_FP_ARMV8:
Logan Chiena39510a2013-12-18 17:23:15 +0000856 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000857 ARMBuildAttrs::AllowFPARMv8A,
858 /* OverwriteExisting= */ false);
Vladimir Sukharevc632cda2015-03-26 17:05:54 +0000859 // 'Advanced_SIMD_arch' must be emitted not here, but within
860 // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
Logan Chien8cbb80d2013-10-28 17:51:12 +0000861 break;
862
Renato Golin35de35d2015-05-12 10:33:58 +0000863 case ARM::FK_SOFTVFP:
Logan Chien05ae7442014-01-02 15:50:02 +0000864 break;
865
Logan Chien8cbb80d2013-10-28 17:51:12 +0000866 default:
867 report_fatal_error("Unknown FPU: " + Twine(FPU));
868 break;
869 }
870}
871size_t ARMTargetELFStreamer::calculateContentSize() const {
872 size_t Result = 0;
873 for (size_t i = 0; i < Contents.size(); ++i) {
874 AttributeItem item = Contents[i];
875 switch (item.Type) {
876 case AttributeItem::HiddenAttribute:
877 break;
878 case AttributeItem::NumericAttribute:
Logan Chien5b776b72014-02-22 14:00:39 +0000879 Result += getULEB128Size(item.Tag);
880 Result += getULEB128Size(item.IntValue);
Logan Chien8cbb80d2013-10-28 17:51:12 +0000881 break;
882 case AttributeItem::TextAttribute:
Logan Chien5b776b72014-02-22 14:00:39 +0000883 Result += getULEB128Size(item.Tag);
Logan Chien8cbb80d2013-10-28 17:51:12 +0000884 Result += item.StringValue.size() + 1; // string + '\0'
885 break;
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000886 case AttributeItem::NumericAndTextAttributes:
Logan Chien5b776b72014-02-22 14:00:39 +0000887 Result += getULEB128Size(item.Tag);
888 Result += getULEB128Size(item.IntValue);
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000889 Result += item.StringValue.size() + 1; // string + '\0';
890 break;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000891 }
892 }
893 return Result;
894}
895void ARMTargetELFStreamer::finishAttributeSection() {
896 // <format-version>
897 // [ <section-length> "vendor-name"
898 // [ <file-tag> <size> <attribute>*
899 // | <section-tag> <size> <section-number>* 0 <attribute>*
900 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
901 // ]+
902 // ]*
903
Renato Golin35de35d2015-05-12 10:33:58 +0000904 if (FPU != ARM::FK_INVALID)
Logan Chien8cbb80d2013-10-28 17:51:12 +0000905 emitFPUDefaultAttributes();
906
Renato Golin35de35d2015-05-12 10:33:58 +0000907 if (Arch != ARM::AK_INVALID)
Logan Chien439e8f92013-12-11 17:16:25 +0000908 emitArchDefaultAttributes();
909
Logan Chien8cbb80d2013-10-28 17:51:12 +0000910 if (Contents.empty())
911 return;
912
913 std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
914
915 ARMELFStreamer &Streamer = getStreamer();
916
917 // Switch to .ARM.attributes section
918 if (AttributeSection) {
919 Streamer.SwitchSection(AttributeSection);
920 } else {
Rafael Espindolaba31e272015-01-29 17:33:21 +0000921 AttributeSection = Streamer.getContext().getELFSection(
922 ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);
Logan Chien8cbb80d2013-10-28 17:51:12 +0000923 Streamer.SwitchSection(AttributeSection);
924
925 // Format version
926 Streamer.EmitIntValue(0x41, 1);
927 }
928
929 // Vendor size + Vendor name + '\0'
930 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
931
932 // Tag + Tag Size
933 const size_t TagHeaderSize = 1 + 4;
934
935 const size_t ContentsSize = calculateContentSize();
936
937 Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
938 Streamer.EmitBytes(CurrentVendor);
939 Streamer.EmitIntValue(0, 1); // '\0'
940
941 Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
942 Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
943
944 // Size should have been accounted for already, now
945 // emit each field as its type (ULEB or String)
946 for (size_t i = 0; i < Contents.size(); ++i) {
947 AttributeItem item = Contents[i];
948 Streamer.EmitULEB128IntValue(item.Tag);
949 switch (item.Type) {
950 default: llvm_unreachable("Invalid attribute type");
951 case AttributeItem::NumericAttribute:
952 Streamer.EmitULEB128IntValue(item.IntValue);
953 break;
954 case AttributeItem::TextAttribute:
Charlie Turner8d433692014-11-27 12:13:56 +0000955 Streamer.EmitBytes(item.StringValue);
Logan Chien8cbb80d2013-10-28 17:51:12 +0000956 Streamer.EmitIntValue(0, 1); // '\0'
957 break;
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000958 case AttributeItem::NumericAndTextAttributes:
959 Streamer.EmitULEB128IntValue(item.IntValue);
Charlie Turner8d433692014-11-27 12:13:56 +0000960 Streamer.EmitBytes(item.StringValue);
Saleem Abdulrasool87ccd362014-01-07 02:28:42 +0000961 Streamer.EmitIntValue(0, 1); // '\0'
962 break;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000963 }
964 }
965
966 Contents.clear();
Renato Golin35de35d2015-05-12 10:33:58 +0000967 FPU = ARM::FK_INVALID;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000968}
Rafael Espindola4c6f6132014-04-27 17:10:46 +0000969
970void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
971 ARMELFStreamer &Streamer = getStreamer();
972 if (!Streamer.IsThumb)
973 return;
974
Rafael Espindolae3b2acf2015-05-29 18:47:23 +0000975 Streamer.getOrCreateSymbolData(Symbol);
976 unsigned Type = MCELF::GetType(*Symbol);
Scott Douglass7650a9b2014-06-30 09:37:24 +0000977 if (Type == ELF_STT_Func || Type == ELF_STT_GnuIFunc)
Rafael Espindola4c6f6132014-04-27 17:10:46 +0000978 Streamer.EmitThumbFunc(Symbol);
979}
980
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +0000981void
982ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
983 getStreamer().EmitFixup(S, FK_Data_4);
984}
Rafael Espindola466d6632014-04-27 20:23:58 +0000985
986void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
987 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
Rafael Espindola4a042942014-05-01 12:45:43 +0000988 const MCSymbol &Sym = SRE->getSymbol();
989 if (!Sym.isDefined()) {
Rafael Espindola466d6632014-04-27 20:23:58 +0000990 getStreamer().EmitAssignment(Symbol, Value);
991 return;
992 }
993 }
994
995 getStreamer().EmitThumbFunc(Symbol);
996 getStreamer().EmitAssignment(Symbol, Value);
997}
998
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000999void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
1000 getStreamer().emitInst(Inst, Suffix);
1001}
Logan Chien8cbb80d2013-10-28 17:51:12 +00001002
1003void ARMELFStreamer::FinishImpl() {
Rafael Espindola4a1a3602014-01-14 01:21:46 +00001004 MCTargetStreamer &TS = *getTargetStreamer();
Logan Chien8cbb80d2013-10-28 17:51:12 +00001005 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1006 ATS.finishAttributeSection();
1007
1008 MCELFStreamer::FinishImpl();
1009}
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001010
Logan Chien2bcc42c2013-01-30 15:39:04 +00001011inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
1012 unsigned Type,
1013 unsigned Flags,
1014 SectionKind Kind,
1015 const MCSymbol &Fn) {
1016 const MCSectionELF &FnSection =
1017 static_cast<const MCSectionELF &>(Fn.getSection());
1018
1019 // Create the name for new section
1020 StringRef FnSecName(FnSection.getSectionName());
1021 SmallString<128> EHSecName(Prefix);
1022 if (FnSecName != ".text") {
1023 EHSecName += FnSecName;
1024 }
1025
1026 // Get .ARM.extab or .ARM.exidx section
Rafael Espindola61e8ce32015-04-06 04:25:18 +00001027 const MCSymbol *Group = FnSection.getGroup();
1028 if (Group)
1029 Flags |= ELF::SHF_GROUP;
Rafael Espindola0709a7b2015-05-21 19:20:38 +00001030 MCSectionELF *EHSection =
Rafael Espindola61e8ce32015-04-06 04:25:18 +00001031 getContext().getELFSection(EHSecName, Type, Flags, 0, Group,
1032 FnSection.getUniqueID(), nullptr, &FnSection);
1033
Logan Chiend8bb4b72013-04-16 12:02:21 +00001034 assert(EHSection && "Failed to get the required EH section");
Logan Chien2bcc42c2013-01-30 15:39:04 +00001035
1036 // Switch to .ARM.extab or .ARM.exidx section
1037 SwitchSection(EHSection);
Rafael Espindola7b514962014-02-04 18:34:04 +00001038 EmitCodeAlignment(4);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001039}
1040
1041inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1042 SwitchToEHSection(".ARM.extab",
1043 ELF::SHT_PROGBITS,
1044 ELF::SHF_ALLOC,
1045 SectionKind::getDataRel(),
1046 FnStart);
1047}
1048
1049inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
1050 SwitchToEHSection(".ARM.exidx",
1051 ELF::SHT_ARM_EXIDX,
1052 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
1053 SectionKind::getDataRel(),
1054 FnStart);
1055}
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +00001056void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
1057 MCDataFragment *Frag = getOrCreateDataFragment();
Jim Grosbach63661f82015-05-15 19:13:05 +00001058 Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
Saleem Abdulrasool56e06e82014-01-30 04:02:47 +00001059 Kind));
1060}
Logan Chien2bcc42c2013-01-30 15:39:04 +00001061
1062void ARMELFStreamer::Reset() {
Craig Topper062a2ba2014-04-25 05:30:21 +00001063 ExTab = nullptr;
1064 FnStart = nullptr;
1065 Personality = nullptr;
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +00001066 PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
Logan Chien325823a2013-06-09 12:22:30 +00001067 FPReg = ARM::SP;
Logan Chiend8bb4b72013-04-16 12:02:21 +00001068 FPOffset = 0;
1069 SPOffset = 0;
Logan Chien325823a2013-06-09 12:22:30 +00001070 PendingOffset = 0;
Logan Chiend8bb4b72013-04-16 12:02:21 +00001071 UsedFP = false;
Logan Chien2bcc42c2013-01-30 15:39:04 +00001072 CantUnwind = false;
Logan Chiend8bb4b72013-04-16 12:02:21 +00001073
Logan Chien325823a2013-06-09 12:22:30 +00001074 Opcodes.clear();
Logan Chiend8bb4b72013-04-16 12:02:21 +00001075 UnwindOpAsm.Reset();
Logan Chien2bcc42c2013-01-30 15:39:04 +00001076}
1077
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001078void ARMELFStreamer::emitFnStart() {
Craig Toppere73658d2014-04-28 04:05:08 +00001079 assert(FnStart == nullptr);
Jim Grosbach6f482002015-05-18 18:43:14 +00001080 FnStart = getContext().createTempSymbol();
Logan Chien2bcc42c2013-01-30 15:39:04 +00001081 EmitLabel(FnStart);
1082}
1083
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001084void ARMELFStreamer::emitFnEnd() {
Alp Tokercb402912014-01-24 17:20:08 +00001085 assert(FnStart && ".fnstart must precedes .fnend");
Logan Chien2bcc42c2013-01-30 15:39:04 +00001086
1087 // Emit unwind opcodes if there is no .handlerdata directive
Logan Chien4ea23b52013-05-10 16:17:24 +00001088 if (!ExTab && !CantUnwind)
1089 FlushUnwindOpcodes(true);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001090
1091 // Emit the exception index table entry
1092 SwitchToExIdxSection(*FnStart);
1093
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +00001094 if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX)
Logan Chiend8bb4b72013-04-16 12:02:21 +00001095 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
Logan Chien2bcc42c2013-01-30 15:39:04 +00001096
1097 const MCSymbolRefExpr *FnStartRef =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001098 MCSymbolRefExpr::create(FnStart,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001099 MCSymbolRefExpr::VK_ARM_PREL31,
1100 getContext());
1101
Rafael Espindola64e1af82013-07-02 15:49:13 +00001102 EmitValue(FnStartRef, 4);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001103
1104 if (CantUnwind) {
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +00001105 EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4);
Logan Chiend8bb4b72013-04-16 12:02:21 +00001106 } else if (ExTab) {
1107 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
Logan Chien2bcc42c2013-01-30 15:39:04 +00001108 const MCSymbolRefExpr *ExTabEntryRef =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001109 MCSymbolRefExpr::create(ExTab,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001110 MCSymbolRefExpr::VK_ARM_PREL31,
1111 getContext());
Rafael Espindola64e1af82013-07-02 15:49:13 +00001112 EmitValue(ExTabEntryRef, 4);
Logan Chiend8bb4b72013-04-16 12:02:21 +00001113 } else {
1114 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1115 // the second word of exception index table entry. The size of the unwind
1116 // opcodes should always be 4 bytes.
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +00001117 assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
Jonathan Roelofs4971b402014-05-15 02:24:50 +00001118 "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
Logan Chien325823a2013-06-09 12:22:30 +00001119 assert(Opcodes.size() == 4u &&
Jonathan Roelofs4971b402014-05-15 02:24:50 +00001120 "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
Christian Pirker39db7ec2014-05-13 16:44:30 +00001121 uint64_t Intval = Opcodes[0] |
1122 Opcodes[1] << 8 |
1123 Opcodes[2] << 16 |
1124 Opcodes[3] << 24;
1125 EmitIntValue(Intval, Opcodes.size());
Logan Chien2bcc42c2013-01-30 15:39:04 +00001126 }
1127
Logan Chien4ea23b52013-05-10 16:17:24 +00001128 // Switch to the section containing FnStart
1129 SwitchSection(&FnStart->getSection());
1130
Logan Chien2bcc42c2013-01-30 15:39:04 +00001131 // Clean exception handling frame information
1132 Reset();
1133}
1134
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001135void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1136
1137// Add the R_ARM_NONE fixup at the same position
1138void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
Jim Grosbach6f482002015-05-18 18:43:14 +00001139 const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001140
Jim Grosbach13760bd2015-05-30 01:25:56 +00001141 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001142 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
1143
Rafael Espindola2be12812014-06-25 15:29:54 +00001144 visitUsedExpr(*PersonalityRef);
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001145 MCDataFragment *DF = getOrCreateDataFragment();
Jim Grosbach63661f82015-05-15 19:13:05 +00001146 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001147 PersonalityRef,
1148 MCFixup::getKindForSize(4, false)));
Logan Chien2bcc42c2013-01-30 15:39:04 +00001149}
1150
Logan Chien325823a2013-06-09 12:22:30 +00001151void ARMELFStreamer::FlushPendingOffset() {
1152 if (PendingOffset != 0) {
1153 UnwindOpAsm.EmitSPOffset(-PendingOffset);
1154 PendingOffset = 0;
1155 }
1156}
1157
Logan Chienc931fce2013-07-02 12:43:27 +00001158void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
Logan Chien325823a2013-06-09 12:22:30 +00001159 // Emit the unwind opcode to restore $sp.
1160 if (UsedFP) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001161 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
Logan Chien325823a2013-06-09 12:22:30 +00001162 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1163 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
Bill Wendlingbc07a892013-06-18 07:20:20 +00001164 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
Logan Chien325823a2013-06-09 12:22:30 +00001165 } else {
1166 FlushPendingOffset();
1167 }
1168
1169 // Finalize the unwind opcode sequence
1170 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
Logan Chien4ea23b52013-05-10 16:17:24 +00001171
1172 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1173 // section. Thus, we don't have to create an entry in the .ARM.extab
1174 // section.
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +00001175 if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
Logan Chien4ea23b52013-05-10 16:17:24 +00001176 return;
1177
1178 // Switch to .ARM.extab section.
Logan Chien2bcc42c2013-01-30 15:39:04 +00001179 SwitchToExTabSection(*FnStart);
1180
1181 // Create .ARM.extab label for offset in .ARM.exidx
1182 assert(!ExTab);
Jim Grosbach6f482002015-05-18 18:43:14 +00001183 ExTab = getContext().createTempSymbol();
Logan Chien2bcc42c2013-01-30 15:39:04 +00001184 EmitLabel(ExTab);
1185
Logan Chien4ea23b52013-05-10 16:17:24 +00001186 // Emit personality
1187 if (Personality) {
1188 const MCSymbolRefExpr *PersonalityRef =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001189 MCSymbolRefExpr::create(Personality,
Logan Chien4ea23b52013-05-10 16:17:24 +00001190 MCSymbolRefExpr::VK_ARM_PREL31,
1191 getContext());
Logan Chien2bcc42c2013-01-30 15:39:04 +00001192
Rafael Espindola64e1af82013-07-02 15:49:13 +00001193 EmitValue(PersonalityRef, 4);
Logan Chien4ea23b52013-05-10 16:17:24 +00001194 }
Logan Chien2bcc42c2013-01-30 15:39:04 +00001195
1196 // Emit unwind opcodes
Christian Pirker39db7ec2014-05-13 16:44:30 +00001197 assert((Opcodes.size() % 4) == 0 &&
1198 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1199 for (unsigned I = 0; I != Opcodes.size(); I += 4) {
1200 uint64_t Intval = Opcodes[I] |
1201 Opcodes[I + 1] << 8 |
1202 Opcodes[I + 2] << 16 |
1203 Opcodes[I + 3] << 24;
1204 EmitIntValue(Intval, 4);
1205 }
Logan Chienc931fce2013-07-02 12:43:27 +00001206
1207 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1208 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1209 // after the unwind opcodes. The handler data consists of several 32-bit
1210 // words, and should be terminated by zero.
1211 //
1212 // In case that the .handlerdata directive is not specified by the
1213 // programmer, we should emit zero to terminate the handler data.
1214 if (NoHandlerData && !Personality)
1215 EmitIntValue(0, 4);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001216}
1217
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001218void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
Logan Chien4ea23b52013-05-10 16:17:24 +00001219
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001220void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
Logan Chien2bcc42c2013-01-30 15:39:04 +00001221 Personality = Per;
Logan Chiend8bb4b72013-04-16 12:02:21 +00001222 UnwindOpAsm.setPersonality(Per);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001223}
1224
Saleem Abdulrasool662f5c12014-01-21 02:33:02 +00001225void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
1226 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
1227 PersonalityIndex = Index;
1228}
1229
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001230void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001231 int64_t Offset) {
Logan Chien325823a2013-06-09 12:22:30 +00001232 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
Logan Chiend8bb4b72013-04-16 12:02:21 +00001233 "the operand of .setfp directive should be either $sp or $fp");
1234
1235 UsedFP = true;
Logan Chien325823a2013-06-09 12:22:30 +00001236 FPReg = NewFPReg;
1237
1238 if (NewSPReg == ARM::SP)
1239 FPOffset = SPOffset + Offset;
1240 else
1241 FPOffset += Offset;
Logan Chien2bcc42c2013-01-30 15:39:04 +00001242}
1243
Saleem Abdulrasool5d962d32014-01-30 04:46:24 +00001244void ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
1245 assert((Reg != ARM::SP && Reg != ARM::PC) &&
1246 "the operand of .movsp cannot be either sp or pc");
1247 assert(FPReg == ARM::SP && "current FP must be SP");
1248
1249 FlushPendingOffset();
1250
1251 FPReg = Reg;
1252 FPOffset = SPOffset + Offset;
1253
1254 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1255 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1256}
1257
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001258void ARMELFStreamer::emitPad(int64_t Offset) {
Logan Chien325823a2013-06-09 12:22:30 +00001259 // Track the change of the $sp offset
1260 SPOffset -= Offset;
1261
1262 // To squash multiple .pad directives, we should delay the unwind opcode
1263 // until the .save, .vsave, .handlerdata, or .fnend directives.
1264 PendingOffset -= Offset;
Logan Chien2bcc42c2013-01-30 15:39:04 +00001265}
1266
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001267void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001268 bool IsVector) {
Logan Chien325823a2013-06-09 12:22:30 +00001269 // Collect the registers in the register list
1270 unsigned Count = 0;
1271 uint32_t Mask = 0;
Bill Wendlingbc07a892013-06-18 07:20:20 +00001272 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
Logan Chiend8bb4b72013-04-16 12:02:21 +00001273 for (size_t i = 0; i < RegList.size(); ++i) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001274 unsigned Reg = MRI->getEncodingValue(RegList[i]);
Aaron Ballmanab1d27e2013-06-10 16:45:40 +00001275 assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
Logan Chien325823a2013-06-09 12:22:30 +00001276 unsigned Bit = (1u << Reg);
1277 if ((Mask & Bit) == 0) {
1278 Mask |= Bit;
1279 ++Count;
1280 }
Logan Chiend8bb4b72013-04-16 12:02:21 +00001281 }
Logan Chien325823a2013-06-09 12:22:30 +00001282
1283 // Track the change the $sp offset: For the .save directive, the
1284 // corresponding push instruction will decrease the $sp by (4 * Count).
1285 // For the .vsave directive, the corresponding vpush instruction will
1286 // decrease $sp by (8 * Count).
1287 SPOffset -= Count * (IsVector ? 8 : 4);
1288
1289 // Emit the opcode
1290 FlushPendingOffset();
1291 if (IsVector)
1292 UnwindOpAsm.EmitVFPRegSave(Mask);
1293 else
1294 UnwindOpAsm.EmitRegSave(Mask);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001295}
1296
Saleem Abdulrasoold9f08602014-01-21 02:33:10 +00001297void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
1298 const SmallVectorImpl<uint8_t> &Opcodes) {
1299 FlushPendingOffset();
1300 SPOffset = SPOffset - Offset;
1301 UnwindOpAsm.EmitRaw(Opcodes);
1302}
1303
Tim Northover5cc3dc82012-12-07 16:50:23 +00001304namespace llvm {
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001305
Rafael Espindola73870dd2015-03-16 21:43:42 +00001306MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
1307 formatted_raw_ostream &OS,
1308 MCInstPrinter *InstPrint,
1309 bool isVerboseAsm) {
1310 return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001311}
1312
Peter Collingbourne20c72592015-02-19 00:45:02 +00001313MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
1314 return new ARMTargetStreamer(S);
1315}
1316
Rafael Espindolacd584a82015-03-19 01:50:16 +00001317MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S,
1318 const MCSubtargetInfo &STI) {
1319 Triple TT(STI.getTargetTriple());
1320 if (TT.getObjectFormat() == Triple::ELF)
1321 return new ARMTargetELFStreamer(S);
1322 return new ARMTargetStreamer(S);
1323}
1324
Rafael Espindola7b61ddf2014-10-15 16:12:52 +00001325MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
Rafael Espindola5560a4c2015-04-14 22:14:34 +00001326 raw_pwrite_stream &OS,
1327 MCCodeEmitter *Emitter, bool RelaxAll,
1328 bool IsThumb) {
Rafael Espindola24ea09e2014-01-26 06:06:37 +00001329 ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb);
Rafael Espindolaac4ad252013-10-05 16:42:21 +00001330 // FIXME: This should eventually end up somewhere else where more
1331 // intelligent flag decisions can be made. For now we are just maintaining
1332 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1333 S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1334
Tim Northover5cc3dc82012-12-07 16:50:23 +00001335 if (RelaxAll)
1336 S->getAssembler().setRelaxAll(true);
Tim Northover5cc3dc82012-12-07 16:50:23 +00001337 return S;
1338 }
1339
1340}
1341
1342