LLVM 19.0.0git
ELFObjectWriter.cpp
Go to the documentation of this file.
1//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
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 implements ELF object file writer information.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/Twine.h"
20#include "llvm/ADT/iterator.h"
23#include "llvm/MC/MCAsmInfo.h"
24#include "llvm/MC/MCAsmLayout.h"
25#include "llvm/MC/MCAssembler.h"
26#include "llvm/MC/MCContext.h"
28#include "llvm/MC/MCExpr.h"
29#include "llvm/MC/MCFixup.h"
31#include "llvm/MC/MCFragment.h"
33#include "llvm/MC/MCSection.h"
35#include "llvm/MC/MCSymbol.h"
36#include "llvm/MC/MCSymbolELF.h"
38#include "llvm/MC/MCValue.h"
43#include "llvm/Support/Endian.h"
45#include "llvm/Support/Error.h"
47#include "llvm/Support/LEB128.h"
49#include "llvm/Support/SMLoc.h"
52#include <algorithm>
53#include <cassert>
54#include <cstddef>
55#include <cstdint>
56#include <map>
57#include <memory>
58#include <string>
59#include <utility>
60#include <vector>
61
62using namespace llvm;
63
64#undef DEBUG_TYPE
65#define DEBUG_TYPE "reloc-info"
66
67namespace {
68
69using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
70
71class ELFObjectWriter;
72struct ELFWriter;
73
74bool isDwoSection(const MCSectionELF &Sec) {
75 return Sec.getName().ends_with(".dwo");
76}
77
78class SymbolTableWriter {
79 ELFWriter &EWriter;
80 bool Is64Bit;
81
82 // indexes we are going to write to .symtab_shndx.
83 std::vector<uint32_t> ShndxIndexes;
84
85 // The numbel of symbols written so far.
86 unsigned NumWritten;
87
88 void createSymtabShndx();
89
90 template <typename T> void write(T Value);
91
92public:
93 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
94
95 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
96 uint8_t other, uint32_t shndx, bool Reserved);
97
98 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
99};
100
101struct ELFWriter {
102 ELFObjectWriter &OWriter;
104
105 enum DwoMode {
106 AllSections,
107 NonDwoOnly,
108 DwoOnly,
109 } Mode;
110
111 static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
112 static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
113 bool Used, bool Renamed);
114
115 /// Helper struct for containing some precomputed information on symbols.
116 struct ELFSymbolData {
117 const MCSymbolELF *Symbol;
118 StringRef Name;
119 uint32_t SectionIndex;
120 uint32_t Order;
121 };
122
123 /// @}
124 /// @name Symbol Table Data
125 /// @{
126
128
129 /// @}
130
131 // This holds the symbol table index of the last local symbol.
132 unsigned LastLocalSymbolIndex = ~0u;
133 // This holds the .strtab section index.
134 unsigned StringTableIndex = ~0u;
135 // This holds the .symtab section index.
136 unsigned SymbolTableIndex = ~0u;
137
138 // Sections in the order they are to be output in the section table.
139 std::vector<const MCSectionELF *> SectionTable;
140 unsigned addToSectionTable(const MCSectionELF *Sec);
141
142 // TargetObjectWriter wrappers.
143 bool is64Bit() const;
144 bool usesRela(const MCSectionELF &Sec) const;
145
146 uint64_t align(Align Alignment);
147
148 bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
149 SmallVectorImpl<uint8_t> &CompressedContents,
150 Align Alignment);
151
152public:
153 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
154 bool IsLittleEndian, DwoMode Mode)
155 : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little
157 Mode(Mode) {}
158
159 void WriteWord(uint64_t Word) {
160 if (is64Bit())
161 W.write<uint64_t>(Word);
162 else
163 W.write<uint32_t>(Word);
164 }
165
166 template <typename T> void write(T Val) {
167 W.write(Val);
168 }
169
170 void writeHeader(const MCAssembler &Asm);
171
172 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
173 ELFSymbolData &MSD, const MCAsmLayout &Layout);
174
175 // Start and end offset of each section
176 using SectionOffsetsTy =
177 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
178
179 // Map from a signature symbol to the group section index
180 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
181
182 /// Compute the symbol table data
183 ///
184 /// \param Asm - The assembler.
185 /// \param SectionIndexMap - Maps a section to its index.
186 /// \param RevGroupMap - Maps a signature symbol to the group section.
187 void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
188 const SectionIndexMapTy &SectionIndexMap,
189 const RevGroupMapTy &RevGroupMap,
190 SectionOffsetsTy &SectionOffsets);
191
192 void writeAddrsigSection();
193
194 MCSectionELF *createRelocationSection(MCContext &Ctx,
195 const MCSectionELF &Sec);
196
197 void createMemtagRelocs(MCAssembler &Asm);
198
199 void writeSectionHeader(const MCAsmLayout &Layout,
200 const SectionIndexMapTy &SectionIndexMap,
201 const SectionOffsetsTy &SectionOffsets);
202
203 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
204 const MCAsmLayout &Layout);
205
206 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
208 uint32_t Link, uint32_t Info, MaybeAlign Alignment,
209 uint64_t EntrySize);
210
211 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
212
213 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
214 void writeSection(const SectionIndexMapTy &SectionIndexMap,
215 uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
216 const MCSectionELF &Section);
217};
218
219class ELFObjectWriter : public MCObjectWriter {
220 /// The target specific ELF writer instance.
221 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
222
224
226
227 bool SeenGnuAbi = false;
228
229 std::optional<uint8_t> OverrideABIVersion;
230
231 bool hasRelocationAddend() const;
232
233 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
234 const MCSymbolELF *Sym, uint64_t C,
235 unsigned Type) const;
236
237public:
238 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
239 : TargetObjectWriter(std::move(MOTW)) {}
240
241 void reset() override {
242 SeenGnuAbi = false;
243 OverrideABIVersion.reset();
244 Relocations.clear();
245 Renames.clear();
247 }
248
250 const MCSymbol &SymA,
251 const MCFragment &FB, bool InSet,
252 bool IsPCRel) const override;
253
254 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
255 const MCSectionELF *From,
256 const MCSectionELF *To) {
257 return true;
258 }
259
260 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
261 const MCFragment *Fragment, const MCFixup &Fixup,
262 MCValue Target, uint64_t &FixedValue) override;
263
265 const MCAsmLayout &Layout) override;
266
267 void markGnuAbi() override { SeenGnuAbi = true; }
268 bool seenGnuAbi() const { return SeenGnuAbi; }
269
270 bool seenOverrideABIVersion() const { return OverrideABIVersion.has_value(); }
271 uint8_t getOverrideABIVersion() const { return OverrideABIVersion.value(); }
272 void setOverrideABIVersion(uint8_t V) override { OverrideABIVersion = V; }
273
274 friend struct ELFWriter;
275};
276
277class ELFSingleObjectWriter : public ELFObjectWriter {
279 bool IsLittleEndian;
280
281public:
282 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
283 raw_pwrite_stream &OS, bool IsLittleEndian)
284 : ELFObjectWriter(std::move(MOTW)), OS(OS),
285 IsLittleEndian(IsLittleEndian) {}
286
287 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
288 return ELFWriter(*this, OS, IsLittleEndian, ELFWriter::AllSections)
289 .writeObject(Asm, Layout);
290 }
291
292 friend struct ELFWriter;
293};
294
295class ELFDwoObjectWriter : public ELFObjectWriter {
296 raw_pwrite_stream &OS, &DwoOS;
297 bool IsLittleEndian;
298
299public:
300 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
302 bool IsLittleEndian)
303 : ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
304 IsLittleEndian(IsLittleEndian) {}
305
306 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
307 const MCSectionELF *To) override {
308 if (isDwoSection(*From)) {
309 Ctx.reportError(Loc, "A dwo section may not contain relocations");
310 return false;
311 }
312 if (To && isDwoSection(*To)) {
313 Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
314 return false;
315 }
316 return true;
317 }
318
319 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
320 uint64_t Size = ELFWriter(*this, OS, IsLittleEndian, ELFWriter::NonDwoOnly)
321 .writeObject(Asm, Layout);
322 Size += ELFWriter(*this, DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
323 .writeObject(Asm, Layout);
324 return Size;
325 }
326};
327
328} // end anonymous namespace
329
330uint64_t ELFWriter::align(Align Alignment) {
331 uint64_t Offset = W.OS.tell();
332 uint64_t NewOffset = alignTo(Offset, Alignment);
333 W.OS.write_zeros(NewOffset - Offset);
334 return NewOffset;
335}
336
337unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
338 SectionTable.push_back(Sec);
339 StrTabBuilder.add(Sec->getName());
340 return SectionTable.size();
341}
342
343void SymbolTableWriter::createSymtabShndx() {
344 if (!ShndxIndexes.empty())
345 return;
346
347 ShndxIndexes.resize(NumWritten);
348}
349
350template <typename T> void SymbolTableWriter::write(T Value) {
351 EWriter.write(Value);
352}
353
354SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
355 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
356
357void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
358 uint64_t size, uint8_t other,
359 uint32_t shndx, bool Reserved) {
360 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
361
362 if (LargeIndex)
363 createSymtabShndx();
364
365 if (!ShndxIndexes.empty()) {
366 if (LargeIndex)
367 ShndxIndexes.push_back(shndx);
368 else
369 ShndxIndexes.push_back(0);
370 }
371
372 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
373
374 if (Is64Bit) {
375 write(name); // st_name
376 write(info); // st_info
377 write(other); // st_other
378 write(Index); // st_shndx
379 write(value); // st_value
380 write(size); // st_size
381 } else {
382 write(name); // st_name
383 write(uint32_t(value)); // st_value
384 write(uint32_t(size)); // st_size
385 write(info); // st_info
386 write(other); // st_other
387 write(Index); // st_shndx
388 }
389
390 ++NumWritten;
391}
392
393bool ELFWriter::is64Bit() const {
394 return OWriter.TargetObjectWriter->is64Bit();
395}
396
397bool ELFWriter::usesRela(const MCSectionELF &Sec) const {
398 return OWriter.hasRelocationAddend() &&
400}
401
402// Emit the ELF header.
403void ELFWriter::writeHeader(const MCAssembler &Asm) {
404 // ELF Header
405 // ----------
406 //
407 // Note
408 // ----
409 // emitWord method behaves differently for ELF32 and ELF64, writing
410 // 4 bytes in the former and 8 in the latter.
411
412 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
413
414 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
415
416 // e_ident[EI_DATA]
419
420 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
421 // e_ident[EI_OSABI]
422 uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
423 W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()
424 ? int(ELF::ELFOSABI_GNU)
425 : OSABI);
426 // e_ident[EI_ABIVERSION]
427 W.OS << char(OWriter.seenOverrideABIVersion()
428 ? OWriter.getOverrideABIVersion()
429 : OWriter.TargetObjectWriter->getABIVersion());
430
431 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
432
433 W.write<uint16_t>(ELF::ET_REL); // e_type
434
435 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
436
437 W.write<uint32_t>(ELF::EV_CURRENT); // e_version
438 WriteWord(0); // e_entry, no entry point in .o file
439 WriteWord(0); // e_phoff, no program header for .o
440 WriteWord(0); // e_shoff = sec hdr table off in bytes
441
442 // e_flags = whatever the target wants
443 W.write<uint32_t>(Asm.getELFHeaderEFlags());
444
445 // e_ehsize = ELF header size
446 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
447 : sizeof(ELF::Elf32_Ehdr));
448
449 W.write<uint16_t>(0); // e_phentsize = prog header entry size
450 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
451
452 // e_shentsize = Section header entry size
453 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
454 : sizeof(ELF::Elf32_Shdr));
455
456 // e_shnum = # of section header ents
457 W.write<uint16_t>(0);
458
459 // e_shstrndx = Section # of '.strtab'
460 assert(StringTableIndex < ELF::SHN_LORESERVE);
461 W.write<uint16_t>(StringTableIndex);
462}
463
464uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
465 const MCAsmLayout &Layout) {
466 if (Sym.isCommon())
467 return Sym.getCommonAlignment()->value();
468
469 uint64_t Res;
470 if (!Layout.getSymbolOffset(Sym, Res))
471 return 0;
472
473 if (Layout.getAssembler().isThumbFunc(&Sym))
474 Res |= 1;
475
476 return Res;
477}
478
479static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
480 uint8_t Type = newType;
481
482 // Propagation rules:
483 // IFUNC > FUNC > OBJECT > NOTYPE
484 // TLS_OBJECT > OBJECT > NOTYPE
485 //
486 // dont let the new type degrade the old type
487 switch (origType) {
488 default:
489 break;
491 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
494 break;
495 case ELF::STT_FUNC:
499 break;
500 case ELF::STT_OBJECT:
501 if (Type == ELF::STT_NOTYPE)
503 break;
504 case ELF::STT_TLS:
508 break;
509 }
510
511 return Type;
512}
513
514static bool isIFunc(const MCSymbolELF *Symbol) {
515 while (Symbol->getType() != ELF::STT_GNU_IFUNC) {
516 const MCSymbolRefExpr *Value;
517 if (!Symbol->isVariable() ||
518 !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) ||
519 Value->getKind() != MCSymbolRefExpr::VK_None ||
521 return false;
522 Symbol = &cast<MCSymbolELF>(Value->getSymbol());
523 }
524 return true;
525}
526
527void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
528 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
529 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
530 const MCSymbolELF *Base =
531 cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
532
533 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
534 // SHN_COMMON.
535 bool IsReserved = !Base || Symbol.isCommon();
536
537 // Binding and Type share the same byte as upper and lower nibbles
538 uint8_t Binding = Symbol.getBinding();
539 uint8_t Type = Symbol.getType();
540 if (isIFunc(&Symbol))
542 if (Base) {
543 Type = mergeTypeForSet(Type, Base->getType());
544 }
545 uint8_t Info = (Binding << 4) | Type;
546
547 // Other and Visibility share the same byte with Visibility using the lower
548 // 2 bits
549 uint8_t Visibility = Symbol.getVisibility();
550 uint8_t Other = Symbol.getOther() | Visibility;
551
552 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
553 uint64_t Size = 0;
554
555 const MCExpr *ESize = MSD.Symbol->getSize();
556 if (!ESize && Base) {
557 // For expressions like .set y, x+1, if y's size is unset, inherit from x.
558 ESize = Base->getSize();
559
560 // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
561 // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
562 // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
563 // needs. MCBinaryExpr is not handled.
564 const MCSymbolELF *Sym = &Symbol;
565 while (Sym->isVariable()) {
566 if (auto *Expr =
567 dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
568 Sym = cast<MCSymbolELF>(&Expr->getSymbol());
569 if (!Sym->getSize())
570 continue;
571 ESize = Sym->getSize();
572 }
573 break;
574 }
575 }
576
577 if (ESize) {
578 int64_t Res;
579 if (!ESize->evaluateKnownAbsolute(Res, Layout))
580 report_fatal_error("Size expression must be absolute.");
581 Size = Res;
582 }
583
584 // Write out the symbol table entry
585 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
586 IsReserved);
587}
588
589bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
590 bool Used, bool Renamed) {
591 if (Symbol.isVariable()) {
592 const MCExpr *Expr = Symbol.getVariableValue();
593 // Target Expressions that are always inlined do not appear in the symtab
594 if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
595 if (T->inlineAssignedExpr())
596 return false;
597 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
598 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
599 return false;
600 }
601 }
602
603 if (Used)
604 return true;
605
606 if (Renamed)
607 return false;
608
609 if (Symbol.isVariable() && Symbol.isUndefined()) {
610 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
611 Layout.getBaseSymbol(Symbol);
612 return false;
613 }
614
615 if (Symbol.isTemporary())
616 return false;
617
618 if (Symbol.getType() == ELF::STT_SECTION)
619 return false;
620
621 return true;
622}
623
624void ELFWriter::createMemtagRelocs(MCAssembler &Asm) {
625 MCSectionELF *MemtagRelocs = nullptr;
626 for (const MCSymbol &Sym : Asm.symbols()) {
627 const auto &SymE = cast<MCSymbolELF>(Sym);
628 if (!SymE.isMemtag())
629 continue;
630 if (MemtagRelocs == nullptr) {
631 MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(Asm.getContext());
632 if (MemtagRelocs == nullptr)
633 report_fatal_error("Tagged globals are not available on this architecture.");
634 Asm.registerSection(*MemtagRelocs);
635 }
636 ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
637 OWriter.Relocations[MemtagRelocs].push_back(Rec);
638 }
639}
640
641void ELFWriter::computeSymbolTable(
642 MCAssembler &Asm, const MCAsmLayout &Layout,
643 const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
644 SectionOffsetsTy &SectionOffsets) {
645 MCContext &Ctx = Asm.getContext();
646 SymbolTableWriter Writer(*this, is64Bit());
647
648 // Symbol table
649 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
650 MCSectionELF *SymtabSection =
651 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
652 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
653 SymbolTableIndex = addToSectionTable(SymtabSection);
654
655 uint64_t SecStart = align(SymtabSection->getAlign());
656
657 // The first entry is the undefined symbol entry.
658 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
659
660 std::vector<ELFSymbolData> LocalSymbolData;
661 std::vector<ELFSymbolData> ExternalSymbolData;
663 Asm.getFileNames();
664 for (const std::pair<std::string, size_t> &F : FileNames)
665 StrTabBuilder.add(F.first);
666
667 // Add the data for the symbols.
668 bool HasLargeSectionIndex = false;
669 for (auto It : llvm::enumerate(Asm.symbols())) {
670 const auto &Symbol = cast<MCSymbolELF>(It.value());
671 bool Used = Symbol.isUsedInReloc();
672 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
673 bool isSignature = Symbol.isSignature();
674
675 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
676 OWriter.Renames.count(&Symbol)))
677 continue;
678
679 if (Symbol.isTemporary() && Symbol.isUndefined()) {
680 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
681 continue;
682 }
683
684 ELFSymbolData MSD;
685 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
686 MSD.Order = It.index();
687
688 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
689 assert(Local || !Symbol.isTemporary());
690
691 if (Symbol.isAbsolute()) {
692 MSD.SectionIndex = ELF::SHN_ABS;
693 } else if (Symbol.isCommon()) {
694 if (Symbol.isTargetCommon()) {
695 MSD.SectionIndex = Symbol.getIndex();
696 } else {
697 assert(!Local);
698 MSD.SectionIndex = ELF::SHN_COMMON;
699 }
700 } else if (Symbol.isUndefined()) {
701 if (isSignature && !Used) {
702 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
703 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
704 HasLargeSectionIndex = true;
705 } else {
706 MSD.SectionIndex = ELF::SHN_UNDEF;
707 }
708 } else {
709 const MCSectionELF &Section =
710 static_cast<const MCSectionELF &>(Symbol.getSection());
711
712 // We may end up with a situation when section symbol is technically
713 // defined, but should not be. That happens because we explicitly
714 // pre-create few .debug_* sections to have accessors.
715 // And if these sections were not really defined in the code, but were
716 // referenced, we simply error out.
717 if (!Section.isRegistered()) {
718 assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
720 Ctx.reportError(SMLoc(),
721 "Undefined section reference: " + Symbol.getName());
722 continue;
723 }
724
725 if (Mode == NonDwoOnly && isDwoSection(Section))
726 continue;
727 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
728 assert(MSD.SectionIndex && "Invalid section index!");
729 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
730 HasLargeSectionIndex = true;
731 }
732
733 StringRef Name = Symbol.getName();
734
735 // Sections have their own string table
736 if (Symbol.getType() != ELF::STT_SECTION) {
737 MSD.Name = Name;
738 StrTabBuilder.add(Name);
739 }
740
741 if (Local)
742 LocalSymbolData.push_back(MSD);
743 else
744 ExternalSymbolData.push_back(MSD);
745 }
746
747 // This holds the .symtab_shndx section index.
748 unsigned SymtabShndxSectionIndex = 0;
749
750 if (HasLargeSectionIndex) {
751 MCSectionELF *SymtabShndxSection =
752 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
753 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
754 SymtabShndxSection->setAlignment(Align(4));
755 }
756
757 StrTabBuilder.finalize();
758
759 // Make the first STT_FILE precede previous local symbols.
760 unsigned Index = 1;
761 auto FileNameIt = FileNames.begin();
762 if (!FileNames.empty())
763 FileNames[0].second = 0;
764
765 for (ELFSymbolData &MSD : LocalSymbolData) {
766 // Emit STT_FILE symbols before their associated local symbols.
767 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
768 ++FileNameIt) {
769 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
771 ELF::SHN_ABS, true);
772 ++Index;
773 }
774
775 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
776 ? 0
777 : StrTabBuilder.getOffset(MSD.Name);
778 MSD.Symbol->setIndex(Index++);
779 writeSymbol(Writer, StringIndex, MSD, Layout);
780 }
781 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
782 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
784 ELF::SHN_ABS, true);
785 ++Index;
786 }
787
788 // Write the symbol table entries.
789 LastLocalSymbolIndex = Index;
790
791 for (ELFSymbolData &MSD : ExternalSymbolData) {
792 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
793 MSD.Symbol->setIndex(Index++);
794 writeSymbol(Writer, StringIndex, MSD, Layout);
795 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
796 }
797
798 uint64_t SecEnd = W.OS.tell();
799 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
800
801 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
802 if (ShndxIndexes.empty()) {
803 assert(SymtabShndxSectionIndex == 0);
804 return;
805 }
806 assert(SymtabShndxSectionIndex != 0);
807
808 SecStart = W.OS.tell();
809 const MCSectionELF *SymtabShndxSection =
810 SectionTable[SymtabShndxSectionIndex - 1];
811 for (uint32_t Index : ShndxIndexes)
812 write(Index);
813 SecEnd = W.OS.tell();
814 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
815}
816
817void ELFWriter::writeAddrsigSection() {
818 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
819 if (Sym->getIndex() != 0)
820 encodeULEB128(Sym->getIndex(), W.OS);
821}
822
823MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
824 const MCSectionELF &Sec) {
825 if (OWriter.Relocations[&Sec].empty())
826 return nullptr;
827
828 const StringRef SectionName = Sec.getName();
829 bool Rela = usesRela(Sec);
830 std::string RelaSectionName = Rela ? ".rela" : ".rel";
831 RelaSectionName += SectionName;
832
833 unsigned EntrySize;
834 if (Rela)
835 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
836 else
837 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
838
839 unsigned Flags = ELF::SHF_INFO_LINK;
840 if (Sec.getFlags() & ELF::SHF_GROUP)
841 Flags = ELF::SHF_GROUP;
842
843 MCSectionELF *RelaSection = Ctx.createELFRelSection(
844 RelaSectionName, Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, EntrySize,
845 Sec.getGroup(), &Sec);
846 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
847 return RelaSection;
848}
849
850// Include the debug info compression header.
851bool ELFWriter::maybeWriteCompression(
852 uint32_t ChType, uint64_t Size,
853 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
854 uint64_t HdrSize =
855 is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
856 if (Size <= HdrSize + CompressedContents.size())
857 return false;
858 // Platform specific header is followed by compressed data.
859 if (is64Bit()) {
860 // Write Elf64_Chdr header.
861 write(static_cast<ELF::Elf64_Word>(ChType));
862 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
863 write(static_cast<ELF::Elf64_Xword>(Size));
864 write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
865 } else {
866 // Write Elf32_Chdr header otherwise.
867 write(static_cast<ELF::Elf32_Word>(ChType));
868 write(static_cast<ELF::Elf32_Word>(Size));
869 write(static_cast<ELF::Elf32_Word>(Alignment.value()));
870 }
871 return true;
872}
873
874void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
875 const MCAsmLayout &Layout) {
876 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
877 StringRef SectionName = Section.getName();
878 auto &Ctx = Asm.getContext();
879 const DebugCompressionType CompressionType =
881 : DebugCompressionType::None;
882 if (CompressionType == DebugCompressionType::None ||
883 !SectionName.starts_with(".debug_")) {
884 Asm.writeSectionData(W.OS, &Section, Layout);
885 return;
886 }
887
888 SmallVector<char, 128> UncompressedData;
889 raw_svector_ostream VecOS(UncompressedData);
890 Asm.writeSectionData(VecOS, &Section, Layout);
891 ArrayRef<uint8_t> Uncompressed =
892 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
893 UncompressedData.size());
894
895 SmallVector<uint8_t, 128> Compressed;
896 uint32_t ChType;
897 switch (CompressionType) {
898 case DebugCompressionType::None:
899 llvm_unreachable("has been handled");
900 case DebugCompressionType::Zlib:
901 ChType = ELF::ELFCOMPRESS_ZLIB;
902 break;
903 case DebugCompressionType::Zstd:
904 ChType = ELF::ELFCOMPRESS_ZSTD;
905 break;
906 }
907 compression::compress(compression::Params(CompressionType), Uncompressed,
908 Compressed);
909 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
910 Sec.getAlign())) {
911 W.OS << UncompressedData;
912 return;
913 }
914
915 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
916 // Alignment field should reflect the requirements of
917 // the compressed section header.
918 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
919 W.OS << toStringRef(Compressed);
920}
921
922void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
923 uint64_t Address, uint64_t Offset,
924 uint64_t Size, uint32_t Link, uint32_t Info,
925 MaybeAlign Alignment, uint64_t EntrySize) {
926 W.write<uint32_t>(Name); // sh_name: index into string table
927 W.write<uint32_t>(Type); // sh_type
928 WriteWord(Flags); // sh_flags
929 WriteWord(Address); // sh_addr
930 WriteWord(Offset); // sh_offset
931 WriteWord(Size); // sh_size
932 W.write<uint32_t>(Link); // sh_link
933 W.write<uint32_t>(Info); // sh_info
934 WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
935 WriteWord(EntrySize); // sh_entsize
936}
937
938void ELFWriter::writeRelocations(const MCAssembler &Asm,
939 const MCSectionELF &Sec) {
940 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
941
942 // Sort the relocation entries. MIPS needs this.
943 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
944
945 const bool Rela = usesRela(Sec);
946 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
947 for (const ELFRelocationEntry &Entry : Relocs) {
948 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
949 if (is64Bit()) {
950 write(Entry.Offset);
951 write(uint32_t(Symidx));
952 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
953 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
954 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
955 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
956 if (Rela)
957 write(Entry.Addend);
958 } else {
959 write(uint32_t(Entry.Offset));
960 ELF::Elf32_Rela ERE32;
961 ERE32.setSymbolAndType(Symidx, Entry.Type);
962 write(ERE32.r_info);
963 if (Rela)
964 write(uint32_t(Entry.Addend));
965 if (uint32_t RType =
966 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
967 write(uint32_t(Entry.Offset));
968 ERE32.setSymbolAndType(0, RType);
969 write(ERE32.r_info);
970 write(uint32_t(0));
971 }
972 if (uint32_t RType =
973 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
974 write(uint32_t(Entry.Offset));
975 ERE32.setSymbolAndType(0, RType);
976 write(ERE32.r_info);
977 write(uint32_t(0));
978 }
979 }
980 }
981 return;
982 }
983 for (const ELFRelocationEntry &Entry : Relocs) {
984 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
985 if (is64Bit()) {
986 write(Entry.Offset);
987 ELF::Elf64_Rela ERE;
988 ERE.setSymbolAndType(Symidx, Entry.Type);
989 write(ERE.r_info);
990 if (Rela)
991 write(Entry.Addend);
992 } else {
993 write(uint32_t(Entry.Offset));
994 ELF::Elf32_Rela ERE;
995 ERE.setSymbolAndType(Symidx, Entry.Type);
996 write(ERE.r_info);
997 if (Rela)
998 write(uint32_t(Entry.Addend));
999 }
1000 }
1001}
1002
1003void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
1004 uint32_t GroupSymbolIndex, uint64_t Offset,
1005 uint64_t Size, const MCSectionELF &Section) {
1006 uint64_t sh_link = 0;
1007 uint64_t sh_info = 0;
1008
1009 switch(Section.getType()) {
1010 default:
1011 // Nothing to do.
1012 break;
1013
1014 case ELF::SHT_DYNAMIC:
1015 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1016
1017 case ELF::SHT_REL:
1018 case ELF::SHT_RELA: {
1019 sh_link = SymbolTableIndex;
1020 assert(sh_link && ".symtab not found");
1021 const MCSection *InfoSection = Section.getLinkedToSection();
1022 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
1023 break;
1024 }
1025
1026 case ELF::SHT_SYMTAB:
1027 sh_link = StringTableIndex;
1028 sh_info = LastLocalSymbolIndex;
1029 break;
1030
1034 sh_link = SymbolTableIndex;
1035 break;
1036
1037 case ELF::SHT_GROUP:
1038 sh_link = SymbolTableIndex;
1039 sh_info = GroupSymbolIndex;
1040 break;
1041 }
1042
1043 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
1044 // If the value in the associated metadata is not a definition, Sym will be
1045 // undefined. Represent this with sh_link=0.
1046 const MCSymbol *Sym = Section.getLinkedToSymbol();
1047 if (Sym && Sym->isInSection()) {
1048 const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
1049 sh_link = SectionIndexMap.lookup(Sec);
1050 }
1051 }
1052
1053 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
1054 Section.getType(), Section.getFlags(), 0, Offset, Size,
1055 sh_link, sh_info, Section.getAlign(),
1056 Section.getEntrySize());
1057}
1058
1059void ELFWriter::writeSectionHeader(
1060 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1061 const SectionOffsetsTy &SectionOffsets) {
1062 const unsigned NumSections = SectionTable.size();
1063
1064 // Null section first.
1065 uint64_t FirstSectionSize =
1066 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
1067 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
1068
1069 for (const MCSectionELF *Section : SectionTable) {
1070 uint32_t GroupSymbolIndex;
1071 unsigned Type = Section->getType();
1072 if (Type != ELF::SHT_GROUP)
1073 GroupSymbolIndex = 0;
1074 else
1075 GroupSymbolIndex = Section->getGroup()->getIndex();
1076
1077 const std::pair<uint64_t, uint64_t> &Offsets =
1078 SectionOffsets.find(Section)->second;
1079 uint64_t Size;
1080 if (Type == ELF::SHT_NOBITS)
1081 Size = Layout.getSectionAddressSize(Section);
1082 else
1083 Size = Offsets.second - Offsets.first;
1084
1085 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1086 *Section);
1087 }
1088}
1089
1090uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
1091 uint64_t StartOffset = W.OS.tell();
1092
1093 MCContext &Ctx = Asm.getContext();
1094 MCSectionELF *StrtabSection =
1095 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1096 StringTableIndex = addToSectionTable(StrtabSection);
1097
1098 createMemtagRelocs(Asm);
1099
1100 RevGroupMapTy RevGroupMap;
1101 SectionIndexMapTy SectionIndexMap;
1102
1103 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1104
1105 // Write out the ELF header ...
1106 writeHeader(Asm);
1107
1108 // ... then the sections ...
1109 SectionOffsetsTy SectionOffsets;
1110 std::vector<MCSectionELF *> Groups;
1111 std::vector<MCSectionELF *> Relocations;
1112 for (MCSection &Sec : Asm) {
1113 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1114 if (Mode == NonDwoOnly && isDwoSection(Section))
1115 continue;
1116 if (Mode == DwoOnly && !isDwoSection(Section))
1117 continue;
1118
1119 // Remember the offset into the file for this section.
1120 const uint64_t SecStart = align(Section.getAlign());
1121
1122 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1123 writeSectionData(Asm, Section, Layout);
1124
1125 uint64_t SecEnd = W.OS.tell();
1126 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1127
1128 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1129
1130 if (SignatureSymbol) {
1131 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1132 if (!GroupIdx) {
1133 MCSectionELF *Group =
1134 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1135 GroupIdx = addToSectionTable(Group);
1136 Group->setAlignment(Align(4));
1137 Groups.push_back(Group);
1138 }
1139 std::vector<const MCSectionELF *> &Members =
1140 GroupMembers[SignatureSymbol];
1141 Members.push_back(&Section);
1142 if (RelSection)
1143 Members.push_back(RelSection);
1144 }
1145
1146 SectionIndexMap[&Section] = addToSectionTable(&Section);
1147 if (RelSection) {
1148 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1149 Relocations.push_back(RelSection);
1150 }
1151
1152 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
1153 }
1154
1155 for (MCSectionELF *Group : Groups) {
1156 // Remember the offset into the file for this section.
1157 const uint64_t SecStart = align(Group->getAlign());
1158
1159 const MCSymbol *SignatureSymbol = Group->getGroup();
1160 assert(SignatureSymbol);
1161 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1162 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1163 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1164 write(SecIndex);
1165 }
1166
1167 uint64_t SecEnd = W.OS.tell();
1168 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1169 }
1170
1171 if (Mode == DwoOnly) {
1172 // dwo files don't have symbol tables or relocations, but they do have
1173 // string tables.
1174 StrTabBuilder.finalize();
1175 } else {
1176 MCSectionELF *AddrsigSection;
1177 if (OWriter.EmitAddrsigSection) {
1178 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1180 addToSectionTable(AddrsigSection);
1181 }
1182
1183 // Compute symbol table information.
1184 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1185 SectionOffsets);
1186
1187 for (MCSectionELF *RelSection : Relocations) {
1188 // Remember the offset into the file for this section.
1189 const uint64_t SecStart = align(RelSection->getAlign());
1190
1191 writeRelocations(Asm,
1192 cast<MCSectionELF>(*RelSection->getLinkedToSection()));
1193
1194 uint64_t SecEnd = W.OS.tell();
1195 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1196 }
1197
1198 if (OWriter.EmitAddrsigSection) {
1199 uint64_t SecStart = W.OS.tell();
1200 writeAddrsigSection();
1201 uint64_t SecEnd = W.OS.tell();
1202 SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1203 }
1204 }
1205
1206 {
1207 uint64_t SecStart = W.OS.tell();
1208 StrTabBuilder.write(W.OS);
1209 SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
1210 }
1211
1212 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1213
1214 // ... then the section header table ...
1215 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1216
1217 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1218 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1219 : SectionTable.size() + 1,
1220 W.Endian);
1221 unsigned NumSectionsOffset;
1222
1223 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1224 if (is64Bit()) {
1225 uint64_t Val =
1226 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1227 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1228 offsetof(ELF::Elf64_Ehdr, e_shoff));
1229 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1230 } else {
1231 uint32_t Val =
1232 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1233 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1234 offsetof(ELF::Elf32_Ehdr, e_shoff));
1235 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1236 }
1237 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1238 NumSectionsOffset);
1239
1240 return W.OS.tell() - StartOffset;
1241}
1242
1243bool ELFObjectWriter::hasRelocationAddend() const {
1244 return TargetObjectWriter->hasRelocationAddend();
1245}
1246
1247void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1248 const MCAsmLayout &Layout) {
1249 // The presence of symbol versions causes undefined symbols and
1250 // versions declared with @@@ to be renamed.
1251 for (const MCAssembler::Symver &S : Asm.Symvers) {
1252 StringRef AliasName = S.Name;
1253 const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
1254 size_t Pos = AliasName.find('@');
1255 assert(Pos != StringRef::npos);
1256
1257 StringRef Prefix = AliasName.substr(0, Pos);
1258 StringRef Rest = AliasName.substr(Pos);
1259 StringRef Tail = Rest;
1260 if (Rest.starts_with("@@@"))
1261 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1262
1263 auto *Alias =
1264 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1265 Asm.registerSymbol(*Alias);
1266 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1267 Alias->setVariableValue(Value);
1268
1269 // Aliases defined with .symvar copy the binding from the symbol they alias.
1270 // This is the first place we are able to copy this information.
1271 Alias->setBinding(Symbol.getBinding());
1272 Alias->setVisibility(Symbol.getVisibility());
1273 Alias->setOther(Symbol.getOther());
1274
1275 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1276 continue;
1277
1278 if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1279 !Rest.starts_with("@@@")) {
1280 Asm.getContext().reportError(S.Loc, "default version symbol " +
1281 AliasName + " must be defined");
1282 continue;
1283 }
1284
1285 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1286 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1287 Symbol.getName());
1288 continue;
1289 }
1290
1291 Renames.insert(std::make_pair(&Symbol, Alias));
1292 }
1293
1294 for (const MCSymbol *&Sym : AddrsigSyms) {
1295 if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1296 Sym = R;
1297 if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1298 Sym = Sym->getSection().getBeginSymbol();
1299 Sym->setUsedInReloc();
1300 }
1301}
1302
1303// It is always valid to create a relocation with a symbol. It is preferable
1304// to use a relocation with a section if that is possible. Using the section
1305// allows us to omit some local symbols from the symbol table.
1306bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1307 const MCValue &Val,
1308 const MCSymbolELF *Sym,
1309 uint64_t C,
1310 unsigned Type) const {
1311 const MCSymbolRefExpr *RefA = Val.getSymA();
1312 // A PCRel relocation to an absolute value has no symbol (or section). We
1313 // represent that with a relocation to a null section.
1314 if (!RefA)
1315 return false;
1316
1318 switch (Kind) {
1319 default:
1320 break;
1321 // The .odp creation emits a relocation against the symbol ".TOC." which
1322 // create a R_PPC64_TOC relocation. However the relocation symbol name
1323 // in final object creation should be NULL, since the symbol does not
1324 // really exist, it is just the reference to TOC base for the current
1325 // object file. Since the symbol is undefined, returning false results
1326 // in a relocation with a null section which is the desired result.
1328 return false;
1329
1330 // These VariantKind cause the relocation to refer to something other than
1331 // the symbol itself, like a linker generated table. Since the address of
1332 // symbol is not relevant, we cannot replace the symbol with the
1333 // section and patch the difference in the addend.
1341 return true;
1342 }
1343
1344 // An undefined symbol is not in any section, so the relocation has to point
1345 // to the symbol itself.
1346 assert(Sym && "Expected a symbol");
1347 if (Sym->isUndefined())
1348 return true;
1349
1350 // For memory-tagged symbols, ensure that the relocation uses the symbol. For
1351 // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
1352 // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
1353 // this global needs to be tagged. In addition, the linker needs to know
1354 // whether to emit a special addend when relocating `end` symbols, and this
1355 // can only be determined by the attributes of the symbol itself.
1356 if (Sym->isMemtag())
1357 return true;
1358
1359 unsigned Binding = Sym->getBinding();
1360 switch(Binding) {
1361 default:
1362 llvm_unreachable("Invalid Binding");
1363 case ELF::STB_LOCAL:
1364 break;
1365 case ELF::STB_WEAK:
1366 // If the symbol is weak, it might be overridden by a symbol in another
1367 // file. The relocation has to point to the symbol so that the linker
1368 // can update it.
1369 return true;
1370 case ELF::STB_GLOBAL:
1372 // Global ELF symbols can be preempted by the dynamic linker. The relocation
1373 // has to point to the symbol for a reason analogous to the STB_WEAK case.
1374 return true;
1375 }
1376
1377 // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1378 // reloc that the dynamic loader will use to resolve the address at startup
1379 // time.
1380 if (Sym->getType() == ELF::STT_GNU_IFUNC)
1381 return true;
1382
1383 // If a relocation points to a mergeable section, we have to be careful.
1384 // If the offset is zero, a relocation with the section will encode the
1385 // same information. With a non-zero offset, the situation is different.
1386 // For example, a relocation can point 42 bytes past the end of a string.
1387 // If we change such a relocation to use the section, the linker would think
1388 // that it pointed to another string and subtracting 42 at runtime will
1389 // produce the wrong value.
1390 if (Sym->isInSection()) {
1391 auto &Sec = cast<MCSectionELF>(Sym->getSection());
1392 unsigned Flags = Sec.getFlags();
1393 if (Flags & ELF::SHF_MERGE) {
1394 if (C != 0)
1395 return true;
1396
1397 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1398 // (http://sourceware.org/PR16794).
1399 if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1400 Type == ELF::R_386_GOTOFF)
1401 return true;
1402
1403 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1404 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1405 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1406 // range of a MergeInputSection. We could introduce a new RelExpr member
1407 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1408 // but the complexity is unnecessary given that GNU as keeps the original
1409 // symbol for this case as well.
1410 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1411 !hasRelocationAddend())
1412 return true;
1413 }
1414
1415 // Most TLS relocations use a got, so they need the symbol. Even those that
1416 // are just an offset (@tpoff), require a symbol in gold versions before
1417 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1418 // http://sourceware.org/PR16773.
1419 if (Flags & ELF::SHF_TLS)
1420 return true;
1421 }
1422
1423 // If the symbol is a thumb function the final relocation must set the lowest
1424 // bit. With a symbol that is done by just having the symbol have that bit
1425 // set, so we would lose the bit if we relocated with the section.
1426 // FIXME: We could use the section but add the bit to the relocation value.
1427 if (Asm.isThumbFunc(Sym))
1428 return true;
1429
1430 if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type))
1431 return true;
1432 return false;
1433}
1434
1435void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1436 const MCAsmLayout &Layout,
1437 const MCFragment *Fragment,
1438 const MCFixup &Fixup, MCValue Target,
1439 uint64_t &FixedValue) {
1440 MCAsmBackend &Backend = Asm.getBackend();
1441 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1443 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1444 uint64_t C = Target.getConstant();
1445 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1446 MCContext &Ctx = Asm.getContext();
1447
1448 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1449 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1450 if (SymB.isUndefined()) {
1451 Ctx.reportError(Fixup.getLoc(),
1452 Twine("symbol '") + SymB.getName() +
1453 "' can not be undefined in a subtraction expression");
1454 return;
1455 }
1456
1457 assert(!SymB.isAbsolute() && "Should have been folded");
1458 const MCSection &SecB = SymB.getSection();
1459 if (&SecB != &FixupSection) {
1460 Ctx.reportError(Fixup.getLoc(),
1461 "Cannot represent a difference across sections");
1462 return;
1463 }
1464
1465 assert(!IsPCRel && "should have been folded");
1466 IsPCRel = true;
1467 C += FixupOffset - Layout.getSymbolOffset(SymB);
1468 }
1469
1470 // We either rejected the fixup or folded B into C at this point.
1471 const MCSymbolRefExpr *RefA = Target.getSymA();
1472 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1473
1474 bool ViaWeakRef = false;
1475 if (SymA && SymA->isVariable()) {
1476 const MCExpr *Expr = SymA->getVariableValue();
1477 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1478 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1479 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1480 ViaWeakRef = true;
1481 }
1482 }
1483 }
1484
1485 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1486 ? cast<MCSectionELF>(&SymA->getSection())
1487 : nullptr;
1488 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1489 return;
1490
1491 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1492 const auto *Parent = cast<MCSectionELF>(Fragment->getParent());
1493 // Emiting relocation with sybmol for CG Profile to help with --cg-profile.
1494 bool RelocateWithSymbol =
1495 shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||
1496 (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
1497 uint64_t Addend = 0;
1498
1499 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1500 ? C + Layout.getSymbolOffset(*SymA)
1501 : C;
1502 if (hasRelocationAddend()) {
1503 Addend = FixedValue;
1504 FixedValue = 0;
1505 }
1506
1507 if (!RelocateWithSymbol) {
1508 const auto *SectionSymbol =
1509 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1510 if (SectionSymbol)
1511 SectionSymbol->setUsedInReloc();
1512 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
1513 Relocations[&FixupSection].push_back(Rec);
1514 return;
1515 }
1516
1517 const MCSymbolELF *RenamedSymA = SymA;
1518 if (SymA) {
1519 if (const MCSymbolELF *R = Renames.lookup(SymA))
1520 RenamedSymA = R;
1521
1522 if (ViaWeakRef)
1523 RenamedSymA->setIsWeakrefUsedInReloc();
1524 else
1525 RenamedSymA->setUsedInReloc();
1526 }
1527 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1528 Relocations[&FixupSection].push_back(Rec);
1529}
1530
1531bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1532 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1533 bool InSet, bool IsPCRel) const {
1534 const auto &SymA = cast<MCSymbolELF>(SA);
1535 if (IsPCRel) {
1536 assert(!InSet);
1537 if (SymA.getBinding() != ELF::STB_LOCAL ||
1538 SymA.getType() == ELF::STT_GNU_IFUNC)
1539 return false;
1540 }
1542 InSet, IsPCRel);
1543}
1544
1545std::unique_ptr<MCObjectWriter>
1546llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1547 raw_pwrite_stream &OS, bool IsLittleEndian) {
1548 return std::make_unique<ELFSingleObjectWriter>(std::move(MOTW), OS,
1549 IsLittleEndian);
1550}
1551
1552std::unique_ptr<MCObjectWriter>
1553llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1555 bool IsLittleEndian) {
1556 return std::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1557 IsLittleEndian);
1558}
#define offsetof(TYPE, MEMBER)
BlockVerifier::State From
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
Given that RA is a live value
This file defines the DenseMap class.
std::string Name
uint64_t Size
static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType)
static bool isIFunc(const MCSymbolELF *Symbol)
std::optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1291
Symbol * Sym
Definition: ELF_riscv.cpp:479
lazy value info
#define F(x, y, z)
Definition: MD5.cpp:55
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:49
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
static bool isInSymtab(const MCSymbolWasm &Sym)
static bool isDwoSection(const MCSection &Sec)
static bool is64Bit(const char *name)
static const X86InstrFMA3Group Groups[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:43
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const
If this symbol is equivalent to A + Constant, return A.
Definition: MCFragment.cpp:162
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
Definition: MCFragment.cpp:198
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
Definition: MCFragment.cpp:152
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Definition: MCFragment.cpp:96
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:50
bool isThumbFunc(const MCSymbol *Func) const
Check whether a given symbol has been flagged with .thumb_func.
Context object for machine code objects.
Definition: MCContext.h:76
MCSectionELF * createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, const MCSectionELF *RelInfoSection)
Definition: MCContext.cpp:504
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:567
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1064
const MCTargetOptions * getTargetOptions() const
Definition: MCContext.h:454
MCSectionELF * createELFGroupSection(const MCSymbolELF *Group, bool IsComdat)
Definition: MCContext.cpp:607
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const
Definition: MCExpr.cpp:572
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
MCSection * getParent() const
Definition: MCFragment.h:96
Defines the object file and target independent interfaces used by the assembler backend to write nati...
virtual void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
virtual void reset()
lifetime management
virtual void markGnuAbi()
ELF only. Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN).
virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const
virtual void setOverrideABIVersion(uint8_t ABIVersion)
ELF only, override the default ABIVersion in the ELF header.
virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
Record a relocation entry.
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:26
const MCSection * getLinkedToSection() const
Definition: MCSectionELF.h:89
unsigned getFlags() const
Definition: MCSectionELF.h:73
const MCSymbolELF * getGroup() const
Definition: MCSectionELF.h:76
unsigned getType() const
Definition: MCSectionELF.h:72
bool isComdat() const
Definition: MCSectionELF.h:77
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
void setAlignment(Align Value)
Definition: MCSection.h:141
Align getAlign() const
Definition: MCSection.h:140
StringRef getName() const
Definition: MCSection.h:124
MCSymbol * getBeginSymbol()
Definition: MCSection.h:129
void setIsWeakrefUsedInReloc() const
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:410
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
VariantKind getKind() const
Definition: MCExpr.h:412
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
void setUsedInReloc() const
Definition: MCSymbol.h:215
DebugCompressionType CompressDebugSections
This represents an "assembler immediate".
Definition: MCValue.h:36
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:44
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
Represents a location in source code.
Definition: SMLoc.h:23
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:299
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:567
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:257
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:293
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:271
static constexpr size_t npos
Definition: StringRef.h:52
Utility for building string tables with deduplicated suffixes.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:444
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:690
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition: CallingConv.h:76
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ SHF_MERGE
Definition: ELF.h:1163
@ SHF_INFO_LINK
Definition: ELF.h:1169
@ SHF_EXCLUDE
Definition: ELF.h:1191
@ SHF_LINK_ORDER
Definition: ELF.h:1172
@ SHF_GROUP
Definition: ELF.h:1179
@ SHF_COMPRESSED
Definition: ELF.h:1185
@ SHF_TLS
Definition: ELF.h:1182
@ EM_386
Definition: ELF.h:136
@ EM_MIPS
Definition: ELF.h:141
@ STV_DEFAULT
Definition: ELF.h:1340
@ ELFDATA2MSB
Definition: ELF.h:336
@ ELFDATA2LSB
Definition: ELF.h:335
@ ELFCLASS64
Definition: ELF.h:329
@ ELFCLASS32
Definition: ELF.h:328
@ ELFOSABI_GNU
Definition: ELF.h:344
@ ELFOSABI_NONE
Definition: ELF.h:341
@ SHN_XINDEX
Definition: ELF.h:1056
@ SHN_ABS
Definition: ELF.h:1054
@ SHN_COMMON
Definition: ELF.h:1055
@ SHN_UNDEF
Definition: ELF.h:1048
@ SHN_LORESERVE
Definition: ELF.h:1049
static const char ElfMagic[]
Definition: ELF.h:44
@ SHT_STRTAB
Definition: ELF.h:1065
@ SHT_GROUP
Definition: ELF.h:1077
@ SHT_REL
Definition: ELF.h:1071
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition: ELF.h:1099
@ SHT_NOBITS
Definition: ELF.h:1070
@ SHT_SYMTAB
Definition: ELF.h:1064
@ SHT_DYNAMIC
Definition: ELF.h:1068
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1078
@ SHT_LLVM_ADDRSIG
Definition: ELF.h:1089
@ SHT_RELA
Definition: ELF.h:1066
@ GRP_COMDAT
Definition: ELF.h:1257
@ ELFCOMPRESS_ZSTD
Definition: ELF.h:1913
@ ELFCOMPRESS_ZLIB
Definition: ELF.h:1912
@ EI_PAD
Definition: ELF.h:57
@ EI_NIDENT
Definition: ELF.h:58
@ STB_GLOBAL
Definition: ELF.h:1311
@ STB_LOCAL
Definition: ELF.h:1310
@ STB_GNU_UNIQUE
Definition: ELF.h:1313
@ STB_WEAK
Definition: ELF.h:1312
@ EV_CURRENT
Definition: ELF.h:127
@ ET_REL
Definition: ELF.h:116
@ SYMENTRY_SIZE32
Definition: ELF.h:1304
@ SYMENTRY_SIZE64
Definition: ELF.h:1305
@ STT_FUNC
Definition: ELF.h:1324
@ STT_NOTYPE
Definition: ELF.h:1322
@ STT_SECTION
Definition: ELF.h:1325
@ STT_FILE
Definition: ELF.h:1326
@ STT_GNU_IFUNC
Definition: ELF.h:1329
@ STT_OBJECT
Definition: ELF.h:1323
@ STT_TLS
Definition: ELF.h:1328
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1522
void compress(Params P, ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &Output)
Definition: Compression.cpp:46
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1689
std::unique_ptr< MCObjectWriter > createELFObjectWriter(std::unique_ptr< MCELFObjectTargetWriter > MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new ELF writer instance.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
Definition: STLExtras.h:2415
std::unique_ptr< MCObjectWriter > createELFDwoObjectWriter(std::unique_ptr< MCELFObjectTargetWriter > MOTW, raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS, bool IsLittleEndian)
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Definition: DWP.cpp:601
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
@ Ref
The access may reference the value stored in memory.
DebugCompressionType
Definition: Compression.h:27
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Elf32_Word r_info
Definition: ELF.h:1376
void setSymbolAndType(Elf32_Word s, unsigned char t)
Definition: ELF.h:1385
void setSymbolAndType(Elf64_Word s, Elf64_Word t)
Definition: ELF.h:1421
Elf64_Xword r_info
Definition: ELF.h:1412
const MCSymbol * Sym
Definition: MCAssembler.h:235
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
unsigned Flags
Flags describing additional information on this fixup kind.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67