Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/MC/MCELFStreamer.cpp
35233 views
1
//===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file assembles .s files and emits ELF .o object files.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/MC/MCELFStreamer.h"
14
#include "llvm/ADT/SmallString.h"
15
#include "llvm/ADT/SmallVector.h"
16
#include "llvm/BinaryFormat/ELF.h"
17
#include "llvm/MC/MCAsmBackend.h"
18
#include "llvm/MC/MCAsmInfo.h"
19
#include "llvm/MC/MCAssembler.h"
20
#include "llvm/MC/MCCodeEmitter.h"
21
#include "llvm/MC/MCContext.h"
22
#include "llvm/MC/MCExpr.h"
23
#include "llvm/MC/MCFixup.h"
24
#include "llvm/MC/MCFragment.h"
25
#include "llvm/MC/MCObjectFileInfo.h"
26
#include "llvm/MC/MCObjectWriter.h"
27
#include "llvm/MC/MCSection.h"
28
#include "llvm/MC/MCSectionELF.h"
29
#include "llvm/MC/MCStreamer.h"
30
#include "llvm/MC/MCSymbol.h"
31
#include "llvm/MC/MCSymbolELF.h"
32
#include "llvm/MC/TargetRegistry.h"
33
#include "llvm/Support/Casting.h"
34
#include "llvm/Support/ErrorHandling.h"
35
#include "llvm/Support/LEB128.h"
36
#include "llvm/Support/raw_ostream.h"
37
#include <cassert>
38
#include <cstdint>
39
40
using namespace llvm;
41
42
MCELFStreamer::MCELFStreamer(MCContext &Context,
43
std::unique_ptr<MCAsmBackend> TAB,
44
std::unique_ptr<MCObjectWriter> OW,
45
std::unique_ptr<MCCodeEmitter> Emitter)
46
: MCObjectStreamer(Context, std::move(TAB), std::move(OW),
47
std::move(Emitter)) {}
48
49
ELFObjectWriter &MCELFStreamer::getWriter() {
50
return static_cast<ELFObjectWriter &>(getAssembler().getWriter());
51
}
52
53
bool MCELFStreamer::isBundleLocked() const {
54
return getCurrentSectionOnly()->isBundleLocked();
55
}
56
57
void MCELFStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
58
MCContext &Ctx = getContext();
59
switchSection(Ctx.getObjectFileInfo()->getTextSection());
60
emitCodeAlignment(Align(Ctx.getObjectFileInfo()->getTextSectionAlignment()),
61
&STI);
62
63
if (NoExecStack)
64
switchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
65
}
66
67
void MCELFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
68
auto *Symbol = cast<MCSymbolELF>(S);
69
MCObjectStreamer::emitLabel(Symbol, Loc);
70
71
const MCSectionELF &Section =
72
static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
73
if (Section.getFlags() & ELF::SHF_TLS)
74
Symbol->setType(ELF::STT_TLS);
75
}
76
77
void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F,
78
uint64_t Offset) {
79
auto *Symbol = cast<MCSymbolELF>(S);
80
MCObjectStreamer::emitLabelAtPos(Symbol, Loc, F, Offset);
81
82
const MCSectionELF &Section =
83
static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
84
if (Section.getFlags() & ELF::SHF_TLS)
85
Symbol->setType(ELF::STT_TLS);
86
}
87
88
void MCELFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
89
// Let the target do whatever target specific stuff it needs to do.
90
getAssembler().getBackend().handleAssemblerFlag(Flag);
91
}
92
93
// If bundle alignment is used and there are any instructions in the section, it
94
// needs to be aligned to at least the bundle size.
95
static void setSectionAlignmentForBundling(const MCAssembler &Assembler,
96
MCSection *Section) {
97
if (Assembler.isBundlingEnabled() && Section->hasInstructions())
98
Section->ensureMinAlignment(Align(Assembler.getBundleAlignSize()));
99
}
100
101
void MCELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
102
MCAssembler &Asm = getAssembler();
103
if (auto *F = getCurrentFragment()) {
104
if (isBundleLocked())
105
report_fatal_error("Unterminated .bundle_lock when changing a section");
106
107
// Ensure the previous section gets aligned if necessary.
108
setSectionAlignmentForBundling(Asm, F->getParent());
109
}
110
auto *SectionELF = static_cast<const MCSectionELF *>(Section);
111
const MCSymbol *Grp = SectionELF->getGroup();
112
if (Grp)
113
Asm.registerSymbol(*Grp);
114
if (SectionELF->getFlags() & ELF::SHF_GNU_RETAIN)
115
getWriter().markGnuAbi();
116
117
changeSectionImpl(Section, Subsection);
118
Asm.registerSymbol(*Section->getBeginSymbol());
119
}
120
121
void MCELFStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
122
getAssembler().registerSymbol(*Symbol);
123
const MCExpr *Value = MCSymbolRefExpr::create(
124
Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext());
125
Alias->setVariableValue(Value);
126
}
127
128
// When GNU as encounters more than one .type declaration for an object it seems
129
// to use a mechanism similar to the one below to decide which type is actually
130
// used in the object file. The greater of T1 and T2 is selected based on the
131
// following ordering:
132
// STT_NOTYPE < STT_OBJECT < STT_FUNC < STT_GNU_IFUNC < STT_TLS < anything else
133
// If neither T1 < T2 nor T2 < T1 according to this ordering, use T2 (the user
134
// provided type).
135
static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) {
136
for (unsigned Type : {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC,
137
ELF::STT_GNU_IFUNC, ELF::STT_TLS}) {
138
if (T1 == Type)
139
return T2;
140
if (T2 == Type)
141
return T1;
142
}
143
144
return T2;
145
}
146
147
bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
148
auto *Symbol = cast<MCSymbolELF>(S);
149
150
// Adding a symbol attribute always introduces the symbol, note that an
151
// important side effect of calling registerSymbol here is to register
152
// the symbol with the assembler.
153
getAssembler().registerSymbol(*Symbol);
154
155
// The implementation of symbol attributes is designed to match 'as', but it
156
// leaves much to desired. It doesn't really make sense to arbitrarily add and
157
// remove flags, but 'as' allows this (in particular, see .desc).
158
//
159
// In the future it might be worth trying to make these operations more well
160
// defined.
161
switch (Attribute) {
162
case MCSA_Cold:
163
case MCSA_Extern:
164
case MCSA_LazyReference:
165
case MCSA_Reference:
166
case MCSA_SymbolResolver:
167
case MCSA_PrivateExtern:
168
case MCSA_WeakDefinition:
169
case MCSA_WeakDefAutoPrivate:
170
case MCSA_Invalid:
171
case MCSA_IndirectSymbol:
172
case MCSA_Exported:
173
case MCSA_WeakAntiDep:
174
return false;
175
176
case MCSA_NoDeadStrip:
177
// Ignore for now.
178
break;
179
180
case MCSA_ELF_TypeGnuUniqueObject:
181
Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
182
Symbol->setBinding(ELF::STB_GNU_UNIQUE);
183
getWriter().markGnuAbi();
184
break;
185
186
case MCSA_Global:
187
// For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we
188
// traditionally set the binding to STB_GLOBAL. This is error-prone, so we
189
// error on such cases. Note, we also disallow changed binding from .local.
190
if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL)
191
getContext().reportError(getStartTokLoc(),
192
Symbol->getName() +
193
" changed binding to STB_GLOBAL");
194
Symbol->setBinding(ELF::STB_GLOBAL);
195
break;
196
197
case MCSA_WeakReference:
198
case MCSA_Weak:
199
// For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK.
200
// We emit a warning for now but may switch to an error in the future.
201
if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK)
202
getContext().reportWarning(
203
getStartTokLoc(), Symbol->getName() + " changed binding to STB_WEAK");
204
Symbol->setBinding(ELF::STB_WEAK);
205
break;
206
207
case MCSA_Local:
208
if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL)
209
getContext().reportError(getStartTokLoc(),
210
Symbol->getName() +
211
" changed binding to STB_LOCAL");
212
Symbol->setBinding(ELF::STB_LOCAL);
213
break;
214
215
case MCSA_ELF_TypeFunction:
216
Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_FUNC));
217
break;
218
219
case MCSA_ELF_TypeIndFunction:
220
Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC));
221
getWriter().markGnuAbi();
222
break;
223
224
case MCSA_ELF_TypeObject:
225
Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
226
break;
227
228
case MCSA_ELF_TypeTLS:
229
Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_TLS));
230
break;
231
232
case MCSA_ELF_TypeCommon:
233
// TODO: Emit these as a common symbol.
234
Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
235
break;
236
237
case MCSA_ELF_TypeNoType:
238
Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_NOTYPE));
239
break;
240
241
case MCSA_Protected:
242
Symbol->setVisibility(ELF::STV_PROTECTED);
243
break;
244
245
case MCSA_Memtag:
246
Symbol->setMemtag(true);
247
break;
248
249
case MCSA_Hidden:
250
Symbol->setVisibility(ELF::STV_HIDDEN);
251
break;
252
253
case MCSA_Internal:
254
Symbol->setVisibility(ELF::STV_INTERNAL);
255
break;
256
257
case MCSA_AltEntry:
258
llvm_unreachable("ELF doesn't support the .alt_entry attribute");
259
260
case MCSA_LGlobal:
261
llvm_unreachable("ELF doesn't support the .lglobl attribute");
262
}
263
264
return true;
265
}
266
267
void MCELFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
268
Align ByteAlignment) {
269
auto *Symbol = cast<MCSymbolELF>(S);
270
getAssembler().registerSymbol(*Symbol);
271
272
if (!Symbol->isBindingSet())
273
Symbol->setBinding(ELF::STB_GLOBAL);
274
275
Symbol->setType(ELF::STT_OBJECT);
276
277
if (Symbol->getBinding() == ELF::STB_LOCAL) {
278
MCSection &Section = *getAssembler().getContext().getELFSection(
279
".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
280
MCSectionSubPair P = getCurrentSection();
281
switchSection(&Section);
282
283
emitValueToAlignment(ByteAlignment, 0, 1, 0);
284
emitLabel(Symbol);
285
emitZeros(Size);
286
287
switchSection(P.first, P.second);
288
} else {
289
if (Symbol->declareCommon(Size, ByteAlignment))
290
report_fatal_error(Twine("Symbol: ") + Symbol->getName() +
291
" redeclared as different type");
292
}
293
294
cast<MCSymbolELF>(Symbol)
295
->setSize(MCConstantExpr::create(Size, getContext()));
296
}
297
298
void MCELFStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
299
cast<MCSymbolELF>(Symbol)->setSize(Value);
300
}
301
302
void MCELFStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
303
StringRef Name,
304
bool KeepOriginalSym) {
305
getWriter().Symvers.push_back(ELFObjectWriter::Symver{
306
getStartTokLoc(), OriginalSym, Name, KeepOriginalSym});
307
}
308
309
void MCELFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
310
Align ByteAlignment) {
311
auto *Symbol = cast<MCSymbolELF>(S);
312
// FIXME: Should this be caught and done earlier?
313
getAssembler().registerSymbol(*Symbol);
314
Symbol->setBinding(ELF::STB_LOCAL);
315
emitCommonSymbol(Symbol, Size, ByteAlignment);
316
}
317
318
void MCELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
319
SMLoc Loc) {
320
if (isBundleLocked())
321
report_fatal_error("Emitting values inside a locked bundle is forbidden");
322
fixSymbolsInTLSFixups(Value);
323
MCObjectStreamer::emitValueImpl(Value, Size, Loc);
324
}
325
326
void MCELFStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
327
unsigned ValueSize,
328
unsigned MaxBytesToEmit) {
329
if (isBundleLocked())
330
report_fatal_error("Emitting values inside a locked bundle is forbidden");
331
MCObjectStreamer::emitValueToAlignment(Alignment, Value, ValueSize,
332
MaxBytesToEmit);
333
}
334
335
void MCELFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
336
const MCSymbolRefExpr *To,
337
uint64_t Count) {
338
getWriter().getCGProfile().push_back({From, To, Count});
339
}
340
341
void MCELFStreamer::emitIdent(StringRef IdentString) {
342
MCSection *Comment = getAssembler().getContext().getELFSection(
343
".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
344
pushSection();
345
switchSection(Comment);
346
if (!SeenIdent) {
347
emitInt8(0);
348
SeenIdent = true;
349
}
350
emitBytes(IdentString);
351
emitInt8(0);
352
popSection();
353
}
354
355
void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
356
switch (expr->getKind()) {
357
case MCExpr::Target:
358
cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler());
359
break;
360
case MCExpr::Constant:
361
break;
362
363
case MCExpr::Binary: {
364
const MCBinaryExpr *be = cast<MCBinaryExpr>(expr);
365
fixSymbolsInTLSFixups(be->getLHS());
366
fixSymbolsInTLSFixups(be->getRHS());
367
break;
368
}
369
370
case MCExpr::SymbolRef: {
371
const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr);
372
switch (symRef.getKind()) {
373
default:
374
return;
375
case MCSymbolRefExpr::VK_GOTTPOFF:
376
case MCSymbolRefExpr::VK_INDNTPOFF:
377
case MCSymbolRefExpr::VK_NTPOFF:
378
case MCSymbolRefExpr::VK_GOTNTPOFF:
379
case MCSymbolRefExpr::VK_TLSCALL:
380
case MCSymbolRefExpr::VK_TLSDESC:
381
case MCSymbolRefExpr::VK_TLSGD:
382
case MCSymbolRefExpr::VK_TLSLD:
383
case MCSymbolRefExpr::VK_TLSLDM:
384
case MCSymbolRefExpr::VK_TPOFF:
385
case MCSymbolRefExpr::VK_TPREL:
386
case MCSymbolRefExpr::VK_DTPOFF:
387
case MCSymbolRefExpr::VK_DTPREL:
388
case MCSymbolRefExpr::VK_PPC_DTPMOD:
389
case MCSymbolRefExpr::VK_PPC_TPREL_LO:
390
case MCSymbolRefExpr::VK_PPC_TPREL_HI:
391
case MCSymbolRefExpr::VK_PPC_TPREL_HA:
392
case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
393
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
394
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
395
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
396
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
397
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
398
case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
399
case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
400
case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
401
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
402
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
403
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
404
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
405
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
406
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
407
case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
408
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
409
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
410
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
411
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
412
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
413
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
414
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
415
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
416
case MCSymbolRefExpr::VK_PPC_TLS:
417
case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
418
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
419
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
420
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
421
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
422
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
423
case MCSymbolRefExpr::VK_PPC_TLSGD:
424
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
425
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
426
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
427
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
428
case MCSymbolRefExpr::VK_PPC_TLSLD:
429
break;
430
}
431
getAssembler().registerSymbol(symRef.getSymbol());
432
cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
433
break;
434
}
435
436
case MCExpr::Unary:
437
fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr());
438
break;
439
}
440
}
441
442
void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE,
443
uint64_t Offset) {
444
const MCSymbol *S = &SRE->getSymbol();
445
if (S->isTemporary()) {
446
if (!S->isInSection()) {
447
getContext().reportError(
448
SRE->getLoc(), Twine("Reference to undefined temporary symbol ") +
449
"`" + S->getName() + "`");
450
return;
451
}
452
S = S->getSection().getBeginSymbol();
453
S->setUsedInReloc();
454
SRE = MCSymbolRefExpr::create(S, MCSymbolRefExpr::VK_None, getContext(),
455
SRE->getLoc());
456
}
457
const MCConstantExpr *MCOffset = MCConstantExpr::create(Offset, getContext());
458
if (std::optional<std::pair<bool, std::string>> Err =
459
MCObjectStreamer::emitRelocDirective(
460
*MCOffset, "BFD_RELOC_NONE", SRE, SRE->getLoc(),
461
*getContext().getSubtargetInfo()))
462
report_fatal_error("Relocation for CG Profile could not be created: " +
463
Twine(Err->second));
464
}
465
466
void MCELFStreamer::finalizeCGProfile() {
467
ELFObjectWriter &W = getWriter();
468
if (W.getCGProfile().empty())
469
return;
470
MCSection *CGProfile = getAssembler().getContext().getELFSection(
471
".llvm.call-graph-profile", ELF::SHT_LLVM_CALL_GRAPH_PROFILE,
472
ELF::SHF_EXCLUDE, /*sizeof(Elf_CGProfile_Impl<>)=*/8);
473
pushSection();
474
switchSection(CGProfile);
475
uint64_t Offset = 0;
476
for (auto &E : W.getCGProfile()) {
477
finalizeCGProfileEntry(E.From, Offset);
478
finalizeCGProfileEntry(E.To, Offset);
479
emitIntValue(E.Count, sizeof(uint64_t));
480
Offset += sizeof(uint64_t);
481
}
482
popSection();
483
}
484
485
void MCELFStreamer::emitInstToFragment(const MCInst &Inst,
486
const MCSubtargetInfo &STI) {
487
this->MCObjectStreamer::emitInstToFragment(Inst, STI);
488
MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment());
489
490
for (auto &Fixup : F.getFixups())
491
fixSymbolsInTLSFixups(Fixup.getValue());
492
}
493
494
// A fragment can only have one Subtarget, and when bundling is enabled we
495
// sometimes need to use the same fragment. We give an error if there
496
// are conflicting Subtargets.
497
static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI,
498
const MCSubtargetInfo *NewSTI) {
499
if (OldSTI && NewSTI && OldSTI != NewSTI)
500
report_fatal_error("A Bundle can only have one Subtarget.");
501
}
502
503
void MCELFStreamer::emitInstToData(const MCInst &Inst,
504
const MCSubtargetInfo &STI) {
505
MCAssembler &Assembler = getAssembler();
506
507
// There are several possibilities here:
508
//
509
// If bundling is disabled, append the encoded instruction to the current data
510
// fragment (or create a new such fragment if the current fragment is not a
511
// data fragment, or the Subtarget has changed).
512
//
513
// If bundling is enabled:
514
// - If we're not in a bundle-locked group, emit the instruction into a
515
// fragment of its own.
516
// - If we're in a bundle-locked group, append the instruction to the current
517
// data fragment because we want all the instructions in a group to get into
518
// the same fragment. Be careful not to do that for the first instruction in
519
// the group, though.
520
MCDataFragment *DF;
521
522
if (Assembler.isBundlingEnabled()) {
523
MCSection &Sec = *getCurrentSectionOnly();
524
if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) {
525
// If we are bundle-locked, we re-use the current fragment.
526
// The bundle-locking directive ensures this is a new data fragment.
527
DF = cast<MCDataFragment>(getCurrentFragment());
528
CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
529
} else {
530
DF = getContext().allocFragment<MCDataFragment>();
531
insert(DF);
532
}
533
if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) {
534
// If this fragment is for a group marked "align_to_end", set a flag
535
// in the fragment. This can happen after the fragment has already been
536
// created if there are nested bundle_align groups and an inner one
537
// is the one marked align_to_end.
538
DF->setAlignToBundleEnd(true);
539
}
540
541
// We're now emitting an instruction in a bundle group, so this flag has
542
// to be turned off.
543
Sec.setBundleGroupBeforeFirstInst(false);
544
} else {
545
DF = getOrCreateDataFragment(&STI);
546
}
547
548
// Emit instruction directly into data fragment.
549
size_t FixupStartIndex = DF->getFixups().size();
550
size_t CodeOffset = DF->getContents().size();
551
Assembler.getEmitter().encodeInstruction(Inst, DF->getContents(),
552
DF->getFixups(), STI);
553
554
auto Fixups = MutableArrayRef(DF->getFixups()).slice(FixupStartIndex);
555
for (auto &Fixup : Fixups) {
556
Fixup.setOffset(Fixup.getOffset() + CodeOffset);
557
fixSymbolsInTLSFixups(Fixup.getValue());
558
}
559
560
DF->setHasInstructions(STI);
561
if (!Fixups.empty() && Fixups.back().getTargetKind() ==
562
getAssembler().getBackend().RelaxFixupKind)
563
DF->setLinkerRelaxable();
564
}
565
566
void MCELFStreamer::emitBundleAlignMode(Align Alignment) {
567
assert(Log2(Alignment) <= 30 && "Invalid bundle alignment");
568
MCAssembler &Assembler = getAssembler();
569
if (Alignment > 1 && (Assembler.getBundleAlignSize() == 0 ||
570
Assembler.getBundleAlignSize() == Alignment.value()))
571
Assembler.setBundleAlignSize(Alignment.value());
572
else
573
report_fatal_error(".bundle_align_mode cannot be changed once set");
574
}
575
576
void MCELFStreamer::emitBundleLock(bool AlignToEnd) {
577
MCSection &Sec = *getCurrentSectionOnly();
578
579
if (!getAssembler().isBundlingEnabled())
580
report_fatal_error(".bundle_lock forbidden when bundling is disabled");
581
582
if (!isBundleLocked())
583
Sec.setBundleGroupBeforeFirstInst(true);
584
585
Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd
586
: MCSection::BundleLocked);
587
}
588
589
void MCELFStreamer::emitBundleUnlock() {
590
MCSection &Sec = *getCurrentSectionOnly();
591
592
if (!getAssembler().isBundlingEnabled())
593
report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
594
else if (!isBundleLocked())
595
report_fatal_error(".bundle_unlock without matching lock");
596
else if (Sec.isBundleGroupBeforeFirstInst())
597
report_fatal_error("Empty bundle-locked group is forbidden");
598
599
Sec.setBundleLockState(MCSection::NotBundleLocked);
600
}
601
602
void MCELFStreamer::finishImpl() {
603
// Emit the .gnu attributes section if any attributes have been added.
604
if (!GNUAttributes.empty()) {
605
MCSection *DummyAttributeSection = nullptr;
606
createAttributesSection("gnu", ".gnu.attributes", ELF::SHT_GNU_ATTRIBUTES,
607
DummyAttributeSection, GNUAttributes);
608
}
609
610
// Ensure the last section gets aligned if necessary.
611
if (MCFragment *F = getCurrentFragment())
612
setSectionAlignmentForBundling(getAssembler(), F->getParent());
613
614
finalizeCGProfile();
615
emitFrames(nullptr);
616
617
this->MCObjectStreamer::finishImpl();
618
}
619
620
void MCELFStreamer::emitThumbFunc(MCSymbol *Func) {
621
llvm_unreachable("Generic ELF doesn't support this directive");
622
}
623
624
void MCELFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
625
llvm_unreachable("ELF doesn't support this directive");
626
}
627
628
void MCELFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
629
uint64_t Size, Align ByteAlignment,
630
SMLoc Loc) {
631
llvm_unreachable("ELF doesn't support this directive");
632
}
633
634
void MCELFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
635
uint64_t Size, Align ByteAlignment) {
636
llvm_unreachable("ELF doesn't support this directive");
637
}
638
639
void MCELFStreamer::setAttributeItem(unsigned Attribute, unsigned Value,
640
bool OverwriteExisting) {
641
// Look for existing attribute item
642
if (AttributeItem *Item = getAttributeItem(Attribute)) {
643
if (!OverwriteExisting)
644
return;
645
Item->Type = AttributeItem::NumericAttribute;
646
Item->IntValue = Value;
647
return;
648
}
649
650
// Create new attribute item
651
AttributeItem Item = {AttributeItem::NumericAttribute, Attribute, Value,
652
std::string(StringRef(""))};
653
Contents.push_back(Item);
654
}
655
656
void MCELFStreamer::setAttributeItem(unsigned Attribute, StringRef Value,
657
bool OverwriteExisting) {
658
// Look for existing attribute item
659
if (AttributeItem *Item = getAttributeItem(Attribute)) {
660
if (!OverwriteExisting)
661
return;
662
Item->Type = AttributeItem::TextAttribute;
663
Item->StringValue = std::string(Value);
664
return;
665
}
666
667
// Create new attribute item
668
AttributeItem Item = {AttributeItem::TextAttribute, Attribute, 0,
669
std::string(Value)};
670
Contents.push_back(Item);
671
}
672
673
void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue,
674
StringRef StringValue,
675
bool OverwriteExisting) {
676
// Look for existing attribute item
677
if (AttributeItem *Item = getAttributeItem(Attribute)) {
678
if (!OverwriteExisting)
679
return;
680
Item->Type = AttributeItem::NumericAndTextAttributes;
681
Item->IntValue = IntValue;
682
Item->StringValue = std::string(StringValue);
683
return;
684
}
685
686
// Create new attribute item
687
AttributeItem Item = {AttributeItem::NumericAndTextAttributes, Attribute,
688
IntValue, std::string(StringValue)};
689
Contents.push_back(Item);
690
}
691
692
MCELFStreamer::AttributeItem *
693
MCELFStreamer::getAttributeItem(unsigned Attribute) {
694
for (AttributeItem &Item : Contents)
695
if (Item.Tag == Attribute)
696
return &Item;
697
return nullptr;
698
}
699
700
size_t
701
MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
702
size_t Result = 0;
703
for (const AttributeItem &Item : AttrsVec) {
704
switch (Item.Type) {
705
case AttributeItem::HiddenAttribute:
706
break;
707
case AttributeItem::NumericAttribute:
708
Result += getULEB128Size(Item.Tag);
709
Result += getULEB128Size(Item.IntValue);
710
break;
711
case AttributeItem::TextAttribute:
712
Result += getULEB128Size(Item.Tag);
713
Result += Item.StringValue.size() + 1; // string + '\0'
714
break;
715
case AttributeItem::NumericAndTextAttributes:
716
Result += getULEB128Size(Item.Tag);
717
Result += getULEB128Size(Item.IntValue);
718
Result += Item.StringValue.size() + 1; // string + '\0';
719
break;
720
}
721
}
722
return Result;
723
}
724
725
void MCELFStreamer::createAttributesSection(
726
StringRef Vendor, const Twine &Section, unsigned Type,
727
MCSection *&AttributeSection, SmallVector<AttributeItem, 64> &AttrsVec) {
728
// <format-version>
729
// [ <section-length> "vendor-name"
730
// [ <file-tag> <size> <attribute>*
731
// | <section-tag> <size> <section-number>* 0 <attribute>*
732
// | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
733
// ]+
734
// ]*
735
736
// Switch section to AttributeSection or get/create the section.
737
if (AttributeSection) {
738
switchSection(AttributeSection);
739
} else {
740
AttributeSection = getContext().getELFSection(Section, Type, 0);
741
switchSection(AttributeSection);
742
743
// Format version
744
emitInt8(0x41);
745
}
746
747
// Vendor size + Vendor name + '\0'
748
const size_t VendorHeaderSize = 4 + Vendor.size() + 1;
749
750
// Tag + Tag Size
751
const size_t TagHeaderSize = 1 + 4;
752
753
const size_t ContentsSize = calculateContentSize(AttrsVec);
754
755
emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
756
emitBytes(Vendor);
757
emitInt8(0); // '\0'
758
759
emitInt8(ARMBuildAttrs::File);
760
emitInt32(TagHeaderSize + ContentsSize);
761
762
// Size should have been accounted for already, now
763
// emit each field as its type (ULEB or String)
764
for (const AttributeItem &Item : AttrsVec) {
765
emitULEB128IntValue(Item.Tag);
766
switch (Item.Type) {
767
default:
768
llvm_unreachable("Invalid attribute type");
769
case AttributeItem::NumericAttribute:
770
emitULEB128IntValue(Item.IntValue);
771
break;
772
case AttributeItem::TextAttribute:
773
emitBytes(Item.StringValue);
774
emitInt8(0); // '\0'
775
break;
776
case AttributeItem::NumericAndTextAttributes:
777
emitULEB128IntValue(Item.IntValue);
778
emitBytes(Item.StringValue);
779
emitInt8(0); // '\0'
780
break;
781
}
782
}
783
784
AttrsVec.clear();
785
}
786
787
MCStreamer *llvm::createELFStreamer(MCContext &Context,
788
std::unique_ptr<MCAsmBackend> &&MAB,
789
std::unique_ptr<MCObjectWriter> &&OW,
790
std::unique_ptr<MCCodeEmitter> &&CE) {
791
MCELFStreamer *S =
792
new MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE));
793
return S;
794
}
795
796