blob: 39bcbf3e529ae282129d9e2412e5142cd5eedd6f [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
750 default:
751 report_fatal_error("Unknown FPU: " + Twine(FPU));
752 break;
753 }
754}
755size_t ARMTargetELFStreamer::calculateContentSize() const {
756 size_t Result = 0;
757 for (size_t i = 0; i < Contents.size(); ++i) {
758 AttributeItem item = Contents[i];
759 switch (item.Type) {
760 case AttributeItem::HiddenAttribute:
761 break;
762 case AttributeItem::NumericAttribute:
763 Result += getULEBSize(item.Tag);
764 Result += getULEBSize(item.IntValue);
765 break;
766 case AttributeItem::TextAttribute:
767 Result += getULEBSize(item.Tag);
768 Result += item.StringValue.size() + 1; // string + '\0'
769 break;
770 }
771 }
772 return Result;
773}
774void ARMTargetELFStreamer::finishAttributeSection() {
775 // <format-version>
776 // [ <section-length> "vendor-name"
777 // [ <file-tag> <size> <attribute>*
778 // | <section-tag> <size> <section-number>* 0 <attribute>*
779 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
780 // ]+
781 // ]*
782
783 if (FPU != ARM::INVALID_FPU)
784 emitFPUDefaultAttributes();
785
Logan Chien439e8f92013-12-11 17:16:25 +0000786 if (Arch != ARM::INVALID_ARCH)
787 emitArchDefaultAttributes();
788
Logan Chien8cbb80d2013-10-28 17:51:12 +0000789 if (Contents.empty())
790 return;
791
792 std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
793
794 ARMELFStreamer &Streamer = getStreamer();
795
796 // Switch to .ARM.attributes section
797 if (AttributeSection) {
798 Streamer.SwitchSection(AttributeSection);
799 } else {
800 AttributeSection =
801 Streamer.getContext().getELFSection(".ARM.attributes",
802 ELF::SHT_ARM_ATTRIBUTES,
803 0,
804 SectionKind::getMetadata());
805 Streamer.SwitchSection(AttributeSection);
806
807 // Format version
808 Streamer.EmitIntValue(0x41, 1);
809 }
810
811 // Vendor size + Vendor name + '\0'
812 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
813
814 // Tag + Tag Size
815 const size_t TagHeaderSize = 1 + 4;
816
817 const size_t ContentsSize = calculateContentSize();
818
819 Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
820 Streamer.EmitBytes(CurrentVendor);
821 Streamer.EmitIntValue(0, 1); // '\0'
822
823 Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
824 Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
825
826 // Size should have been accounted for already, now
827 // emit each field as its type (ULEB or String)
828 for (size_t i = 0; i < Contents.size(); ++i) {
829 AttributeItem item = Contents[i];
830 Streamer.EmitULEB128IntValue(item.Tag);
831 switch (item.Type) {
832 default: llvm_unreachable("Invalid attribute type");
833 case AttributeItem::NumericAttribute:
834 Streamer.EmitULEB128IntValue(item.IntValue);
835 break;
836 case AttributeItem::TextAttribute:
837 Streamer.EmitBytes(item.StringValue.upper());
838 Streamer.EmitIntValue(0, 1); // '\0'
839 break;
840 }
841 }
842
843 Contents.clear();
844 FPU = ARM::INVALID_FPU;
845}
Saleem Abdulrasoolc0da2cb2013-12-19 05:17:58 +0000846void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
847 getStreamer().emitInst(Inst, Suffix);
848}
Logan Chien8cbb80d2013-10-28 17:51:12 +0000849
850void ARMELFStreamer::FinishImpl() {
851 MCTargetStreamer &TS = getTargetStreamer();
852 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
853 ATS.finishAttributeSection();
854
855 MCELFStreamer::FinishImpl();
856}
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000857
Logan Chien2bcc42c2013-01-30 15:39:04 +0000858inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
859 unsigned Type,
860 unsigned Flags,
861 SectionKind Kind,
862 const MCSymbol &Fn) {
863 const MCSectionELF &FnSection =
864 static_cast<const MCSectionELF &>(Fn.getSection());
865
866 // Create the name for new section
867 StringRef FnSecName(FnSection.getSectionName());
868 SmallString<128> EHSecName(Prefix);
869 if (FnSecName != ".text") {
870 EHSecName += FnSecName;
871 }
872
873 // Get .ARM.extab or .ARM.exidx section
874 const MCSectionELF *EHSection = NULL;
875 if (const MCSymbol *Group = FnSection.getGroup()) {
876 EHSection = getContext().getELFSection(
877 EHSecName, Type, Flags | ELF::SHF_GROUP, Kind,
878 FnSection.getEntrySize(), Group->getName());
879 } else {
880 EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);
881 }
Logan Chiend8bb4b72013-04-16 12:02:21 +0000882 assert(EHSection && "Failed to get the required EH section");
Logan Chien2bcc42c2013-01-30 15:39:04 +0000883
884 // Switch to .ARM.extab or .ARM.exidx section
885 SwitchSection(EHSection);
886 EmitCodeAlignment(4, 0);
887}
888
889inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
890 SwitchToEHSection(".ARM.extab",
891 ELF::SHT_PROGBITS,
892 ELF::SHF_ALLOC,
893 SectionKind::getDataRel(),
894 FnStart);
895}
896
897inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
898 SwitchToEHSection(".ARM.exidx",
899 ELF::SHT_ARM_EXIDX,
900 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
901 SectionKind::getDataRel(),
902 FnStart);
903}
904
905void ARMELFStreamer::Reset() {
906 ExTab = NULL;
907 FnStart = NULL;
908 Personality = NULL;
Logan Chien325823a2013-06-09 12:22:30 +0000909 PersonalityIndex = NUM_PERSONALITY_INDEX;
910 FPReg = ARM::SP;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000911 FPOffset = 0;
912 SPOffset = 0;
Logan Chien325823a2013-06-09 12:22:30 +0000913 PendingOffset = 0;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000914 UsedFP = false;
Logan Chien2bcc42c2013-01-30 15:39:04 +0000915 CantUnwind = false;
Logan Chiend8bb4b72013-04-16 12:02:21 +0000916
Logan Chien325823a2013-06-09 12:22:30 +0000917 Opcodes.clear();
Logan Chiend8bb4b72013-04-16 12:02:21 +0000918 UnwindOpAsm.Reset();
Logan Chien2bcc42c2013-01-30 15:39:04 +0000919}
920
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000921void ARMELFStreamer::emitFnStart() {
Logan Chien2bcc42c2013-01-30 15:39:04 +0000922 assert(FnStart == 0);
923 FnStart = getContext().CreateTempSymbol();
924 EmitLabel(FnStart);
925}
926
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000927void ARMELFStreamer::emitFnEnd() {
Logan Chien2bcc42c2013-01-30 15:39:04 +0000928 assert(FnStart && ".fnstart must preceeds .fnend");
929
930 // Emit unwind opcodes if there is no .handlerdata directive
Logan Chien4ea23b52013-05-10 16:17:24 +0000931 if (!ExTab && !CantUnwind)
932 FlushUnwindOpcodes(true);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000933
934 // Emit the exception index table entry
935 SwitchToExIdxSection(*FnStart);
936
Logan Chiend8bb4b72013-04-16 12:02:21 +0000937 if (PersonalityIndex < NUM_PERSONALITY_INDEX)
938 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
Logan Chien2bcc42c2013-01-30 15:39:04 +0000939
940 const MCSymbolRefExpr *FnStartRef =
941 MCSymbolRefExpr::Create(FnStart,
942 MCSymbolRefExpr::VK_ARM_PREL31,
943 getContext());
944
Rafael Espindola64e1af82013-07-02 15:49:13 +0000945 EmitValue(FnStartRef, 4);
Logan Chien2bcc42c2013-01-30 15:39:04 +0000946
947 if (CantUnwind) {
Rafael Espindola64e1af82013-07-02 15:49:13 +0000948 EmitIntValue(EXIDX_CANTUNWIND, 4);
Logan Chiend8bb4b72013-04-16 12:02:21 +0000949 } else if (ExTab) {
950 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
Logan Chien2bcc42c2013-01-30 15:39:04 +0000951 const MCSymbolRefExpr *ExTabEntryRef =
952 MCSymbolRefExpr::Create(ExTab,
953 MCSymbolRefExpr::VK_ARM_PREL31,
954 getContext());
Rafael Espindola64e1af82013-07-02 15:49:13 +0000955 EmitValue(ExTabEntryRef, 4);
Logan Chiend8bb4b72013-04-16 12:02:21 +0000956 } else {
957 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
958 // the second word of exception index table entry. The size of the unwind
959 // opcodes should always be 4 bytes.
960 assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 &&
961 "Compact model must use __aeabi_cpp_unwind_pr0 as personality");
Logan Chien325823a2013-06-09 12:22:30 +0000962 assert(Opcodes.size() == 4u &&
Logan Chiend8bb4b72013-04-16 12:02:21 +0000963 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");
Logan Chien325823a2013-06-09 12:22:30 +0000964 EmitBytes(StringRef(reinterpret_cast<const char*>(Opcodes.data()),
Rafael Espindola64e1af82013-07-02 15:49:13 +0000965 Opcodes.size()));
Logan Chien2bcc42c2013-01-30 15:39:04 +0000966 }
967
Logan Chien4ea23b52013-05-10 16:17:24 +0000968 // Switch to the section containing FnStart
969 SwitchSection(&FnStart->getSection());
970
Logan Chien2bcc42c2013-01-30 15:39:04 +0000971 // Clean exception handling frame information
972 Reset();
973}
974
Rafael Espindolaa17151a2013-10-08 13:08:17 +0000975void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
976
977// Add the R_ARM_NONE fixup at the same position
978void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
979 const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
980
981 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create(
982 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
983
984 AddValueSymbols(PersonalityRef);
985 MCDataFragment *DF = getOrCreateDataFragment();
986 DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
987 PersonalityRef,
988 MCFixup::getKindForSize(4, false)));
Logan Chien2bcc42c2013-01-30 15:39:04 +0000989}
990
Logan Chien325823a2013-06-09 12:22:30 +0000991void ARMELFStreamer::FlushPendingOffset() {
992 if (PendingOffset != 0) {
993 UnwindOpAsm.EmitSPOffset(-PendingOffset);
994 PendingOffset = 0;
995 }
996}
997
Logan Chienc931fce2013-07-02 12:43:27 +0000998void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
Logan Chien325823a2013-06-09 12:22:30 +0000999 // Emit the unwind opcode to restore $sp.
1000 if (UsedFP) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001001 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
Logan Chien325823a2013-06-09 12:22:30 +00001002 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1003 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
Bill Wendlingbc07a892013-06-18 07:20:20 +00001004 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
Logan Chien325823a2013-06-09 12:22:30 +00001005 } else {
1006 FlushPendingOffset();
1007 }
1008
1009 // Finalize the unwind opcode sequence
1010 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
Logan Chien4ea23b52013-05-10 16:17:24 +00001011
1012 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1013 // section. Thus, we don't have to create an entry in the .ARM.extab
1014 // section.
Logan Chienc931fce2013-07-02 12:43:27 +00001015 if (NoHandlerData && PersonalityIndex == AEABI_UNWIND_CPP_PR0)
Logan Chien4ea23b52013-05-10 16:17:24 +00001016 return;
1017
1018 // Switch to .ARM.extab section.
Logan Chien2bcc42c2013-01-30 15:39:04 +00001019 SwitchToExTabSection(*FnStart);
1020
1021 // Create .ARM.extab label for offset in .ARM.exidx
1022 assert(!ExTab);
1023 ExTab = getContext().CreateTempSymbol();
1024 EmitLabel(ExTab);
1025
Logan Chien4ea23b52013-05-10 16:17:24 +00001026 // Emit personality
1027 if (Personality) {
1028 const MCSymbolRefExpr *PersonalityRef =
1029 MCSymbolRefExpr::Create(Personality,
1030 MCSymbolRefExpr::VK_ARM_PREL31,
1031 getContext());
Logan Chien2bcc42c2013-01-30 15:39:04 +00001032
Rafael Espindola64e1af82013-07-02 15:49:13 +00001033 EmitValue(PersonalityRef, 4);
Logan Chien4ea23b52013-05-10 16:17:24 +00001034 }
Logan Chien2bcc42c2013-01-30 15:39:04 +00001035
1036 // Emit unwind opcodes
Logan Chien325823a2013-06-09 12:22:30 +00001037 EmitBytes(StringRef(reinterpret_cast<const char *>(Opcodes.data()),
Rafael Espindola64e1af82013-07-02 15:49:13 +00001038 Opcodes.size()));
Logan Chienc931fce2013-07-02 12:43:27 +00001039
1040 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1041 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1042 // after the unwind opcodes. The handler data consists of several 32-bit
1043 // words, and should be terminated by zero.
1044 //
1045 // In case that the .handlerdata directive is not specified by the
1046 // programmer, we should emit zero to terminate the handler data.
1047 if (NoHandlerData && !Personality)
1048 EmitIntValue(0, 4);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001049}
1050
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001051void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
Logan Chien4ea23b52013-05-10 16:17:24 +00001052
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001053void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
Logan Chien2bcc42c2013-01-30 15:39:04 +00001054 Personality = Per;
Logan Chiend8bb4b72013-04-16 12:02:21 +00001055 UnwindOpAsm.setPersonality(Per);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001056}
1057
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001058void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001059 int64_t Offset) {
Logan Chien325823a2013-06-09 12:22:30 +00001060 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
Logan Chiend8bb4b72013-04-16 12:02:21 +00001061 "the operand of .setfp directive should be either $sp or $fp");
1062
1063 UsedFP = true;
Logan Chien325823a2013-06-09 12:22:30 +00001064 FPReg = NewFPReg;
1065
1066 if (NewSPReg == ARM::SP)
1067 FPOffset = SPOffset + Offset;
1068 else
1069 FPOffset += Offset;
Logan Chien2bcc42c2013-01-30 15:39:04 +00001070}
1071
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001072void ARMELFStreamer::emitPad(int64_t Offset) {
Logan Chien325823a2013-06-09 12:22:30 +00001073 // Track the change of the $sp offset
1074 SPOffset -= Offset;
1075
1076 // To squash multiple .pad directives, we should delay the unwind opcode
1077 // until the .save, .vsave, .handlerdata, or .fnend directives.
1078 PendingOffset -= Offset;
Logan Chien2bcc42c2013-01-30 15:39:04 +00001079}
1080
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001081void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
Logan Chien2bcc42c2013-01-30 15:39:04 +00001082 bool IsVector) {
Logan Chien325823a2013-06-09 12:22:30 +00001083 // Collect the registers in the register list
1084 unsigned Count = 0;
1085 uint32_t Mask = 0;
Bill Wendlingbc07a892013-06-18 07:20:20 +00001086 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
Logan Chiend8bb4b72013-04-16 12:02:21 +00001087 for (size_t i = 0; i < RegList.size(); ++i) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001088 unsigned Reg = MRI->getEncodingValue(RegList[i]);
Aaron Ballmanab1d27e2013-06-10 16:45:40 +00001089 assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
Logan Chien325823a2013-06-09 12:22:30 +00001090 unsigned Bit = (1u << Reg);
1091 if ((Mask & Bit) == 0) {
1092 Mask |= Bit;
1093 ++Count;
1094 }
Logan Chiend8bb4b72013-04-16 12:02:21 +00001095 }
Logan Chien325823a2013-06-09 12:22:30 +00001096
1097 // Track the change the $sp offset: For the .save directive, the
1098 // corresponding push instruction will decrease the $sp by (4 * Count).
1099 // For the .vsave directive, the corresponding vpush instruction will
1100 // decrease $sp by (8 * Count).
1101 SPOffset -= Count * (IsVector ? 8 : 4);
1102
1103 // Emit the opcode
1104 FlushPendingOffset();
1105 if (IsVector)
1106 UnwindOpAsm.EmitVFPRegSave(Mask);
1107 else
1108 UnwindOpAsm.EmitRegSave(Mask);
Logan Chien2bcc42c2013-01-30 15:39:04 +00001109}
1110
Tim Northover5cc3dc82012-12-07 16:50:23 +00001111namespace llvm {
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001112
1113MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
1114 bool isVerboseAsm, bool useLoc, bool useCFI,
1115 bool useDwarfDirectory,
1116 MCInstPrinter *InstPrint, MCCodeEmitter *CE,
1117 MCAsmBackend *TAB, bool ShowInst) {
1118 ARMTargetAsmStreamer *S = new ARMTargetAsmStreamer(OS, *InstPrint);
1119
1120 return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
1121 useDwarfDirectory, InstPrint, CE, TAB,
1122 ShowInst);
1123}
1124
Tim Northover5cc3dc82012-12-07 16:50:23 +00001125 MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
1126 raw_ostream &OS, MCCodeEmitter *Emitter,
1127 bool RelaxAll, bool NoExecStack,
1128 bool IsThumb) {
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001129 ARMTargetELFStreamer *TS = new ARMTargetELFStreamer();
1130 ARMELFStreamer *S =
1131 new ARMELFStreamer(Context, TS, TAB, OS, Emitter, IsThumb);
Rafael Espindolaac4ad252013-10-05 16:42:21 +00001132 // FIXME: This should eventually end up somewhere else where more
1133 // intelligent flag decisions can be made. For now we are just maintaining
1134 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1135 S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1136
Tim Northover5cc3dc82012-12-07 16:50:23 +00001137 if (RelaxAll)
1138 S->getAssembler().setRelaxAll(true);
1139 if (NoExecStack)
1140 S->getAssembler().setNoExecStack(true);
1141 return S;
1142 }
1143
1144}
1145
1146