blob: 05b4e2e22a8ee87bd728ec125e303b00b3998fef [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 Chien8cbb80d2013-10-28 17:51:12 +000016#include "ARMBuildAttrs.h"
Logan Chien439e8f92013-12-11 17:16:25 +000017#include "ARMArchName.h"
Logan Chien8cbb80d2013-10-28 17:51:12 +000018#include "ARMFPUName.h"
Logan Chiend8bb4b72013-04-16 12:02:21 +000019#include "ARMRegisterInfo.h"
Logan Chien2bcc42c2013-01-30 15:39:04 +000020#include "ARMUnwindOp.h"
Logan Chiend8bb4b72013-04-16 12:02:21 +000021#include "ARMUnwindOpAsm.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000022#include "llvm/ADT/SmallPtrSet.h"
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +000023#include "llvm/ADT/StringExtras.h"
Benjamin Kramerf242d8c2012-12-08 10:45:24 +000024#include "llvm/ADT/Twine.h"
25#include "llvm/MC/MCAsmBackend.h"
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +000026#include "llvm/MC/MCAsmInfo.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000027#include "llvm/MC/MCAssembler.h"
28#include "llvm/MC/MCCodeEmitter.h"
29#include "llvm/MC/MCContext.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000030#include "llvm/MC/MCELF.h"
31#include "llvm/MC/MCELFStreamer.h"
32#include "llvm/MC/MCELFSymbolFlags.h"
33#include "llvm/MC/MCExpr.h"
34#include "llvm/MC/MCInst.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000035#include "llvm/MC/MCInstPrinter.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000036#include "llvm/MC/MCObjectStreamer.h"
Logan Chiend8bb4b72013-04-16 12:02:21 +000037#include "llvm/MC/MCRegisterInfo.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000038#include "llvm/MC/MCSection.h"
Benjamin Kramerf242d8c2012-12-08 10:45:24 +000039#include "llvm/MC/MCSectionELF.h"
40#include "llvm/MC/MCStreamer.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000041#include "llvm/MC/MCSymbol.h"
42#include "llvm/MC/MCValue.h"
Tim Northover5cc3dc82012-12-07 16:50:23 +000043#include "llvm/Support/Debug.h"
44#include "llvm/Support/ELF.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000045#include "llvm/Support/FormattedStream.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) {
52 assert(Index < NUM_PERSONALITY_INDEX && "Invalid personality index");
53 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
54}
55
Logan Chien8cbb80d2013-10-28 17:51:12 +000056static const char *GetFPUName(unsigned ID) {
57 switch (ID) {
58 default:
59 llvm_unreachable("Unknown FPU kind");
60 break;
61#define ARM_FPU_NAME(NAME, ID) case ARM::ID: return NAME;
62#include "ARMFPUName.def"
63 }
64 return NULL;
65}
66
Logan Chien439e8f92013-12-11 17:16:25 +000067static const char *GetArchName(unsigned ID) {
68 switch (ID) {
69 default:
70 llvm_unreachable("Unknown ARCH kind");
71 break;
72#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
73 case ARM::ID: return NAME;
Joerg Sonnenbergera13f8b42013-12-26 11:50:28 +000074#define ARM_ARCH_ALIAS(NAME, ID) /* empty */
Logan Chien439e8f92013-12-11 17:16:25 +000075#include "ARMArchName.def"
76 }
77 return NULL;
78}
79
80static const char *GetArchDefaultCPUName(unsigned ID) {
81 switch (ID) {
82 default:
83 llvm_unreachable("Unknown ARCH kind");
84 break;
85#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
86 case ARM::ID: return DEFAULT_CPU_NAME;
Joerg Sonnenbergera13f8b42013-12-26 11:50:28 +000087#define ARM_ARCH_ALIAS(NAME, ID) /* empty */
Logan Chien439e8f92013-12-11 17:16:25 +000088#include "ARMArchName.def"
89 }
90 return NULL;
91}
92
93static unsigned GetArchDefaultCPUArch(unsigned ID) {
94 switch (ID) {
95 default:
96 llvm_unreachable("Unknown ARCH kind");
97 break;
98#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
99 case ARM::ID: return ARMBuildAttrs::DEFAULT_CPU_ARCH;
Joerg Sonnenbergera13f8b42013-12-26 11:50:28 +0000100#define ARM_ARCH_ALIAS(NAME, ID) /* empty */
Logan Chien439e8f92013-12-11 17:16:25 +0000101#include "ARMArchName.def"
102 }
103 return 0;
104}
105
Tim Northover5cc3dc82012-12-07 16:50:23 +0000106namespace {
107
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000108class ARMELFStreamer;
109
110class ARMTargetAsmStreamer : public ARMTargetStreamer {
111 formatted_raw_ostream &OS;
112 MCInstPrinter &InstPrinter;
113
114 virtual void emitFnStart();
115 virtual void emitFnEnd();
116 virtual void emitCantUnwind();
117 virtual void emitPersonality(const MCSymbol *Personality);
118 virtual void emitHandlerData();
119 virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
120 virtual void emitPad(int64_t Offset);
121 virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
122 bool isVector);
123
Logan Chien8cbb80d2013-10-28 17:51:12 +0000124 virtual void switchVendor(StringRef Vendor);
125 virtual void emitAttribute(unsigned Attribute, unsigned Value);
126 virtual void emitTextAttribute(unsigned Attribute, StringRef String);
Logan Chien439e8f92013-12-11 17:16:25 +0000127 virtual void emitArch(unsigned Arch);
Logan Chien8cbb80d2013-10-28 17:51:12 +0000128 virtual void emitFPU(unsigned FPU);
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000129 virtual void emitInst(uint32_t Inst, char Suffix = '\0');
Logan Chien8cbb80d2013-10-28 17:51:12 +0000130 virtual void finishAttributeSection();
131
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000132public:
133 ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter &InstPrinter);
134};
135
136ARMTargetAsmStreamer::ARMTargetAsmStreamer(formatted_raw_ostream &OS,
137 MCInstPrinter &InstPrinter)
138 : OS(OS), InstPrinter(InstPrinter) {}
139void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
140void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
141void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
142void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
143 OS << "\t.personality " << Personality->getName() << '\n';
144}
145void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
146void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
147 int64_t Offset) {
148 OS << "\t.setfp\t";
149 InstPrinter.printRegName(OS, FpReg);
150 OS << ", ";
151 InstPrinter.printRegName(OS, SpReg);
152 if (Offset)
153 OS << ", #" << Offset;
154 OS << '\n';
155}
156void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
157 OS << "\t.pad\t#" << Offset << '\n';
158}
159void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
160 bool isVector) {
161 assert(RegList.size() && "RegList should not be empty");
162 if (isVector)
163 OS << "\t.vsave\t{";
164 else
165 OS << "\t.save\t{";
166
167 InstPrinter.printRegName(OS, RegList[0]);
168
169 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
170 OS << ", ";
171 InstPrinter.printRegName(OS, RegList[i]);
172 }
173
174 OS << "}\n";
175}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000176void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {
177}
178void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
179 OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
180}
181void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
182 StringRef String) {
183 switch (Attribute) {
184 default: llvm_unreachable("Unsupported Text attribute in ASM Mode");
185 case ARMBuildAttrs::CPU_name:
186 OS << "\t.cpu\t" << String.lower() << "\n";
187 break;
188 }
189}
Logan Chien439e8f92013-12-11 17:16:25 +0000190void ARMTargetAsmStreamer::emitArch(unsigned Arch) {
191 OS << "\t.arch\t" << GetArchName(Arch) << "\n";
192}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000193void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
194 OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
195}
196void ARMTargetAsmStreamer::finishAttributeSection() {
197}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000198
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000199void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
200 OS << "\t.inst";
201 if (Suffix)
202 OS << "." << Suffix;
203 OS << "\t0x" << utohexstr(Inst) << "\n";
204}
205
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000206class ARMTargetELFStreamer : public ARMTargetStreamer {
Logan Chien8cbb80d2013-10-28 17:51:12 +0000207private:
208 // This structure holds all attributes, accounting for
209 // their string/numeric value, so we can later emmit them
210 // in declaration order, keeping all in the same vector
211 struct AttributeItem {
212 enum {
213 HiddenAttribute = 0,
214 NumericAttribute,
215 TextAttribute
216 } Type;
217 unsigned Tag;
218 unsigned IntValue;
219 StringRef StringValue;
220
221 static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
222 return (LHS.Tag < RHS.Tag);
223 }
224 };
225
226 StringRef CurrentVendor;
227 unsigned FPU;
Logan Chien439e8f92013-12-11 17:16:25 +0000228 unsigned Arch;
Logan Chien8cbb80d2013-10-28 17:51:12 +0000229 SmallVector<AttributeItem, 64> Contents;
230
231 const MCSection *AttributeSection;
232
233 // FIXME: this should be in a more generic place, but
234 // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
235 static size_t getULEBSize(int Value) {
236 size_t Size = 0;
237 do {
238 Value >>= 7;
239 Size += sizeof(int8_t); // Is this really necessary?
240 } while (Value);
241 return Size;
242 }
243
244 AttributeItem *getAttributeItem(unsigned Attribute) {
245 for (size_t i = 0; i < Contents.size(); ++i)
246 if (Contents[i].Tag == Attribute)
247 return &Contents[i];
248 return 0;
249 }
250
251 void setAttributeItem(unsigned Attribute, unsigned Value,
252 bool OverwriteExisting) {
253 // Look for existing attribute item
254 if (AttributeItem *Item = getAttributeItem(Attribute)) {
255 if (!OverwriteExisting)
256 return;
257 Item->IntValue = Value;
258 return;
259 }
260
261 // Create new attribute item
262 AttributeItem Item = {
263 AttributeItem::NumericAttribute,
264 Attribute,
265 Value,
266 StringRef("")
267 };
268 Contents.push_back(Item);
269 }
270
271 void setAttributeItem(unsigned Attribute, StringRef Value,
272 bool OverwriteExisting) {
273 // Look for existing attribute item
274 if (AttributeItem *Item = getAttributeItem(Attribute)) {
275 if (!OverwriteExisting)
276 return;
277 Item->StringValue = Value;
278 return;
279 }
280
281 // Create new attribute item
282 AttributeItem Item = {
283 AttributeItem::TextAttribute,
284 Attribute,
285 0,
286 Value
287 };
288 Contents.push_back(Item);
289 }
290
Logan Chien439e8f92013-12-11 17:16:25 +0000291 void emitArchDefaultAttributes();
Logan Chien8cbb80d2013-10-28 17:51:12 +0000292 void emitFPUDefaultAttributes();
293
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000294 ARMELFStreamer &getStreamer();
Logan Chien8cbb80d2013-10-28 17:51:12 +0000295
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000296 virtual void emitFnStart();
297 virtual void emitFnEnd();
298 virtual void emitCantUnwind();
299 virtual void emitPersonality(const MCSymbol *Personality);
300 virtual void emitHandlerData();
301 virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
302 virtual void emitPad(int64_t Offset);
303 virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
304 bool isVector);
Logan Chien8cbb80d2013-10-28 17:51:12 +0000305
306 virtual void switchVendor(StringRef Vendor);
307 virtual void emitAttribute(unsigned Attribute, unsigned Value);
308 virtual void emitTextAttribute(unsigned Attribute, StringRef String);
Logan Chien439e8f92013-12-11 17:16:25 +0000309 virtual void emitArch(unsigned Arch);
Logan Chien8cbb80d2013-10-28 17:51:12 +0000310 virtual void emitFPU(unsigned FPU);
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000311 virtual void emitInst(uint32_t Inst, char Suffix = '\0');
Logan Chien8cbb80d2013-10-28 17:51:12 +0000312 virtual void finishAttributeSection();
313
314 size_t calculateContentSize() const;
315
316public:
317 ARMTargetELFStreamer()
318 : ARMTargetStreamer(), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
Logan Chien439e8f92013-12-11 17:16:25 +0000319 Arch(ARM::INVALID_ARCH), AttributeSection(0) {
Logan Chien8cbb80d2013-10-28 17:51:12 +0000320 }
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000321};
322
Tim Northover5cc3dc82012-12-07 16:50:23 +0000323/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
324/// the appropriate points in the object files. These symbols are defined in the
325/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
326///
327/// In brief: $a, $t or $d should be emitted at the start of each contiguous
328/// region of ARM code, Thumb code or data in a section. In practice, this
329/// emission does not rely on explicit assembler directives but on inherent
330/// properties of the directives doing the emission (e.g. ".byte" is data, "add
331/// r0, r0, r0" an instruction).
332///
333/// As a result this system is orthogonal to the DataRegion infrastructure used
334/// by MachO. Beware!
335class ARMELFStreamer : public MCELFStreamer {
336public:
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000337 friend class ARMTargetELFStreamer;
338
339 ARMELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
340 MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter,
341 bool IsThumb)
342 : MCELFStreamer(Context, TargetStreamer, TAB, OS, Emitter),
343 IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) {
Logan Chiend8bb4b72013-04-16 12:02:21 +0000344 Reset();
345 }
Tim Northover5cc3dc82012-12-07 16:50:23 +0000346
347 ~ARMELFStreamer() {}
348
Logan Chien8cbb80d2013-10-28 17:51:12 +0000349 virtual void FinishImpl();
350
Logan Chien2bcc42c2013-01-30 15:39:04 +0000351 // ARM exception handling directives
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000352 void emitFnStart();
353 void emitFnEnd();
354 void emitCantUnwind();
355 void emitPersonality(const MCSymbol *Per);
356 void emitHandlerData();
357 void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
358 void emitPad(int64_t Offset);
359 void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000360
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000361 virtual void ChangeSection(const MCSection *Section,
362 const MCExpr *Subsection) {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000363 // We have to keep track of the mapping symbol state of any sections we
364 // use. Each one should start off as EMS_None, which is provided as the
365 // default constructor by DenseMap::lookup.
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000366 LastMappingSymbols[getPreviousSection().first] = LastEMS;
Tim Northover5cc3dc82012-12-07 16:50:23 +0000367 LastEMS = LastMappingSymbols.lookup(Section);
368
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000369 MCELFStreamer::ChangeSection(Section, Subsection);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000370 }
371
372 /// This function is the one used to emit instruction data into the ELF
373 /// streamer. We override it to add the appropriate mapping symbol if
374 /// necessary.
375 virtual void EmitInstruction(const MCInst& Inst) {
376 if (IsThumb)
377 EmitThumbMappingSymbol();
378 else
379 EmitARMMappingSymbol();
380
381 MCELFStreamer::EmitInstruction(Inst);
382 }
383
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000384 virtual void emitInst(uint32_t Inst, char Suffix) {
385 unsigned Size;
386 char Buffer[4];
387 const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
388
389 switch (Suffix) {
390 case '\0':
391 Size = 4;
392
393 assert(!IsThumb);
394 EmitARMMappingSymbol();
395 for (unsigned II = 0, IE = Size; II != IE; II++) {
396 const unsigned I = LittleEndian ? (Size - II - 1) : II;
397 Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
398 }
399
400 break;
401 case 'n':
402 case 'w':
403 Size = (Suffix == 'n' ? 2 : 4);
404
405 assert(IsThumb);
406 EmitThumbMappingSymbol();
407 for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
408 const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1);
409 const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2);
410 Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
411 Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
412 }
413
414 break;
415 default:
416 llvm_unreachable("Invalid Suffix");
417 }
418
419 MCELFStreamer::EmitBytes(StringRef(Buffer, Size));
420 }
421
Tim Northover5cc3dc82012-12-07 16:50:23 +0000422 /// This is one of the functions used to emit data into an ELF section, so the
423 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
424 /// necessary.
Rafael Espindola64e1af82013-07-02 15:49:13 +0000425 virtual void EmitBytes(StringRef Data) {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000426 EmitDataMappingSymbol();
Rafael Espindola64e1af82013-07-02 15:49:13 +0000427 MCELFStreamer::EmitBytes(Data);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000428 }
429
430 /// This is one of the functions used to emit data into an ELF section, so the
431 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
432 /// necessary.
Rafael Espindola64e1af82013-07-02 15:49:13 +0000433 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) {
Tim Northover5cc3dc82012-12-07 16:50:23 +0000434 EmitDataMappingSymbol();
Rafael Espindola64e1af82013-07-02 15:49:13 +0000435 MCELFStreamer::EmitValueImpl(Value, Size);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000436 }
437
438 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {
439 MCELFStreamer::EmitAssemblerFlag(Flag);
440
441 switch (Flag) {
442 case MCAF_SyntaxUnified:
443 return; // no-op here.
444 case MCAF_Code16:
445 IsThumb = true;
446 return; // Change to Thumb mode
447 case MCAF_Code32:
448 IsThumb = false;
449 return; // Change to ARM mode
450 case MCAF_Code64:
451 return;
452 case MCAF_SubsectionsViaSymbols:
453 return;
454 }
455 }
456
457private:
458 enum ElfMappingSymbol {
459 EMS_None,
460 EMS_ARM,
461 EMS_Thumb,
462 EMS_Data
463 };
464
465 void EmitDataMappingSymbol() {
466 if (LastEMS == EMS_Data) return;
467 EmitMappingSymbol("$d");
468 LastEMS = EMS_Data;
469 }
470
471 void EmitThumbMappingSymbol() {
472 if (LastEMS == EMS_Thumb) return;
473 EmitMappingSymbol("$t");
474 LastEMS = EMS_Thumb;
475 }
476
477 void EmitARMMappingSymbol() {
478 if (LastEMS == EMS_ARM) return;
479 EmitMappingSymbol("$a");
480 LastEMS = EMS_ARM;
481 }
482
483 void EmitMappingSymbol(StringRef Name) {
484 MCSymbol *Start = getContext().CreateTempSymbol();
485 EmitLabel(Start);
486
Chandler Carruth1d94e932012-12-08 03:10:14 +0000487 MCSymbol *Symbol =
Benjamin Kramerf242d8c2012-12-08 10:45:24 +0000488 getContext().GetOrCreateSymbol(Name + "." +
489 Twine(MappingSymbolCounter++));
Tim Northover5cc3dc82012-12-07 16:50:23 +0000490
491 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
492 MCELF::SetType(SD, ELF::STT_NOTYPE);
493 MCELF::SetBinding(SD, ELF::STB_LOCAL);
494 SD.setExternal(false);
Richard Mitton21101b32013-09-19 23:21:01 +0000495 AssignSection(Symbol, getCurrentSection().first);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000496
497 const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
498 Symbol->setVariableValue(Value);
499 }
500
501 void EmitThumbFunc(MCSymbol *Func) {
502 // FIXME: Anything needed here to flag the function as thumb?
503
504 getAssembler().setIsThumbFunc(Func);
505
506 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
507 SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
508 }
509
Logan Chien2bcc42c2013-01-30 15:39:04 +0000510 // Helper functions for ARM exception handling directives
511 void Reset();
512
513 void EmitPersonalityFixup(StringRef Name);
Logan Chien325823a2013-06-09 12:22:30 +0000514 void FlushPendingOffset();
Logan Chienc931fce2013-07-02 12:43:27 +0000515 void FlushUnwindOpcodes(bool NoHandlerData);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000516
517 void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,
518 SectionKind Kind, const MCSymbol &Fn);
519 void SwitchToExTabSection(const MCSymbol &FnStart);
520 void SwitchToExIdxSection(const MCSymbol &FnStart);
Tim Northover5cc3dc82012-12-07 16:50:23 +0000521
522 bool IsThumb;
523 int64_t MappingSymbolCounter;
524
525 DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
526 ElfMappingSymbol LastEMS;
527
Logan Chien2bcc42c2013-01-30 15:39:04 +0000528 // ARM Exception Handling Frame Information
529 MCSymbol *ExTab;
530 MCSymbol *FnStart;
531 const MCSymbol *Personality;
Logan Chien325823a2013-06-09 12:22:30 +0000532 unsigned PersonalityIndex;
533 unsigned FPReg; // Frame pointer register
534 int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
535 int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
536 int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
Logan Chiend8bb4b72013-04-16 12:02:21 +0000537 bool UsedFP;
Logan Chien2bcc42c2013-01-30 15:39:04 +0000538 bool CantUnwind;
Logan Chien325823a2013-06-09 12:22:30 +0000539 SmallVector<uint8_t, 64> Opcodes;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000540 UnwindOpcodeAssembler UnwindOpAsm;
Tim Northover5cc3dc82012-12-07 16:50:23 +0000541};
Logan Chiend8bb4b72013-04-16 12:02:21 +0000542} // end anonymous namespace
Tim Northover5cc3dc82012-12-07 16:50:23 +0000543
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000544ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
Benjamin Kramer41882932013-10-09 17:23:41 +0000545 ARMELFStreamer *S = static_cast<ARMELFStreamer *>(Streamer);
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000546 return *S;
547}
548
549void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
550void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
551void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
552void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
553 getStreamer().emitPersonality(Personality);
554}
555void ARMTargetELFStreamer::emitHandlerData() {
556 getStreamer().emitHandlerData();
557}
558void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
559 int64_t Offset) {
560 getStreamer().emitSetFP(FpReg, SpReg, Offset);
561}
562void ARMTargetELFStreamer::emitPad(int64_t Offset) {
563 getStreamer().emitPad(Offset);
564}
565void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
566 bool isVector) {
567 getStreamer().emitRegSave(RegList, isVector);
568}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000569void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
570 assert(!Vendor.empty() && "Vendor cannot be empty.");
571
572 if (CurrentVendor == Vendor)
573 return;
574
575 if (!CurrentVendor.empty())
576 finishAttributeSection();
577
578 assert(Contents.empty() &&
579 ".ARM.attributes should be flushed before changing vendor");
580 CurrentVendor = Vendor;
581
582}
583void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
584 setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
585}
586void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
587 StringRef Value) {
588 setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
589}
Logan Chien439e8f92013-12-11 17:16:25 +0000590void ARMTargetELFStreamer::emitArch(unsigned Value) {
591 Arch = Value;
592}
593void ARMTargetELFStreamer::emitArchDefaultAttributes() {
594 using namespace ARMBuildAttrs;
595 setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false);
596 setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false);
597
598 switch (Arch) {
599 case ARM::ARMV2:
600 case ARM::ARMV2A:
601 case ARM::ARMV3:
602 case ARM::ARMV3M:
603 case ARM::ARMV4:
604 case ARM::ARMV5:
605 setAttributeItem(ARM_ISA_use, Allowed, false);
606 break;
607
608 case ARM::ARMV4T:
609 case ARM::ARMV5T:
610 case ARM::ARMV5TE:
611 case ARM::ARMV6:
612 case ARM::ARMV6J:
613 setAttributeItem(ARM_ISA_use, Allowed, false);
614 setAttributeItem(THUMB_ISA_use, Allowed, false);
615 break;
616
617 case ARM::ARMV6T2:
618 setAttributeItem(ARM_ISA_use, Allowed, false);
619 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
620 break;
621
622 case ARM::ARMV6Z:
623 case ARM::ARMV6ZK:
624 setAttributeItem(ARM_ISA_use, Allowed, false);
625 setAttributeItem(THUMB_ISA_use, Allowed, false);
626 setAttributeItem(Virtualization_use, AllowTZ, false);
627 break;
628
629 case ARM::ARMV6M:
630 setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
631 setAttributeItem(THUMB_ISA_use, Allowed, false);
632 break;
633
634 case ARM::ARMV7:
635 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
636 break;
637
638 case ARM::ARMV7A:
639 setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
640 setAttributeItem(ARM_ISA_use, Allowed, false);
641 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
642 break;
643
644 case ARM::ARMV7R:
645 setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
646 setAttributeItem(ARM_ISA_use, Allowed, false);
647 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
648 break;
649
650 case ARM::ARMV7M:
651 setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
652 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
653 break;
654
655 case ARM::ARMV8A:
656 setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
657 setAttributeItem(ARM_ISA_use, Allowed, false);
658 setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
659 setAttributeItem(MPextension_use, Allowed, false);
660 setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
661 break;
662
663 case ARM::IWMMXT:
664 setAttributeItem(ARM_ISA_use, Allowed, false);
665 setAttributeItem(THUMB_ISA_use, Allowed, false);
666 setAttributeItem(WMMX_arch, AllowWMMXv1, false);
667 break;
668
669 case ARM::IWMMXT2:
670 setAttributeItem(ARM_ISA_use, Allowed, false);
671 setAttributeItem(THUMB_ISA_use, Allowed, false);
672 setAttributeItem(WMMX_arch, AllowWMMXv2, false);
673 break;
674
675 default:
676 report_fatal_error("Unknown Arch: " + Twine(Arch));
677 break;
678 }
679}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000680void ARMTargetELFStreamer::emitFPU(unsigned Value) {
681 FPU = Value;
682}
683void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
684 switch (FPU) {
685 case ARM::VFP:
686 case ARM::VFPV2:
Logan Chiena39510a2013-12-18 17:23:15 +0000687 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000688 ARMBuildAttrs::AllowFPv2,
689 /* OverwriteExisting= */ false);
690 break;
691
692 case ARM::VFPV3:
Logan Chiena39510a2013-12-18 17:23:15 +0000693 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000694 ARMBuildAttrs::AllowFPv3A,
695 /* OverwriteExisting= */ false);
696 break;
697
698 case ARM::VFPV3_D16:
Logan Chiena39510a2013-12-18 17:23:15 +0000699 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000700 ARMBuildAttrs::AllowFPv3B,
701 /* OverwriteExisting= */ false);
702 break;
703
704 case ARM::VFPV4:
Logan Chiena39510a2013-12-18 17:23:15 +0000705 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000706 ARMBuildAttrs::AllowFPv4A,
707 /* OverwriteExisting= */ false);
708 break;
709
710 case ARM::VFPV4_D16:
Logan Chiena39510a2013-12-18 17:23:15 +0000711 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000712 ARMBuildAttrs::AllowFPv4B,
713 /* OverwriteExisting= */ false);
714 break;
715
716 case ARM::FP_ARMV8:
Logan Chiena39510a2013-12-18 17:23:15 +0000717 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000718 ARMBuildAttrs::AllowFPARMv8A,
719 /* OverwriteExisting= */ false);
720 break;
721
722 case ARM::NEON:
Logan Chiena39510a2013-12-18 17:23:15 +0000723 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000724 ARMBuildAttrs::AllowFPv3A,
725 /* OverwriteExisting= */ false);
726 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
727 ARMBuildAttrs::AllowNeon,
728 /* OverwriteExisting= */ false);
729 break;
730
731 case ARM::NEON_VFPV4:
Logan Chiena39510a2013-12-18 17:23:15 +0000732 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000733 ARMBuildAttrs::AllowFPv4A,
734 /* OverwriteExisting= */ false);
735 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
736 ARMBuildAttrs::AllowNeon2,
737 /* OverwriteExisting= */ false);
738 break;
739
740 case ARM::NEON_FP_ARMV8:
741 case ARM::CRYPTO_NEON_FP_ARMV8:
Logan Chiena39510a2013-12-18 17:23:15 +0000742 setAttributeItem(ARMBuildAttrs::FP_arch,
Logan Chien8cbb80d2013-10-28 17:51:12 +0000743 ARMBuildAttrs::AllowFPARMv8A,
744 /* OverwriteExisting= */ false);
745 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
746 ARMBuildAttrs::AllowNeonARMv8,
747 /* OverwriteExisting= */ false);
748 break;
749
Logan Chien05ae7442014-01-02 15:50:02 +0000750 case ARM::SOFTVFP:
751 break;
752
Logan Chien8cbb80d2013-10-28 17:51:12 +0000753 default:
754 report_fatal_error("Unknown FPU: " + Twine(FPU));
755 break;
756 }
757}
758size_t ARMTargetELFStreamer::calculateContentSize() const {
759 size_t Result = 0;
760 for (size_t i = 0; i < Contents.size(); ++i) {
761 AttributeItem item = Contents[i];
762 switch (item.Type) {
763 case AttributeItem::HiddenAttribute:
764 break;
765 case AttributeItem::NumericAttribute:
766 Result += getULEBSize(item.Tag);
767 Result += getULEBSize(item.IntValue);
768 break;
769 case AttributeItem::TextAttribute:
770 Result += getULEBSize(item.Tag);
771 Result += item.StringValue.size() + 1; // string + '\0'
772 break;
773 }
774 }
775 return Result;
776}
777void ARMTargetELFStreamer::finishAttributeSection() {
778 // <format-version>
779 // [ <section-length> "vendor-name"
780 // [ <file-tag> <size> <attribute>*
781 // | <section-tag> <size> <section-number>* 0 <attribute>*
782 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
783 // ]+
784 // ]*
785
786 if (FPU != ARM::INVALID_FPU)
787 emitFPUDefaultAttributes();
788
Logan Chien439e8f92013-12-11 17:16:25 +0000789 if (Arch != ARM::INVALID_ARCH)
790 emitArchDefaultAttributes();
791
Logan Chien8cbb80d2013-10-28 17:51:12 +0000792 if (Contents.empty())
793 return;
794
795 std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
796
797 ARMELFStreamer &Streamer = getStreamer();
798
799 // Switch to .ARM.attributes section
800 if (AttributeSection) {
801 Streamer.SwitchSection(AttributeSection);
802 } else {
803 AttributeSection =
804 Streamer.getContext().getELFSection(".ARM.attributes",
805 ELF::SHT_ARM_ATTRIBUTES,
806 0,
807 SectionKind::getMetadata());
808 Streamer.SwitchSection(AttributeSection);
809
810 // Format version
811 Streamer.EmitIntValue(0x41, 1);
812 }
813
814 // Vendor size + Vendor name + '\0'
815 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
816
817 // Tag + Tag Size
818 const size_t TagHeaderSize = 1 + 4;
819
820 const size_t ContentsSize = calculateContentSize();
821
822 Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
823 Streamer.EmitBytes(CurrentVendor);
824 Streamer.EmitIntValue(0, 1); // '\0'
825
826 Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
827 Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
828
829 // Size should have been accounted for already, now
830 // emit each field as its type (ULEB or String)
831 for (size_t i = 0; i < Contents.size(); ++i) {
832 AttributeItem item = Contents[i];
833 Streamer.EmitULEB128IntValue(item.Tag);
834 switch (item.Type) {
835 default: llvm_unreachable("Invalid attribute type");
836 case AttributeItem::NumericAttribute:
837 Streamer.EmitULEB128IntValue(item.IntValue);
838 break;
839 case AttributeItem::TextAttribute:
840 Streamer.EmitBytes(item.StringValue.upper());
841 Streamer.EmitIntValue(0, 1); // '\0'
842 break;
843 }
844 }
845
846 Contents.clear();
847 FPU = ARM::INVALID_FPU;
848}
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000849void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
850 getStreamer().emitInst(Inst, Suffix);
851}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000852
853void ARMELFStreamer::FinishImpl() {
854 MCTargetStreamer &TS = getTargetStreamer();
855 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
856 ATS.finishAttributeSection();
857
858 MCELFStreamer::FinishImpl();
859}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000860
Logan Chien2bcc42c2013-01-30 15:39:04 +0000861inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
862 unsigned Type,
863 unsigned Flags,
864 SectionKind Kind,
865 const MCSymbol &Fn) {
866 const MCSectionELF &FnSection =
867 static_cast<const MCSectionELF &>(Fn.getSection());
868
869 // Create the name for new section
870 StringRef FnSecName(FnSection.getSectionName());
871 SmallString<128> EHSecName(Prefix);
872 if (FnSecName != ".text") {
873 EHSecName += FnSecName;
874 }
875
876 // Get .ARM.extab or .ARM.exidx section
877 const MCSectionELF *EHSection = NULL;
878 if (const MCSymbol *Group = FnSection.getGroup()) {
879 EHSection = getContext().getELFSection(
880 EHSecName, Type, Flags | ELF::SHF_GROUP, Kind,
881 FnSection.getEntrySize(), Group->getName());
882 } else {
883 EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);
884 }
Logan Chiend8bb4b72013-04-16 12:02:21 +0000885 assert(EHSection && "Failed to get the required EH section");
Logan Chien2bcc42c2013-01-30 15:39:04 +0000886
887 // Switch to .ARM.extab or .ARM.exidx section
888 SwitchSection(EHSection);
889 EmitCodeAlignment(4, 0);
890}
891
892inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
893 SwitchToEHSection(".ARM.extab",
894 ELF::SHT_PROGBITS,
895 ELF::SHF_ALLOC,
896 SectionKind::getDataRel(),
897 FnStart);
898}
899
900inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
901 SwitchToEHSection(".ARM.exidx",
902 ELF::SHT_ARM_EXIDX,
903 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
904 SectionKind::getDataRel(),
905 FnStart);
906}
907
908void ARMELFStreamer::Reset() {
909 ExTab = NULL;
910 FnStart = NULL;
911 Personality = NULL;
Logan Chien325823a2013-06-09 12:22:30 +0000912 PersonalityIndex = NUM_PERSONALITY_INDEX;
913 FPReg = ARM::SP;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000914 FPOffset = 0;
915 SPOffset = 0;
Logan Chien325823a2013-06-09 12:22:30 +0000916 PendingOffset = 0;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000917 UsedFP = false;
Logan Chien2bcc42c2013-01-30 15:39:04 +0000918 CantUnwind = false;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000919
Logan Chien325823a2013-06-09 12:22:30 +0000920 Opcodes.clear();
Logan Chiend8bb4b72013-04-16 12:02:21 +0000921 UnwindOpAsm.Reset();
Logan Chien2bcc42c2013-01-30 15:39:04 +0000922}
923
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000924void ARMELFStreamer::emitFnStart() {
Logan Chien2bcc42c2013-01-30 15:39:04 +0000925 assert(FnStart == 0);
926 FnStart = getContext().CreateTempSymbol();
927 EmitLabel(FnStart);
928}
929
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000930void ARMELFStreamer::emitFnEnd() {
Logan Chien2bcc42c2013-01-30 15:39:04 +0000931 assert(FnStart && ".fnstart must preceeds .fnend");
932
933 // Emit unwind opcodes if there is no .handlerdata directive
Logan Chien4ea23b52013-05-10 16:17:24 +0000934 if (!ExTab && !CantUnwind)
935 FlushUnwindOpcodes(true);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000936
937 // Emit the exception index table entry
938 SwitchToExIdxSection(*FnStart);
939
Logan Chiend8bb4b72013-04-16 12:02:21 +0000940 if (PersonalityIndex < NUM_PERSONALITY_INDEX)
941 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
Logan Chien2bcc42c2013-01-30 15:39:04 +0000942
943 const MCSymbolRefExpr *FnStartRef =
944 MCSymbolRefExpr::Create(FnStart,
945 MCSymbolRefExpr::VK_ARM_PREL31,
946 getContext());
947
Rafael Espindola64e1af82013-07-02 15:49:13 +0000948 EmitValue(FnStartRef, 4);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000949
950 if (CantUnwind) {
Rafael Espindola64e1af82013-07-02 15:49:13 +0000951 EmitIntValue(EXIDX_CANTUNWIND, 4);
Logan Chiend8bb4b72013-04-16 12:02:21 +0000952 } else if (ExTab) {
953 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
Logan Chien2bcc42c2013-01-30 15:39:04 +0000954 const MCSymbolRefExpr *ExTabEntryRef =
955 MCSymbolRefExpr::Create(ExTab,
956 MCSymbolRefExpr::VK_ARM_PREL31,
957 getContext());
Rafael Espindola64e1af82013-07-02 15:49:13 +0000958 EmitValue(ExTabEntryRef, 4);
Logan Chiend8bb4b72013-04-16 12:02:21 +0000959 } else {
960 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
961 // the second word of exception index table entry. The size of the unwind
962 // opcodes should always be 4 bytes.
963 assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 &&
964 "Compact model must use __aeabi_cpp_unwind_pr0 as personality");
Logan Chien325823a2013-06-09 12:22:30 +0000965 assert(Opcodes.size() == 4u &&
Logan Chiend8bb4b72013-04-16 12:02:21 +0000966 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");
Logan Chien325823a2013-06-09 12:22:30 +0000967 EmitBytes(StringRef(reinterpret_cast<const char*>(Opcodes.data()),
Rafael Espindola64e1af82013-07-02 15:49:13 +0000968 Opcodes.size()));
Logan Chien2bcc42c2013-01-30 15:39:04 +0000969 }
970
Logan Chien4ea23b52013-05-10 16:17:24 +0000971 // Switch to the section containing FnStart
972 SwitchSection(&FnStart->getSection());
973
Logan Chien2bcc42c2013-01-30 15:39:04 +0000974 // Clean exception handling frame information
975 Reset();
976}
977
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000978void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
979
980// Add the R_ARM_NONE fixup at the same position
981void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
982 const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
983
984 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create(
985 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
986
987 AddValueSymbols(PersonalityRef);
988 MCDataFragment *DF = getOrCreateDataFragment();
989 DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
990 PersonalityRef,
991 MCFixup::getKindForSize(4, false)));
Logan Chien2bcc42c2013-01-30 15:39:04 +0000992}
993
Logan Chien325823a2013-06-09 12:22:30 +0000994void ARMELFStreamer::FlushPendingOffset() {
995 if (PendingOffset != 0) {
996 UnwindOpAsm.EmitSPOffset(-PendingOffset);
997 PendingOffset = 0;
998 }
999}
1000
Logan Chienc931fce2013-07-02 12:43:27 +00001001void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
Logan Chien325823a2013-06-09 12:22:30 +00001002 // Emit the unwind opcode to restore $sp.
1003 if (UsedFP) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001004 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
Logan Chien325823a2013-06-09 12:22:30 +00001005 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1006 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
Bill Wendlingbc07a892013-06-18 07:20:20 +00001007 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
Logan Chien325823a2013-06-09 12:22:30 +00001008 } else {
1009 FlushPendingOffset();
1010 }
1011
1012 // Finalize the unwind opcode sequence
1013 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
Logan Chien4ea23b52013-05-10 16:17:24 +00001014
1015 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1016 // section. Thus, we don't have to create an entry in the .ARM.extab
1017 // section.
Logan Chienc931fce2013-07-02 12:43:27 +00001018 if (NoHandlerData && PersonalityIndex == AEABI_UNWIND_CPP_PR0)
Logan Chien4ea23b52013-05-10 16:17:24 +00001019 return;
1020
1021 // Switch to .ARM.extab section.
Logan Chien2bcc42c2013-01-30 15:39:04 +00001022 SwitchToExTabSection(*FnStart);
1023
1024 // Create .ARM.extab label for offset in .ARM.exidx
1025 assert(!ExTab);
1026 ExTab = getContext().CreateTempSymbol();
1027 EmitLabel(ExTab);
1028
Logan Chien4ea23b52013-05-10 16:17:24 +00001029 // Emit personality
1030 if (Personality) {
1031 const MCSymbolRefExpr *PersonalityRef =
1032 MCSymbolRefExpr::Create(Personality,
1033 MCSymbolRefExpr::VK_ARM_PREL31,
1034 getContext());
Logan Chien2bcc42c2013-01-30 15:39:04 +00001035
Rafael Espindola64e1af82013-07-02 15:49:13 +00001036 EmitValue(PersonalityRef, 4);
Logan Chien4ea23b52013-05-10 16:17:24 +00001037 }
Logan Chien2bcc42c2013-01-30 15:39:04 +00001038
1039 // Emit unwind opcodes
Logan Chien325823a2013-06-09 12:22:30 +00001040 EmitBytes(StringRef(reinterpret_cast<const char *>(Opcodes.data()),
Rafael Espindola64e1af82013-07-02 15:49:13 +00001041 Opcodes.size()));
Logan Chienc931fce2013-07-02 12:43:27 +00001042
1043 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1044 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1045 // after the unwind opcodes. The handler data consists of several 32-bit
1046 // words, and should be terminated by zero.
1047 //
1048 // In case that the .handlerdata directive is not specified by the
1049 // programmer, we should emit zero to terminate the handler data.
1050 if (NoHandlerData && !Personality)
1051 EmitIntValue(0, 4);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001052}
1053
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001054void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
Logan Chien4ea23b52013-05-10 16:17:24 +00001055
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001056void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
Logan Chien2bcc42c2013-01-30 15:39:04 +00001057 Personality = Per;
Logan Chiend8bb4b72013-04-16 12:02:21 +00001058 UnwindOpAsm.setPersonality(Per);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001059}
1060
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001061void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001062 int64_t Offset) {
Logan Chien325823a2013-06-09 12:22:30 +00001063 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
Logan Chiend8bb4b72013-04-16 12:02:21 +00001064 "the operand of .setfp directive should be either $sp or $fp");
1065
1066 UsedFP = true;
Logan Chien325823a2013-06-09 12:22:30 +00001067 FPReg = NewFPReg;
1068
1069 if (NewSPReg == ARM::SP)
1070 FPOffset = SPOffset + Offset;
1071 else
1072 FPOffset += Offset;
Logan Chien2bcc42c2013-01-30 15:39:04 +00001073}
1074
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001075void ARMELFStreamer::emitPad(int64_t Offset) {
Logan Chien325823a2013-06-09 12:22:30 +00001076 // Track the change of the $sp offset
1077 SPOffset -= Offset;
1078
1079 // To squash multiple .pad directives, we should delay the unwind opcode
1080 // until the .save, .vsave, .handlerdata, or .fnend directives.
1081 PendingOffset -= Offset;
Logan Chien2bcc42c2013-01-30 15:39:04 +00001082}
1083
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001084void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001085 bool IsVector) {
Logan Chien325823a2013-06-09 12:22:30 +00001086 // Collect the registers in the register list
1087 unsigned Count = 0;
1088 uint32_t Mask = 0;
Bill Wendlingbc07a892013-06-18 07:20:20 +00001089 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
Logan Chiend8bb4b72013-04-16 12:02:21 +00001090 for (size_t i = 0; i < RegList.size(); ++i) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001091 unsigned Reg = MRI->getEncodingValue(RegList[i]);
Aaron Ballmanab1d27e2013-06-10 16:45:40 +00001092 assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
Logan Chien325823a2013-06-09 12:22:30 +00001093 unsigned Bit = (1u << Reg);
1094 if ((Mask & Bit) == 0) {
1095 Mask |= Bit;
1096 ++Count;
1097 }
Logan Chiend8bb4b72013-04-16 12:02:21 +00001098 }
Logan Chien325823a2013-06-09 12:22:30 +00001099
1100 // Track the change the $sp offset: For the .save directive, the
1101 // corresponding push instruction will decrease the $sp by (4 * Count).
1102 // For the .vsave directive, the corresponding vpush instruction will
1103 // decrease $sp by (8 * Count).
1104 SPOffset -= Count * (IsVector ? 8 : 4);
1105
1106 // Emit the opcode
1107 FlushPendingOffset();
1108 if (IsVector)
1109 UnwindOpAsm.EmitVFPRegSave(Mask);
1110 else
1111 UnwindOpAsm.EmitRegSave(Mask);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001112}
1113
Tim Northover5cc3dc82012-12-07 16:50:23 +00001114namespace llvm {
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001115
1116MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
1117 bool isVerboseAsm, bool useLoc, bool useCFI,
1118 bool useDwarfDirectory,
1119 MCInstPrinter *InstPrint, MCCodeEmitter *CE,
1120 MCAsmBackend *TAB, bool ShowInst) {
1121 ARMTargetAsmStreamer *S = new ARMTargetAsmStreamer(OS, *InstPrint);
1122
1123 return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
1124 useDwarfDirectory, InstPrint, CE, TAB,
1125 ShowInst);
1126}
1127
Tim Northover5cc3dc82012-12-07 16:50:23 +00001128 MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
1129 raw_ostream &OS, MCCodeEmitter *Emitter,
1130 bool RelaxAll, bool NoExecStack,
1131 bool IsThumb) {
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001132 ARMTargetELFStreamer *TS = new ARMTargetELFStreamer();
1133 ARMELFStreamer *S =
1134 new ARMELFStreamer(Context, TS, TAB, OS, Emitter, IsThumb);
Rafael Espindolaac4ad252013-10-05 16:42:21 +00001135 // FIXME: This should eventually end up somewhere else where more
1136 // intelligent flag decisions can be made. For now we are just maintaining
1137 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1138 S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1139
Tim Northover5cc3dc82012-12-07 16:50:23 +00001140 if (RelaxAll)
1141 S->getAssembler().setRelaxAll(true);
1142 if (NoExecStack)
1143 S->getAssembler().setNoExecStack(true);
1144 return S;
1145 }
1146
1147}
1148
1149