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 StringRef Name = Symbol.getName();
729
730 // Sections have their own string table
731 if (Symbol.getType() != ELF::STT_SECTION) {
732 MSD.Name = Name;
733 StrTabBuilder.add(Name);
734 }
735
736 if (Local)
737 LocalSymbolData.push_back(MSD);
738 else
739 ExternalSymbolData.push_back(MSD);
740 }
741
742 // This holds the .symtab_shndx section index.
743 unsigned SymtabShndxSectionIndex = 0;
744
745 if (HasLargeSectionIndex) {
746 MCSectionELF *SymtabShndxSection =
747 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
748 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
749 SymtabShndxSection->setAlignment(Align(4));
750 }
751
752 StrTabBuilder.finalize();
753
754 // Make the first STT_FILE precede previous local symbols.
755 unsigned Index = 1;
756 auto FileNameIt = FileNames.begin();
757 if (!FileNames.empty())
758 FileNames[0].second = 0;
759
760 for (ELFSymbolData &MSD : LocalSymbolData) {
761 // Emit STT_FILE symbols before their associated local symbols.
762 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
763 ++FileNameIt) {
764 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
766 ELF::SHN_ABS, true);
767 ++Index;
768 }
769
770 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
771 ? 0
772 : StrTabBuilder.getOffset(MSD.Name);
773 MSD.Symbol->setIndex(Index++);
774 writeSymbol(Writer, StringIndex, MSD, Layout);
775 }
776 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
777 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
779 ELF::SHN_ABS, true);
780 ++Index;
781 }
782
783 // Write the symbol table entries.
784 LastLocalSymbolIndex = Index;
785
786 for (ELFSymbolData &MSD : ExternalSymbolData) {
787 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
788 MSD.Symbol->setIndex(Index++);
789 writeSymbol(Writer, StringIndex, MSD, Layout);
790 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
791 }
792
793 uint64_t SecEnd = W.OS.tell();
794 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
795
796 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
797 if (ShndxIndexes.empty()) {
798 assert(SymtabShndxSectionIndex == 0);
799 return;
800 }
801 assert(SymtabShndxSectionIndex != 0);
802
803 SecStart = W.OS.tell();
804 const MCSectionELF *SymtabShndxSection =
805 SectionTable[SymtabShndxSectionIndex - 1];
806 for (uint32_t Index : ShndxIndexes)
807 write(Index);
808 SecEnd = W.OS.tell();
809 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
810}
811
812void ELFWriter::writeAddrsigSection() {
813 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
814 if (Sym->getIndex() != 0)
815 encodeULEB128(Sym->getIndex(), W.OS);
816}
817
818MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
819 const MCSectionELF &Sec) {
820 if (OWriter.Relocations[&Sec].empty())
821 return nullptr;
822
823 unsigned Flags = ELF::SHF_INFO_LINK;
824 if (Sec.getFlags() & ELF::SHF_GROUP)
826
827 const StringRef SectionName = Sec.getName();
828 const bool Rela = OWriter.usesRela(Sec);
829 unsigned EntrySize;
830 if (Rela)
831 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
832 else
833 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
834
835 MCSectionELF *RelaSection =
836 Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName),
838 EntrySize, Sec.getGroup(), &Sec);
839 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
840 return RelaSection;
841}
842
843// Include the debug info compression header.
844bool ELFWriter::maybeWriteCompression(
845 uint32_t ChType, uint64_t Size,
846 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
847 uint64_t HdrSize =
848 is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
849 if (Size <= HdrSize + CompressedContents.size())
850 return false;
851 // Platform specific header is followed by compressed data.
852 if (is64Bit()) {
853 // Write Elf64_Chdr header.
854 write(static_cast<ELF::Elf64_Word>(ChType));
855 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
856 write(static_cast<ELF::Elf64_Xword>(Size));
857 write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
858 } else {
859 // Write Elf32_Chdr header otherwise.
860 write(static_cast<ELF::Elf32_Word>(ChType));
861 write(static_cast<ELF::Elf32_Word>(Size));
862 write(static_cast<ELF::Elf32_Word>(Alignment.value()));
863 }
864 return true;
865}
866
867void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
868 const MCAsmLayout &Layout) {
869 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
870 StringRef SectionName = Section.getName();
871 auto &Ctx = Asm.getContext();
872 const DebugCompressionType CompressionType =
874 : DebugCompressionType::None;
875 if (CompressionType == DebugCompressionType::None ||
876 !SectionName.starts_with(".debug_")) {
877 Asm.writeSectionData(W.OS, &Section, Layout);
878 return;
879 }
880
881 SmallVector<char, 128> UncompressedData;
882 raw_svector_ostream VecOS(UncompressedData);
883 Asm.writeSectionData(VecOS, &Section, Layout);
884 ArrayRef<uint8_t> Uncompressed =
885 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
886 UncompressedData.size());
887
888 SmallVector<uint8_t, 128> Compressed;
889 uint32_t ChType;
890 switch (CompressionType) {
891 case DebugCompressionType::None:
892 llvm_unreachable("has been handled");
893 case DebugCompressionType::Zlib:
894 ChType = ELF::ELFCOMPRESS_ZLIB;
895 break;
896 case DebugCompressionType::Zstd:
897 ChType = ELF::ELFCOMPRESS_ZSTD;
898 break;
899 }
900 compression::compress(compression::Params(CompressionType), Uncompressed,
901 Compressed);
902 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
903 Sec.getAlign())) {
904 W.OS << UncompressedData;
905 return;
906 }
907
908 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
909 // Alignment field should reflect the requirements of
910 // the compressed section header.
911 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
912 W.OS << toStringRef(Compressed);
913}
914
915void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
916 uint64_t Address, uint64_t Offset,
917 uint64_t Size, uint32_t Link, uint32_t Info,
918 MaybeAlign Alignment, uint64_t EntrySize) {
919 W.write<uint32_t>(Name); // sh_name: index into string table
920 W.write<uint32_t>(Type); // sh_type
921 WriteWord(Flags); // sh_flags
922 WriteWord(Address); // sh_addr
923 WriteWord(Offset); // sh_offset
924 WriteWord(Size); // sh_size
925 W.write<uint32_t>(Link); // sh_link
926 W.write<uint32_t>(Info); // sh_info
927 WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
928 WriteWord(EntrySize); // sh_entsize
929}
930
931void ELFWriter::writeRelocations(const MCAssembler &Asm,
932 const MCSectionELF &Sec) {
933 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
934 const bool Rela = OWriter.usesRela(Sec);
935
936 // Sort the relocation entries. MIPS needs this.
937 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
938
939 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
940 for (const ELFRelocationEntry &Entry : Relocs) {
941 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
942 if (is64Bit()) {
943 write(Entry.Offset);
944 write(uint32_t(Symidx));
945 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
946 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
947 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
948 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
949 if (Rela)
950 write(Entry.Addend);
951 } else {
952 write(uint32_t(Entry.Offset));
953 ELF::Elf32_Rela ERE32;
954 ERE32.setSymbolAndType(Symidx, Entry.Type);
955 write(ERE32.r_info);
956 if (Rela)
957 write(uint32_t(Entry.Addend));
958 if (uint32_t RType =
959 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
960 write(uint32_t(Entry.Offset));
961 ERE32.setSymbolAndType(0, RType);
962 write(ERE32.r_info);
963 write(uint32_t(0));
964 }
965 if (uint32_t RType =
966 OWriter.TargetObjectWriter->getRType3(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 }
973 }
974 return;
975 }
976 for (const ELFRelocationEntry &Entry : Relocs) {
977 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
978 if (is64Bit()) {
979 write(Entry.Offset);
980 ELF::Elf64_Rela ERE;
981 ERE.setSymbolAndType(Symidx, Entry.Type);
982 write(ERE.r_info);
983 if (Rela)
984 write(Entry.Addend);
985 } else {
986 write(uint32_t(Entry.Offset));
987 ELF::Elf32_Rela ERE;
988 ERE.setSymbolAndType(Symidx, Entry.Type);
989 write(ERE.r_info);
990 if (Rela)
991 write(uint32_t(Entry.Addend));
992 }
993 }
994}
995
996void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
997 uint32_t GroupSymbolIndex, uint64_t Offset,
998 uint64_t Size, const MCSectionELF &Section) {
999 uint64_t sh_link = 0;
1000 uint64_t sh_info = 0;
1001
1002 switch(Section.getType()) {
1003 default:
1004 // Nothing to do.
1005 break;
1006
1007 case ELF::SHT_DYNAMIC:
1008 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1009
1010 case ELF::SHT_REL:
1011 case ELF::SHT_RELA: {
1012 sh_link = SymbolTableIndex;
1013 assert(sh_link && ".symtab not found");
1014 const MCSection *InfoSection = Section.getLinkedToSection();
1015 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
1016 break;
1017 }
1018
1019 case ELF::SHT_SYMTAB:
1020 sh_link = StringTableIndex;
1021 sh_info = LastLocalSymbolIndex;
1022 break;
1023
1027 sh_link = SymbolTableIndex;
1028 break;
1029
1030 case ELF::SHT_GROUP:
1031 sh_link = SymbolTableIndex;
1032 sh_info = GroupSymbolIndex;
1033 break;
1034 }
1035
1036 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
1037 // If the value in the associated metadata is not a definition, Sym will be
1038 // undefined. Represent this with sh_link=0.
1039 const MCSymbol *Sym = Section.getLinkedToSymbol();
1040 if (Sym && Sym->isInSection()) {
1041 const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
1042 sh_link = SectionIndexMap.lookup(Sec);
1043 }
1044 }
1045
1046 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
1047 Section.getType(), Section.getFlags(), 0, Offset, Size,
1048 sh_link, sh_info, Section.getAlign(),
1049 Section.getEntrySize());
1050}
1051
1052void ELFWriter::writeSectionHeader(
1053 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1054 const SectionOffsetsTy &SectionOffsets) {
1055 const unsigned NumSections = SectionTable.size();
1056
1057 // Null section first.
1058 uint64_t FirstSectionSize =
1059 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
1060 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
1061
1062 for (const MCSectionELF *Section : SectionTable) {
1063 uint32_t GroupSymbolIndex;
1064 unsigned Type = Section->getType();
1065 if (Type != ELF::SHT_GROUP)
1066 GroupSymbolIndex = 0;
1067 else
1068 GroupSymbolIndex = Section->getGroup()->getIndex();
1069
1070 const std::pair<uint64_t, uint64_t> &Offsets =
1071 SectionOffsets.find(Section)->second;
1072 uint64_t Size;
1073 if (Type == ELF::SHT_NOBITS)
1074 Size = Layout.getSectionAddressSize(Section);
1075 else
1076 Size = Offsets.second - Offsets.first;
1077
1078 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1079 *Section);
1080 }
1081}
1082
1083uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
1084 uint64_t StartOffset = W.OS.tell();
1085
1086 MCContext &Ctx = Asm.getContext();
1087 MCSectionELF *StrtabSection =
1088 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1089 StringTableIndex = addToSectionTable(StrtabSection);
1090
1091 createMemtagRelocs(Asm);
1092
1093 RevGroupMapTy RevGroupMap;
1094 SectionIndexMapTy SectionIndexMap;
1095
1096 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1097
1098 // Write out the ELF header ...
1099 writeHeader(Asm);
1100
1101 // ... then the sections ...
1102 SectionOffsetsTy SectionOffsets;
1103 std::vector<MCSectionELF *> Groups;
1104 std::vector<MCSectionELF *> Relocations;
1105 for (MCSection &Sec : Asm) {
1106 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1107 if (Mode == NonDwoOnly && isDwoSection(Section))
1108 continue;
1109 if (Mode == DwoOnly && !isDwoSection(Section))
1110 continue;
1111
1112 // Remember the offset into the file for this section.
1113 const uint64_t SecStart = align(Section.getAlign());
1114
1115 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1116 writeSectionData(Asm, Section, Layout);
1117
1118 uint64_t SecEnd = W.OS.tell();
1119 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1120
1121 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1122
1123 if (SignatureSymbol) {
1124 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1125 if (!GroupIdx) {
1126 MCSectionELF *Group =
1127 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1128 GroupIdx = addToSectionTable(Group);
1129 Group->setAlignment(Align(4));
1130 Groups.push_back(Group);
1131 }
1132 std::vector<const MCSectionELF *> &Members =
1133 GroupMembers[SignatureSymbol];
1134 Members.push_back(&Section);
1135 if (RelSection)
1136 Members.push_back(RelSection);
1137 }
1138
1139 SectionIndexMap[&Section] = addToSectionTable(&Section);
1140 if (RelSection) {
1141 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1142 Relocations.push_back(RelSection);
1143 }
1144
1145 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
1146 }
1147
1148 for (MCSectionELF *Group : Groups) {
1149 // Remember the offset into the file for this section.
1150 const uint64_t SecStart = align(Group->getAlign());
1151
1152 const MCSymbol *SignatureSymbol = Group->getGroup();
1153 assert(SignatureSymbol);
1154 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1155 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1156 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1157 write(SecIndex);
1158 }
1159
1160 uint64_t SecEnd = W.OS.tell();
1161 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1162 }
1163
1164 if (Mode == DwoOnly) {
1165 // dwo files don't have symbol tables or relocations, but they do have
1166 // string tables.
1167 StrTabBuilder.finalize();
1168 } else {
1169 MCSectionELF *AddrsigSection;
1170 if (OWriter.EmitAddrsigSection) {
1171 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1173 addToSectionTable(AddrsigSection);
1174 }
1175
1176 // Compute symbol table information.
1177 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1178 SectionOffsets);
1179
1180 for (MCSectionELF *RelSection : Relocations) {
1181 // Remember the offset into the file for this section.
1182 const uint64_t SecStart = align(RelSection->getAlign());
1183
1184 writeRelocations(Asm,
1185 cast<MCSectionELF>(*RelSection->getLinkedToSection()));
1186
1187 uint64_t SecEnd = W.OS.tell();
1188 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1189 }
1190
1191 if (OWriter.EmitAddrsigSection) {
1192 uint64_t SecStart = W.OS.tell();
1193 writeAddrsigSection();
1194 uint64_t SecEnd = W.OS.tell();
1195 SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1196 }
1197 }
1198
1199 {
1200 uint64_t SecStart = W.OS.tell();
1201 StrTabBuilder.write(W.OS);
1202 SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
1203 }
1204
1205 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1206
1207 // ... then the section header table ...
1208 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1209
1210 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1211 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1212 : SectionTable.size() + 1,
1213 W.Endian);
1214 unsigned NumSectionsOffset;
1215
1216 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1217 if (is64Bit()) {
1218 uint64_t Val =
1219 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1220 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1221 offsetof(ELF::Elf64_Ehdr, e_shoff));
1222 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1223 } else {
1224 uint32_t Val =
1225 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1226 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1227 offsetof(ELF::Elf32_Ehdr, e_shoff));
1228 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1229 }
1230 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1231 NumSectionsOffset);
1232
1233 return W.OS.tell() - StartOffset;
1234}
1235
1236bool ELFObjectWriter::hasRelocationAddend() const {
1237 return TargetObjectWriter->hasRelocationAddend();
1238}
1239
1240void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1241 const MCAsmLayout &Layout) {
1242 // The presence of symbol versions causes undefined symbols and
1243 // versions declared with @@@ to be renamed.
1244 for (const MCAssembler::Symver &S : Asm.Symvers) {
1245 StringRef AliasName = S.Name;
1246 const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
1247 size_t Pos = AliasName.find('@');
1248 assert(Pos != StringRef::npos);
1249
1250 StringRef Prefix = AliasName.substr(0, Pos);
1251 StringRef Rest = AliasName.substr(Pos);
1252 StringRef Tail = Rest;
1253 if (Rest.starts_with("@@@"))
1254 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1255
1256 auto *Alias =
1257 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1258 Asm.registerSymbol(*Alias);
1259 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1260 Alias->setVariableValue(Value);
1261
1262 // Aliases defined with .symvar copy the binding from the symbol they alias.
1263 // This is the first place we are able to copy this information.
1264 Alias->setBinding(Symbol.getBinding());
1265 Alias->setVisibility(Symbol.getVisibility());
1266 Alias->setOther(Symbol.getOther());
1267
1268 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1269 continue;
1270
1271 if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1272 !Rest.starts_with("@@@")) {
1273 Asm.getContext().reportError(S.Loc, "default version symbol " +
1274 AliasName + " must be defined");
1275 continue;
1276 }
1277
1278 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1279 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1280 Symbol.getName());
1281 continue;
1282 }
1283
1284 Renames.insert(std::make_pair(&Symbol, Alias));
1285 }
1286
1287 for (const MCSymbol *&Sym : AddrsigSyms) {
1288 if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1289 Sym = R;
1290 if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1291 Sym = Sym->getSection().getBeginSymbol();
1292 Sym->setUsedInReloc();
1293 }
1294}
1295
1296// It is always valid to create a relocation with a symbol. It is preferable
1297// to use a relocation with a section if that is possible. Using the section
1298// allows us to omit some local symbols from the symbol table.
1299bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1300 const MCValue &Val,
1301 const MCSymbolELF *Sym,
1302 uint64_t C,
1303 unsigned Type) const {
1304 const MCSymbolRefExpr *RefA = Val.getSymA();
1305 // A PCRel relocation to an absolute value has no symbol (or section). We
1306 // represent that with a relocation to a null section.
1307 if (!RefA)
1308 return false;
1309
1311 switch (Kind) {
1312 default:
1313 break;
1314 // The .odp creation emits a relocation against the symbol ".TOC." which
1315 // create a R_PPC64_TOC relocation. However the relocation symbol name
1316 // in final object creation should be NULL, since the symbol does not
1317 // really exist, it is just the reference to TOC base for the current
1318 // object file. Since the symbol is undefined, returning false results
1319 // in a relocation with a null section which is the desired result.
1321 return false;
1322
1323 // These VariantKind cause the relocation to refer to something other than
1324 // the symbol itself, like a linker generated table. Since the address of
1325 // symbol is not relevant, we cannot replace the symbol with the
1326 // section and patch the difference in the addend.
1334 return true;
1335 }
1336
1337 // An undefined symbol is not in any section, so the relocation has to point
1338 // to the symbol itself.
1339 assert(Sym && "Expected a symbol");
1340 if (Sym->isUndefined())
1341 return true;
1342
1343 // For memory-tagged symbols, ensure that the relocation uses the symbol. For
1344 // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
1345 // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
1346 // this global needs to be tagged. In addition, the linker needs to know
1347 // whether to emit a special addend when relocating `end` symbols, and this
1348 // can only be determined by the attributes of the symbol itself.
1349 if (Sym->isMemtag())
1350 return true;
1351
1352 unsigned Binding = Sym->getBinding();
1353 switch(Binding) {
1354 default:
1355 llvm_unreachable("Invalid Binding");
1356 case ELF::STB_LOCAL:
1357 break;
1358 case ELF::STB_WEAK:
1359 // If the symbol is weak, it might be overridden by a symbol in another
1360 // file. The relocation has to point to the symbol so that the linker
1361 // can update it.
1362 return true;
1363 case ELF::STB_GLOBAL:
1365 // Global ELF symbols can be preempted by the dynamic linker. The relocation
1366 // has to point to the symbol for a reason analogous to the STB_WEAK case.
1367 return true;
1368 }
1369
1370 // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1371 // reloc that the dynamic loader will use to resolve the address at startup
1372 // time.
1373 if (Sym->getType() == ELF::STT_GNU_IFUNC)
1374 return true;
1375
1376 // If a relocation points to a mergeable section, we have to be careful.
1377 // If the offset is zero, a relocation with the section will encode the
1378 // same information. With a non-zero offset, the situation is different.
1379 // For example, a relocation can point 42 bytes past the end of a string.
1380 // If we change such a relocation to use the section, the linker would think
1381 // that it pointed to another string and subtracting 42 at runtime will
1382 // produce the wrong value.
1383 if (Sym->isInSection()) {
1384 auto &Sec = cast<MCSectionELF>(Sym->getSection());
1385 unsigned Flags = Sec.getFlags();
1386 if (Flags & ELF::SHF_MERGE) {
1387 if (C != 0)
1388 return true;
1389
1390 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1391 // (http://sourceware.org/PR16794).
1392 if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1393 Type == ELF::R_386_GOTOFF)
1394 return true;
1395
1396 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1397 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1398 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1399 // range of a MergeInputSection. We could introduce a new RelExpr member
1400 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1401 // but the complexity is unnecessary given that GNU as keeps the original
1402 // symbol for this case as well.
1403 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1404 !hasRelocationAddend())
1405 return true;
1406 }
1407
1408 // Most TLS relocations use a got, so they need the symbol. Even those that
1409 // are just an offset (@tpoff), require a symbol in gold versions before
1410 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1411 // http://sourceware.org/PR16773.
1412 if (Flags & ELF::SHF_TLS)
1413 return true;
1414 }
1415
1416 // If the symbol is a thumb function the final relocation must set the lowest
1417 // bit. With a symbol that is done by just having the symbol have that bit
1418 // set, so we would lose the bit if we relocated with the section.
1419 // FIXME: We could use the section but add the bit to the relocation value.
1420 if (Asm.isThumbFunc(Sym))
1421 return true;
1422
1423 if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type))
1424 return true;
1425 return false;
1426}
1427
1428void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1429 const MCAsmLayout &Layout,
1430 const MCFragment *Fragment,
1431 const MCFixup &Fixup, MCValue Target,
1432 uint64_t &FixedValue) {
1433 MCAsmBackend &Backend = Asm.getBackend();
1434 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1436 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1437 uint64_t C = Target.getConstant();
1438 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1439 MCContext &Ctx = Asm.getContext();
1440
1441 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1442 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1443 if (SymB.isUndefined()) {
1444 Ctx.reportError(Fixup.getLoc(),
1445 Twine("symbol '") + SymB.getName() +
1446 "' can not be undefined in a subtraction expression");
1447 return;
1448 }
1449
1450 assert(!SymB.isAbsolute() && "Should have been folded");
1451 const MCSection &SecB = SymB.getSection();
1452 if (&SecB != &FixupSection) {
1453 Ctx.reportError(Fixup.getLoc(),
1454 "Cannot represent a difference across sections");
1455 return;
1456 }
1457
1458 assert(!IsPCRel && "should have been folded");
1459 IsPCRel = true;
1460 C += FixupOffset - Layout.getSymbolOffset(SymB);
1461 }
1462
1463 // We either rejected the fixup or folded B into C at this point.
1464 const MCSymbolRefExpr *RefA = Target.getSymA();
1465 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1466
1467 bool ViaWeakRef = false;
1468 if (SymA && SymA->isVariable()) {
1469 const MCExpr *Expr = SymA->getVariableValue();
1470 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1471 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1472 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1473 ViaWeakRef = true;
1474 }
1475 }
1476 }
1477
1478 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1479 ? cast<MCSectionELF>(&SymA->getSection())
1480 : nullptr;
1481 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1482 return;
1483
1484 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1485 const auto *Parent = cast<MCSectionELF>(Fragment->getParent());
1486 // Emiting relocation with sybmol for CG Profile to help with --cg-profile.
1487 bool RelocateWithSymbol =
1488 shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||
1489 (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
1490 uint64_t Addend = 0;
1491
1492 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1493 ? C + Layout.getSymbolOffset(*SymA)
1494 : C;
1495 if (usesRela(FixupSection)) {
1496 Addend = FixedValue;
1497 FixedValue = 0;
1498 }
1499
1500 if (!RelocateWithSymbol) {
1501 const auto *SectionSymbol =
1502 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1503 if (SectionSymbol)
1504 SectionSymbol->setUsedInReloc();
1505 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
1506 Relocations[&FixupSection].push_back(Rec);
1507 return;
1508 }
1509
1510 const MCSymbolELF *RenamedSymA = SymA;
1511 if (SymA) {
1512 if (const MCSymbolELF *R = Renames.lookup(SymA))
1513 RenamedSymA = R;
1514
1515 if (ViaWeakRef)
1516 RenamedSymA->setIsWeakrefUsedInReloc();
1517 else
1518 RenamedSymA->setUsedInReloc();
1519 }
1520 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1521 Relocations[&FixupSection].push_back(Rec);
1522}
1523
1524bool ELFObjectWriter::usesRela(const MCSectionELF &Sec) const {
1525 return hasRelocationAddend() &&
1527}
1528
1529bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1530 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1531 bool InSet, bool IsPCRel) const {
1532 const auto &SymA = cast<MCSymbolELF>(SA);
1533 if (IsPCRel) {
1534 assert(!InSet);
1535 if (SymA.getBinding() != ELF::STB_LOCAL ||
1536 SymA.getType() == ELF::STT_GNU_IFUNC)
1537 return false;
1538 }
1540 InSet, IsPCRel);
1541}
1542
1543std::unique_ptr<MCObjectWriter>
1544llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1545 raw_pwrite_stream &OS, bool IsLittleEndian) {
1546 return std::make_unique<ELFSingleObjectWriter>(std::move(MOTW), OS,
1547 IsLittleEndian);
1548}
1549
1550std::unique_ptr<MCObjectWriter>
1551llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1553 bool IsLittleEndian) {
1554 return std::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1555 IsLittleEndian);
1556}
#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:578
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1069
const MCTargetOptions * getTargetOptions() const
Definition: MCContext.h:461
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:557
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:283
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:266
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:1531
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