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
145 uint64_t align(Align Alignment);
146
147 bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
148 SmallVectorImpl<uint8_t> &CompressedContents,
149 Align Alignment);
150
151public:
152 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
153 bool IsLittleEndian, DwoMode Mode)
154 : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little
156 Mode(Mode) {}
157
158 void WriteWord(uint64_t Word) {
159 if (is64Bit())
160 W.write<uint64_t>(Word);
161 else
162 W.write<uint32_t>(Word);
163 }
164
165 template <typename T> void write(T Val) {
166 W.write(Val);
167 }
168
169 void writeHeader(const MCAssembler &Asm);
170
171 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
172 ELFSymbolData &MSD, const MCAsmLayout &Layout);
173
174 // Start and end offset of each section
175 using SectionOffsetsTy =
176 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
177
178 // Map from a signature symbol to the group section index
179 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
180
181 /// Compute the symbol table data
182 ///
183 /// \param Asm - The assembler.
184 /// \param SectionIndexMap - Maps a section to its index.
185 /// \param RevGroupMap - Maps a signature symbol to the group section.
186 void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
187 const SectionIndexMapTy &SectionIndexMap,
188 const RevGroupMapTy &RevGroupMap,
189 SectionOffsetsTy &SectionOffsets);
190
191 void writeAddrsigSection();
192
193 MCSectionELF *createRelocationSection(MCContext &Ctx,
194 const MCSectionELF &Sec);
195
196 void createMemtagRelocs(MCAssembler &Asm);
197
198 void writeSectionHeader(const MCAsmLayout &Layout,
199 const SectionIndexMapTy &SectionIndexMap,
200 const SectionOffsetsTy &SectionOffsets);
201
202 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
203 const MCAsmLayout &Layout);
204
205 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
207 uint32_t Link, uint32_t Info, MaybeAlign Alignment,
208 uint64_t EntrySize);
209
210 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
211
212 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
213 void writeSection(const SectionIndexMapTy &SectionIndexMap,
214 uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
215 const MCSectionELF &Section);
216};
217
218class ELFObjectWriter : public MCObjectWriter {
219 /// The target specific ELF writer instance.
220 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
221
223
225
226 bool SeenGnuAbi = false;
227
228 std::optional<uint8_t> OverrideABIVersion;
229
230 bool hasRelocationAddend() const;
231
232 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
233 const MCSymbolELF *Sym, uint64_t C,
234 unsigned Type) const;
235
236public:
237 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
238 : TargetObjectWriter(std::move(MOTW)) {}
239
240 void reset() override {
241 SeenGnuAbi = false;
242 OverrideABIVersion.reset();
243 Relocations.clear();
244 Renames.clear();
246 }
247
249 const MCSymbol &SymA,
250 const MCFragment &FB, bool InSet,
251 bool IsPCRel) const override;
252
253 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
254 const MCSectionELF *From,
255 const MCSectionELF *To) {
256 return true;
257 }
258
259 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
260 const MCFragment *Fragment, const MCFixup &Fixup,
261 MCValue Target, uint64_t &FixedValue) override;
262 bool usesRela(const MCSectionELF &Sec) const;
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
397// Emit the ELF header.
398void ELFWriter::writeHeader(const MCAssembler &Asm) {
399 // ELF Header
400 // ----------
401 //
402 // Note
403 // ----
404 // emitWord method behaves differently for ELF32 and ELF64, writing
405 // 4 bytes in the former and 8 in the latter.
406
407 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
408
409 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
410
411 // e_ident[EI_DATA]
414
415 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
416 // e_ident[EI_OSABI]
417 uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
418 W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()
419 ? int(ELF::ELFOSABI_GNU)
420 : OSABI);
421 // e_ident[EI_ABIVERSION]
422 W.OS << char(OWriter.seenOverrideABIVersion()
423 ? OWriter.getOverrideABIVersion()
424 : OWriter.TargetObjectWriter->getABIVersion());
425
426 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
427
428 W.write<uint16_t>(ELF::ET_REL); // e_type
429
430 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
431
432 W.write<uint32_t>(ELF::EV_CURRENT); // e_version
433 WriteWord(0); // e_entry, no entry point in .o file
434 WriteWord(0); // e_phoff, no program header for .o
435 WriteWord(0); // e_shoff = sec hdr table off in bytes
436
437 // e_flags = whatever the target wants
438 W.write<uint32_t>(Asm.getELFHeaderEFlags());
439
440 // e_ehsize = ELF header size
441 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
442 : sizeof(ELF::Elf32_Ehdr));
443
444 W.write<uint16_t>(0); // e_phentsize = prog header entry size
445 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
446
447 // e_shentsize = Section header entry size
448 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
449 : sizeof(ELF::Elf32_Shdr));
450
451 // e_shnum = # of section header ents
452 W.write<uint16_t>(0);
453
454 // e_shstrndx = Section # of '.strtab'
455 assert(StringTableIndex < ELF::SHN_LORESERVE);
456 W.write<uint16_t>(StringTableIndex);
457}
458
459uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
460 const MCAsmLayout &Layout) {
461 if (Sym.isCommon())
462 return Sym.getCommonAlignment()->value();
463
464 uint64_t Res;
465 if (!Layout.getSymbolOffset(Sym, Res))
466 return 0;
467
468 if (Layout.getAssembler().isThumbFunc(&Sym))
469 Res |= 1;
470
471 return Res;
472}
473
474static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
475 uint8_t Type = newType;
476
477 // Propagation rules:
478 // IFUNC > FUNC > OBJECT > NOTYPE
479 // TLS_OBJECT > OBJECT > NOTYPE
480 //
481 // dont let the new type degrade the old type
482 switch (origType) {
483 default:
484 break;
486 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
489 break;
490 case ELF::STT_FUNC:
494 break;
495 case ELF::STT_OBJECT:
496 if (Type == ELF::STT_NOTYPE)
498 break;
499 case ELF::STT_TLS:
503 break;
504 }
505
506 return Type;
507}
508
509static bool isIFunc(const MCSymbolELF *Symbol) {
510 while (Symbol->getType() != ELF::STT_GNU_IFUNC) {
511 const MCSymbolRefExpr *Value;
512 if (!Symbol->isVariable() ||
513 !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) ||
514 Value->getKind() != MCSymbolRefExpr::VK_None ||
516 return false;
517 Symbol = &cast<MCSymbolELF>(Value->getSymbol());
518 }
519 return true;
520}
521
522void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
523 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
524 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
525 const MCSymbolELF *Base =
526 cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
527
528 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
529 // SHN_COMMON.
530 bool IsReserved = !Base || Symbol.isCommon();
531
532 // Binding and Type share the same byte as upper and lower nibbles
533 uint8_t Binding = Symbol.getBinding();
534 uint8_t Type = Symbol.getType();
535 if (isIFunc(&Symbol))
537 if (Base) {
538 Type = mergeTypeForSet(Type, Base->getType());
539 }
540 uint8_t Info = (Binding << 4) | Type;
541
542 // Other and Visibility share the same byte with Visibility using the lower
543 // 2 bits
544 uint8_t Visibility = Symbol.getVisibility();
545 uint8_t Other = Symbol.getOther() | Visibility;
546
547 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
548 uint64_t Size = 0;
549
550 const MCExpr *ESize = MSD.Symbol->getSize();
551 if (!ESize && Base) {
552 // For expressions like .set y, x+1, if y's size is unset, inherit from x.
553 ESize = Base->getSize();
554
555 // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
556 // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
557 // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
558 // needs. MCBinaryExpr is not handled.
559 const MCSymbolELF *Sym = &Symbol;
560 while (Sym->isVariable()) {
561 if (auto *Expr =
562 dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
563 Sym = cast<MCSymbolELF>(&Expr->getSymbol());
564 if (!Sym->getSize())
565 continue;
566 ESize = Sym->getSize();
567 }
568 break;
569 }
570 }
571
572 if (ESize) {
573 int64_t Res;
574 if (!ESize->evaluateKnownAbsolute(Res, Layout))
575 report_fatal_error("Size expression must be absolute.");
576 Size = Res;
577 }
578
579 // Write out the symbol table entry
580 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
581 IsReserved);
582}
583
584bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
585 bool Used, bool Renamed) {
586 if (Symbol.isVariable()) {
587 const MCExpr *Expr = Symbol.getVariableValue();
588 // Target Expressions that are always inlined do not appear in the symtab
589 if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
590 if (T->inlineAssignedExpr())
591 return false;
592 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
593 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
594 return false;
595 }
596 }
597
598 if (Used)
599 return true;
600
601 if (Renamed)
602 return false;
603
604 if (Symbol.isVariable() && Symbol.isUndefined()) {
605 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
606 Layout.getBaseSymbol(Symbol);
607 return false;
608 }
609
610 if (Symbol.isTemporary())
611 return false;
612
613 if (Symbol.getType() == ELF::STT_SECTION)
614 return false;
615
616 return true;
617}
618
619void ELFWriter::createMemtagRelocs(MCAssembler &Asm) {
620 MCSectionELF *MemtagRelocs = nullptr;
621 for (const MCSymbol &Sym : Asm.symbols()) {
622 const auto &SymE = cast<MCSymbolELF>(Sym);
623 if (!SymE.isMemtag())
624 continue;
625 if (MemtagRelocs == nullptr) {
626 MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(Asm.getContext());
627 if (MemtagRelocs == nullptr)
628 report_fatal_error("Tagged globals are not available on this architecture.");
629 Asm.registerSection(*MemtagRelocs);
630 }
631 ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
632 OWriter.Relocations[MemtagRelocs].push_back(Rec);
633 }
634}
635
636void ELFWriter::computeSymbolTable(
637 MCAssembler &Asm, const MCAsmLayout &Layout,
638 const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
639 SectionOffsetsTy &SectionOffsets) {
640 MCContext &Ctx = Asm.getContext();
641 SymbolTableWriter Writer(*this, is64Bit());
642
643 // Symbol table
644 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
645 MCSectionELF *SymtabSection =
646 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
647 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
648 SymbolTableIndex = addToSectionTable(SymtabSection);
649
650 uint64_t SecStart = align(SymtabSection->getAlign());
651
652 // The first entry is the undefined symbol entry.
653 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
654
655 std::vector<ELFSymbolData> LocalSymbolData;
656 std::vector<ELFSymbolData> ExternalSymbolData;
658 Asm.getFileNames();
659 for (const std::pair<std::string, size_t> &F : FileNames)
660 StrTabBuilder.add(F.first);
661
662 // Add the data for the symbols.
663 bool HasLargeSectionIndex = false;
664 for (auto It : llvm::enumerate(Asm.symbols())) {
665 const auto &Symbol = cast<MCSymbolELF>(It.value());
666 bool Used = Symbol.isUsedInReloc();
667 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
668 bool isSignature = Symbol.isSignature();
669
670 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
671 OWriter.Renames.count(&Symbol)))
672 continue;
673
674 if (Symbol.isTemporary() && Symbol.isUndefined()) {
675 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
676 continue;
677 }
678
679 ELFSymbolData MSD;
680 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
681 MSD.Order = It.index();
682
683 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
684 assert(Local || !Symbol.isTemporary());
685
686 if (Symbol.isAbsolute()) {
687 MSD.SectionIndex = ELF::SHN_ABS;
688 } else if (Symbol.isCommon()) {
689 if (Symbol.isTargetCommon()) {
690 MSD.SectionIndex = Symbol.getIndex();
691 } else {
692 assert(!Local);
693 MSD.SectionIndex = ELF::SHN_COMMON;
694 }
695 } else if (Symbol.isUndefined()) {
696 if (isSignature && !Used) {
697 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
698 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
699 HasLargeSectionIndex = true;
700 } else {
701 MSD.SectionIndex = ELF::SHN_UNDEF;
702 }
703 } else {
704 const MCSectionELF &Section =
705 static_cast<const MCSectionELF &>(Symbol.getSection());
706
707 // We may end up with a situation when section symbol is technically
708 // defined, but should not be. That happens because we explicitly
709 // pre-create few .debug_* sections to have accessors.
710 // And if these sections were not really defined in the code, but were
711 // referenced, we simply error out.
712 if (!Section.isRegistered()) {
713 assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
715 Ctx.reportError(SMLoc(),
716 "Undefined section reference: " + Symbol.getName());
717 continue;
718 }
719
720 if (Mode == NonDwoOnly && isDwoSection(Section))
721 continue;
722 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
723 assert(MSD.SectionIndex && "Invalid section index!");
724 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
725 HasLargeSectionIndex = true;
726 }
727
728 // Temporary symbols generated for certain assembler features (.eh_frame,
729 // .debug_line) of an empty name may be referenced by relocations due to
730 // linker relaxation. Rename them to ".L0 " to match the gas fake label name
731 // and allow ld/objcopy --discard-locals to discard such symbols.
732 StringRef Name = Symbol.getName();
733 if (Name.empty())
734 Name = ".L0 ";
735
736 // Sections have their own string table
737 if (Symbol.getType() != ELF::STT_SECTION) {
738 MSD.Name = Name;
739 StrTabBuilder.add(Name);
740 }
741
742 if (Local)
743 LocalSymbolData.push_back(MSD);
744 else
745 ExternalSymbolData.push_back(MSD);
746 }
747
748 // This holds the .symtab_shndx section index.
749 unsigned SymtabShndxSectionIndex = 0;
750
751 if (HasLargeSectionIndex) {
752 MCSectionELF *SymtabShndxSection =
753 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
754 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
755 SymtabShndxSection->setAlignment(Align(4));
756 }
757
758 StrTabBuilder.finalize();
759
760 // Make the first STT_FILE precede previous local symbols.
761 unsigned Index = 1;
762 auto FileNameIt = FileNames.begin();
763 if (!FileNames.empty())
764 FileNames[0].second = 0;
765
766 for (ELFSymbolData &MSD : LocalSymbolData) {
767 // Emit STT_FILE symbols before their associated local symbols.
768 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
769 ++FileNameIt) {
770 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
772 ELF::SHN_ABS, true);
773 ++Index;
774 }
775
776 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
777 ? 0
778 : StrTabBuilder.getOffset(MSD.Name);
779 MSD.Symbol->setIndex(Index++);
780 writeSymbol(Writer, StringIndex, MSD, Layout);
781 }
782 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
783 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
785 ELF::SHN_ABS, true);
786 ++Index;
787 }
788
789 // Write the symbol table entries.
790 LastLocalSymbolIndex = Index;
791
792 for (ELFSymbolData &MSD : ExternalSymbolData) {
793 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
794 MSD.Symbol->setIndex(Index++);
795 writeSymbol(Writer, StringIndex, MSD, Layout);
796 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
797 }
798
799 uint64_t SecEnd = W.OS.tell();
800 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
801
802 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
803 if (ShndxIndexes.empty()) {
804 assert(SymtabShndxSectionIndex == 0);
805 return;
806 }
807 assert(SymtabShndxSectionIndex != 0);
808
809 SecStart = W.OS.tell();
810 const MCSectionELF *SymtabShndxSection =
811 SectionTable[SymtabShndxSectionIndex - 1];
812 for (uint32_t Index : ShndxIndexes)
813 write(Index);
814 SecEnd = W.OS.tell();
815 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
816}
817
818void ELFWriter::writeAddrsigSection() {
819 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
820 if (Sym->getIndex() != 0)
821 encodeULEB128(Sym->getIndex(), W.OS);
822}
823
824MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
825 const MCSectionELF &Sec) {
826 if (OWriter.Relocations[&Sec].empty())
827 return nullptr;
828
829 unsigned Flags = ELF::SHF_INFO_LINK;
830 if (Sec.getFlags() & ELF::SHF_GROUP)
832
833 const StringRef SectionName = Sec.getName();
834 const bool Rela = OWriter.usesRela(Sec);
835 unsigned EntrySize;
836 if (Rela)
837 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
838 else
839 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
840
841 MCSectionELF *RelaSection =
842 Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName),
844 EntrySize, Sec.getGroup(), &Sec);
845 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
846 return RelaSection;
847}
848
849// Include the debug info compression header.
850bool ELFWriter::maybeWriteCompression(
851 uint32_t ChType, uint64_t Size,
852 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
853 uint64_t HdrSize =
854 is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
855 if (Size <= HdrSize + CompressedContents.size())
856 return false;
857 // Platform specific header is followed by compressed data.
858 if (is64Bit()) {
859 // Write Elf64_Chdr header.
860 write(static_cast<ELF::Elf64_Word>(ChType));
861 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
862 write(static_cast<ELF::Elf64_Xword>(Size));
863 write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
864 } else {
865 // Write Elf32_Chdr header otherwise.
866 write(static_cast<ELF::Elf32_Word>(ChType));
867 write(static_cast<ELF::Elf32_Word>(Size));
868 write(static_cast<ELF::Elf32_Word>(Alignment.value()));
869 }
870 return true;
871}
872
873void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
874 const MCAsmLayout &Layout) {
875 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
876 StringRef SectionName = Section.getName();
877 auto &Ctx = Asm.getContext();
878 const DebugCompressionType CompressionType =
880 : DebugCompressionType::None;
881 if (CompressionType == DebugCompressionType::None ||
882 !SectionName.starts_with(".debug_")) {
883 Asm.writeSectionData(W.OS, &Section, Layout);
884 return;
885 }
886
887 SmallVector<char, 128> UncompressedData;
888 raw_svector_ostream VecOS(UncompressedData);
889 Asm.writeSectionData(VecOS, &Section, Layout);
890 ArrayRef<uint8_t> Uncompressed =
891 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
892 UncompressedData.size());
893
894 SmallVector<uint8_t, 128> Compressed;
895 uint32_t ChType;
896 switch (CompressionType) {
897 case DebugCompressionType::None:
898 llvm_unreachable("has been handled");
899 case DebugCompressionType::Zlib:
900 ChType = ELF::ELFCOMPRESS_ZLIB;
901 break;
902 case DebugCompressionType::Zstd:
903 ChType = ELF::ELFCOMPRESS_ZSTD;
904 break;
905 }
906 compression::compress(compression::Params(CompressionType), Uncompressed,
907 Compressed);
908 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
909 Sec.getAlign())) {
910 W.OS << UncompressedData;
911 return;
912 }
913
914 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
915 // Alignment field should reflect the requirements of
916 // the compressed section header.
917 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
918 W.OS << toStringRef(Compressed);
919}
920
921void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
922 uint64_t Address, uint64_t Offset,
923 uint64_t Size, uint32_t Link, uint32_t Info,
924 MaybeAlign Alignment, uint64_t EntrySize) {
925 W.write<uint32_t>(Name); // sh_name: index into string table
926 W.write<uint32_t>(Type); // sh_type
927 WriteWord(Flags); // sh_flags
928 WriteWord(Address); // sh_addr
929 WriteWord(Offset); // sh_offset
930 WriteWord(Size); // sh_size
931 W.write<uint32_t>(Link); // sh_link
932 W.write<uint32_t>(Info); // sh_info
933 WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
934 WriteWord(EntrySize); // sh_entsize
935}
936
937void ELFWriter::writeRelocations(const MCAssembler &Asm,
938 const MCSectionELF &Sec) {
939 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
940 const bool Rela = OWriter.usesRela(Sec);
941
942 // Sort the relocation entries. MIPS needs this.
943 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
944
945 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
946 for (const ELFRelocationEntry &Entry : Relocs) {
947 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
948 if (is64Bit()) {
949 write(Entry.Offset);
950 write(uint32_t(Symidx));
951 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
952 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
953 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
954 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
955 if (Rela)
956 write(Entry.Addend);
957 } else {
958 write(uint32_t(Entry.Offset));
959 ELF::Elf32_Rela ERE32;
960 ERE32.setSymbolAndType(Symidx, Entry.Type);
961 write(ERE32.r_info);
962 if (Rela)
963 write(uint32_t(Entry.Addend));
964 if (uint32_t RType =
965 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
966 write(uint32_t(Entry.Offset));
967 ERE32.setSymbolAndType(0, RType);
968 write(ERE32.r_info);
969 write(uint32_t(0));
970 }
971 if (uint32_t RType =
972 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
973 write(uint32_t(Entry.Offset));
974 ERE32.setSymbolAndType(0, RType);
975 write(ERE32.r_info);
976 write(uint32_t(0));
977 }
978 }
979 }
980 return;
981 }
982 for (const ELFRelocationEntry &Entry : Relocs) {
983 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
984 if (is64Bit()) {
985 write(Entry.Offset);
986 ELF::Elf64_Rela ERE;
987 ERE.setSymbolAndType(Symidx, Entry.Type);
988 write(ERE.r_info);
989 if (Rela)
990 write(Entry.Addend);
991 } else {
992 write(uint32_t(Entry.Offset));
993 ELF::Elf32_Rela ERE;
994 ERE.setSymbolAndType(Symidx, Entry.Type);
995 write(ERE.r_info);
996 if (Rela)
997 write(uint32_t(Entry.Addend));
998 }
999 }
1000}
1001
1002void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
1003 uint32_t GroupSymbolIndex, uint64_t Offset,
1004 uint64_t Size, const MCSectionELF &Section) {
1005 uint64_t sh_link = 0;
1006 uint64_t sh_info = 0;
1007
1008 switch(Section.getType()) {
1009 default:
1010 // Nothing to do.
1011 break;
1012
1013 case ELF::SHT_DYNAMIC:
1014 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1015
1016 case ELF::SHT_REL:
1017 case ELF::SHT_RELA: {
1018 sh_link = SymbolTableIndex;
1019 assert(sh_link && ".symtab not found");
1020 const MCSection *InfoSection = Section.getLinkedToSection();
1021 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
1022 break;
1023 }
1024
1025 case ELF::SHT_SYMTAB:
1026 sh_link = StringTableIndex;
1027 sh_info = LastLocalSymbolIndex;
1028 break;
1029
1033 sh_link = SymbolTableIndex;
1034 break;
1035
1036 case ELF::SHT_GROUP:
1037 sh_link = SymbolTableIndex;
1038 sh_info = GroupSymbolIndex;
1039 break;
1040 }
1041
1042 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
1043 // If the value in the associated metadata is not a definition, Sym will be
1044 // undefined. Represent this with sh_link=0.
1045 const MCSymbol *Sym = Section.getLinkedToSymbol();
1046 if (Sym && Sym->isInSection()) {
1047 const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
1048 sh_link = SectionIndexMap.lookup(Sec);
1049 }
1050 }
1051
1052 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
1053 Section.getType(), Section.getFlags(), 0, Offset, Size,
1054 sh_link, sh_info, Section.getAlign(),
1055 Section.getEntrySize());
1056}
1057
1058void ELFWriter::writeSectionHeader(
1059 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1060 const SectionOffsetsTy &SectionOffsets) {
1061 const unsigned NumSections = SectionTable.size();
1062
1063 // Null section first.
1064 uint64_t FirstSectionSize =
1065 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
1066 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
1067
1068 for (const MCSectionELF *Section : SectionTable) {
1069 uint32_t GroupSymbolIndex;
1070 unsigned Type = Section->getType();
1071 if (Type != ELF::SHT_GROUP)
1072 GroupSymbolIndex = 0;
1073 else
1074 GroupSymbolIndex = Section->getGroup()->getIndex();
1075
1076 const std::pair<uint64_t, uint64_t> &Offsets =
1077 SectionOffsets.find(Section)->second;
1078 uint64_t Size;
1079 if (Type == ELF::SHT_NOBITS)
1080 Size = Layout.getSectionAddressSize(Section);
1081 else
1082 Size = Offsets.second - Offsets.first;
1083
1084 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1085 *Section);
1086 }
1087}
1088
1089uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
1090 uint64_t StartOffset = W.OS.tell();
1091
1092 MCContext &Ctx = Asm.getContext();
1093 MCSectionELF *StrtabSection =
1094 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1095 StringTableIndex = addToSectionTable(StrtabSection);
1096
1097 createMemtagRelocs(Asm);
1098
1099 RevGroupMapTy RevGroupMap;
1100 SectionIndexMapTy SectionIndexMap;
1101
1102 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1103
1104 // Write out the ELF header ...
1105 writeHeader(Asm);
1106
1107 // ... then the sections ...
1108 SectionOffsetsTy SectionOffsets;
1109 std::vector<MCSectionELF *> Groups;
1110 std::vector<MCSectionELF *> Relocations;
1111 for (MCSection &Sec : Asm) {
1112 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1113 if (Mode == NonDwoOnly && isDwoSection(Section))
1114 continue;
1115 if (Mode == DwoOnly && !isDwoSection(Section))
1116 continue;
1117
1118 // Remember the offset into the file for this section.
1119 const uint64_t SecStart = align(Section.getAlign());
1120
1121 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1122 writeSectionData(Asm, Section, Layout);
1123
1124 uint64_t SecEnd = W.OS.tell();
1125 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1126
1127 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1128
1129 if (SignatureSymbol) {
1130 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1131 if (!GroupIdx) {
1132 MCSectionELF *Group =
1133 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1134 GroupIdx = addToSectionTable(Group);
1135 Group->setAlignment(Align(4));
1136 Groups.push_back(Group);
1137 }
1138 std::vector<const MCSectionELF *> &Members =
1139 GroupMembers[SignatureSymbol];
1140 Members.push_back(&Section);
1141 if (RelSection)
1142 Members.push_back(RelSection);
1143 }
1144
1145 SectionIndexMap[&Section] = addToSectionTable(&Section);
1146 if (RelSection) {
1147 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1148 Relocations.push_back(RelSection);
1149 }
1150
1151 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
1152 }
1153
1154 for (MCSectionELF *Group : Groups) {
1155 // Remember the offset into the file for this section.
1156 const uint64_t SecStart = align(Group->getAlign());
1157
1158 const MCSymbol *SignatureSymbol = Group->getGroup();
1159 assert(SignatureSymbol);
1160 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1161 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1162 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1163 write(SecIndex);
1164 }
1165
1166 uint64_t SecEnd = W.OS.tell();
1167 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1168 }
1169
1170 if (Mode == DwoOnly) {
1171 // dwo files don't have symbol tables or relocations, but they do have
1172 // string tables.
1173 StrTabBuilder.finalize();
1174 } else {
1175 MCSectionELF *AddrsigSection;
1176 if (OWriter.EmitAddrsigSection) {
1177 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1179 addToSectionTable(AddrsigSection);
1180 }
1181
1182 // Compute symbol table information.
1183 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1184 SectionOffsets);
1185
1186 for (MCSectionELF *RelSection : Relocations) {
1187 // Remember the offset into the file for this section.
1188 const uint64_t SecStart = align(RelSection->getAlign());
1189
1190 writeRelocations(Asm,
1191 cast<MCSectionELF>(*RelSection->getLinkedToSection()));
1192
1193 uint64_t SecEnd = W.OS.tell();
1194 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1195 }
1196
1197 if (OWriter.EmitAddrsigSection) {
1198 uint64_t SecStart = W.OS.tell();
1199 writeAddrsigSection();
1200 uint64_t SecEnd = W.OS.tell();
1201 SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1202 }
1203 }
1204
1205 {
1206 uint64_t SecStart = W.OS.tell();
1207 StrTabBuilder.write(W.OS);
1208 SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
1209 }
1210
1211 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1212
1213 // ... then the section header table ...
1214 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1215
1216 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1217 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1218 : SectionTable.size() + 1,
1219 W.Endian);
1220 unsigned NumSectionsOffset;
1221
1222 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1223 if (is64Bit()) {
1224 uint64_t Val =
1225 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1226 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1227 offsetof(ELF::Elf64_Ehdr, e_shoff));
1228 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1229 } else {
1230 uint32_t Val =
1231 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1232 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1233 offsetof(ELF::Elf32_Ehdr, e_shoff));
1234 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1235 }
1236 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1237 NumSectionsOffset);
1238
1239 return W.OS.tell() - StartOffset;
1240}
1241
1242bool ELFObjectWriter::hasRelocationAddend() const {
1243 return TargetObjectWriter->hasRelocationAddend();
1244}
1245
1246void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1247 const MCAsmLayout &Layout) {
1248 // The presence of symbol versions causes undefined symbols and
1249 // versions declared with @@@ to be renamed.
1250 for (const MCAssembler::Symver &S : Asm.Symvers) {
1251 StringRef AliasName = S.Name;
1252 const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
1253 size_t Pos = AliasName.find('@');
1254 assert(Pos != StringRef::npos);
1255
1256 StringRef Prefix = AliasName.substr(0, Pos);
1257 StringRef Rest = AliasName.substr(Pos);
1258 StringRef Tail = Rest;
1259 if (Rest.starts_with("@@@"))
1260 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1261
1262 auto *Alias =
1263 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1264 Asm.registerSymbol(*Alias);
1265 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1266 Alias->setVariableValue(Value);
1267
1268 // Aliases defined with .symvar copy the binding from the symbol they alias.
1269 // This is the first place we are able to copy this information.
1270 Alias->setBinding(Symbol.getBinding());
1271 Alias->setVisibility(Symbol.getVisibility());
1272 Alias->setOther(Symbol.getOther());
1273
1274 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1275 continue;
1276
1277 if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1278 !Rest.starts_with("@@@")) {
1279 Asm.getContext().reportError(S.Loc, "default version symbol " +
1280 AliasName + " must be defined");
1281 continue;
1282 }
1283
1284 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1285 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1286 Symbol.getName());
1287 continue;
1288 }
1289
1290 Renames.insert(std::make_pair(&Symbol, Alias));
1291 }
1292
1293 for (const MCSymbol *&Sym : AddrsigSyms) {
1294 if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1295 Sym = R;
1296 if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1297 Sym = Sym->getSection().getBeginSymbol();
1298 Sym->setUsedInReloc();
1299 }
1300}
1301
1302// It is always valid to create a relocation with a symbol. It is preferable
1303// to use a relocation with a section if that is possible. Using the section
1304// allows us to omit some local symbols from the symbol table.
1305bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1306 const MCValue &Val,
1307 const MCSymbolELF *Sym,
1308 uint64_t C,
1309 unsigned Type) const {
1310 const MCSymbolRefExpr *RefA = Val.getSymA();
1311 // A PCRel relocation to an absolute value has no symbol (or section). We
1312 // represent that with a relocation to a null section.
1313 if (!RefA)
1314 return false;
1315
1317 switch (Kind) {
1318 default:
1319 break;
1320 // The .odp creation emits a relocation against the symbol ".TOC." which
1321 // create a R_PPC64_TOC relocation. However the relocation symbol name
1322 // in final object creation should be NULL, since the symbol does not
1323 // really exist, it is just the reference to TOC base for the current
1324 // object file. Since the symbol is undefined, returning false results
1325 // in a relocation with a null section which is the desired result.
1327 return false;
1328
1329 // These VariantKind cause the relocation to refer to something other than
1330 // the symbol itself, like a linker generated table. Since the address of
1331 // symbol is not relevant, we cannot replace the symbol with the
1332 // section and patch the difference in the addend.
1340 return true;
1341 }
1342
1343 // An undefined symbol is not in any section, so the relocation has to point
1344 // to the symbol itself.
1345 assert(Sym && "Expected a symbol");
1346 if (Sym->isUndefined())
1347 return true;
1348
1349 // For memory-tagged symbols, ensure that the relocation uses the symbol. For
1350 // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
1351 // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
1352 // this global needs to be tagged. In addition, the linker needs to know
1353 // whether to emit a special addend when relocating `end` symbols, and this
1354 // can only be determined by the attributes of the symbol itself.
1355 if (Sym->isMemtag())
1356 return true;
1357
1358 unsigned Binding = Sym->getBinding();
1359 switch(Binding) {
1360 default:
1361 llvm_unreachable("Invalid Binding");
1362 case ELF::STB_LOCAL:
1363 break;
1364 case ELF::STB_WEAK:
1365 // If the symbol is weak, it might be overridden by a symbol in another
1366 // file. The relocation has to point to the symbol so that the linker
1367 // can update it.
1368 return true;
1369 case ELF::STB_GLOBAL:
1371 // Global ELF symbols can be preempted by the dynamic linker. The relocation
1372 // has to point to the symbol for a reason analogous to the STB_WEAK case.
1373 return true;
1374 }
1375
1376 // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1377 // reloc that the dynamic loader will use to resolve the address at startup
1378 // time.
1379 if (Sym->getType() == ELF::STT_GNU_IFUNC)
1380 return true;
1381
1382 // If a relocation points to a mergeable section, we have to be careful.
1383 // If the offset is zero, a relocation with the section will encode the
1384 // same information. With a non-zero offset, the situation is different.
1385 // For example, a relocation can point 42 bytes past the end of a string.
1386 // If we change such a relocation to use the section, the linker would think
1387 // that it pointed to another string and subtracting 42 at runtime will
1388 // produce the wrong value.
1389 if (Sym->isInSection()) {
1390 auto &Sec = cast<MCSectionELF>(Sym->getSection());
1391 unsigned Flags = Sec.getFlags();
1392 if (Flags & ELF::SHF_MERGE) {
1393 if (C != 0)
1394 return true;
1395
1396 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1397 // (http://sourceware.org/PR16794).
1398 if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1399 Type == ELF::R_386_GOTOFF)
1400 return true;
1401
1402 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1403 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1404 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1405 // range of a MergeInputSection. We could introduce a new RelExpr member
1406 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1407 // but the complexity is unnecessary given that GNU as keeps the original
1408 // symbol for this case as well.
1409 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1410 !hasRelocationAddend())
1411 return true;
1412 }
1413
1414 // Most TLS relocations use a got, so they need the symbol. Even those that
1415 // are just an offset (@tpoff), require a symbol in gold versions before
1416 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1417 // http://sourceware.org/PR16773.
1418 if (Flags & ELF::SHF_TLS)
1419 return true;
1420 }
1421
1422 // If the symbol is a thumb function the final relocation must set the lowest
1423 // bit. With a symbol that is done by just having the symbol have that bit
1424 // set, so we would lose the bit if we relocated with the section.
1425 // FIXME: We could use the section but add the bit to the relocation value.
1426 if (Asm.isThumbFunc(Sym))
1427 return true;
1428
1429 if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type))
1430 return true;
1431 return false;
1432}
1433
1434void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1435 const MCAsmLayout &Layout,
1436 const MCFragment *Fragment,
1437 const MCFixup &Fixup, MCValue Target,
1438 uint64_t &FixedValue) {
1439 MCAsmBackend &Backend = Asm.getBackend();
1440 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1442 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1443 uint64_t C = Target.getConstant();
1444 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1445 MCContext &Ctx = Asm.getContext();
1446
1447 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1448 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1449 if (SymB.isUndefined()) {
1450 Ctx.reportError(Fixup.getLoc(),
1451 Twine("symbol '") + SymB.getName() +
1452 "' can not be undefined in a subtraction expression");
1453 return;
1454 }
1455
1456 assert(!SymB.isAbsolute() && "Should have been folded");
1457 const MCSection &SecB = SymB.getSection();
1458 if (&SecB != &FixupSection) {
1459 Ctx.reportError(Fixup.getLoc(),
1460 "Cannot represent a difference across sections");
1461 return;
1462 }
1463
1464 assert(!IsPCRel && "should have been folded");
1465 IsPCRel = true;
1466 C += FixupOffset - Layout.getSymbolOffset(SymB);
1467 }
1468
1469 // We either rejected the fixup or folded B into C at this point.
1470 const MCSymbolRefExpr *RefA = Target.getSymA();
1471 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1472
1473 bool ViaWeakRef = false;
1474 if (SymA && SymA->isVariable()) {
1475 const MCExpr *Expr = SymA->getVariableValue();
1476 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1477 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1478 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1479 ViaWeakRef = true;
1480 }
1481 }
1482 }
1483
1484 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1485 ? cast<MCSectionELF>(&SymA->getSection())
1486 : nullptr;
1487 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1488 return;
1489
1490 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1491 const auto *Parent = cast<MCSectionELF>(Fragment->getParent());
1492 // Emiting relocation with sybmol for CG Profile to help with --cg-profile.
1493 bool RelocateWithSymbol =
1494 shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||
1495 (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
1496 uint64_t Addend = 0;
1497
1498 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1499 ? C + Layout.getSymbolOffset(*SymA)
1500 : C;
1501 if (usesRela(FixupSection)) {
1502 Addend = FixedValue;
1503 FixedValue = 0;
1504 }
1505
1506 if (!RelocateWithSymbol) {
1507 const auto *SectionSymbol =
1508 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1509 if (SectionSymbol)
1510 SectionSymbol->setUsedInReloc();
1511 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
1512 Relocations[&FixupSection].push_back(Rec);
1513 return;
1514 }
1515
1516 const MCSymbolELF *RenamedSymA = SymA;
1517 if (SymA) {
1518 if (const MCSymbolELF *R = Renames.lookup(SymA))
1519 RenamedSymA = R;
1520
1521 if (ViaWeakRef)
1522 RenamedSymA->setIsWeakrefUsedInReloc();
1523 else
1524 RenamedSymA->setUsedInReloc();
1525 }
1526 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1527 Relocations[&FixupSection].push_back(Rec);
1528}
1529
1530bool ELFObjectWriter::usesRela(const MCSectionELF &Sec) const {
1531 return hasRelocationAddend() &&
1533}
1534
1535bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1536 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1537 bool InSet, bool IsPCRel) const {
1538 const auto &SymA = cast<MCSymbolELF>(SA);
1539 if (IsPCRel) {
1540 assert(!InSet);
1541 if (SymA.getBinding() != ELF::STB_LOCAL ||
1542 SymA.getType() == ELF::STT_GNU_IFUNC)
1543 return false;
1544 }
1546 InSet, IsPCRel);
1547}
1548
1549std::unique_ptr<MCObjectWriter>
1550llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1551 raw_pwrite_stream &OS, bool IsLittleEndian) {
1552 return std::make_unique<ELFSingleObjectWriter>(std::move(MOTW), OS,
1553 IsLittleEndian);
1554}
1555
1556std::unique_ptr<MCObjectWriter>
1557llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1559 bool IsLittleEndian) {
1560 return std::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1561 IsLittleEndian);
1562}
#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:81
MCSectionELF * createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, const MCSectionELF *RelInfoSection)
Definition: MCContext.cpp:509
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:562
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1073
const MCTargetOptions * getTargetOptions() const
Definition: MCContext.h:445
MCSectionELF * createELFGroupSection(const MCSymbolELF *Group, bool IsComdat)
Definition: MCContext.cpp:612
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:564
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:258
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:290
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:270
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
@ 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
@ ELFCOMPRESS_ZSTD
Definition: ELF.h:1929
@ ELFCOMPRESS_ZLIB
Definition: ELF.h:1928
@ 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:1542
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:1680
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:2406
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