LLVM 18.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().endswith(".dwo");
76}
77
78class SymbolTableWriter {
79 ELFWriter &EWriter;
80 bool Is64Bit;
81
82 // indexes we are going to write to .symtab_shndx.
83 std::vector<uint32_t> ShndxIndexes;
84
85 // The numbel of symbols written so far.
86 unsigned NumWritten;
87
88 void createSymtabShndx();
89
90 template <typename T> void write(T Value);
91
92public:
93 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
94
95 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
96 uint8_t other, uint32_t shndx, bool Reserved);
97
98 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
99};
100
101struct ELFWriter {
102 ELFObjectWriter &OWriter;
104
105 enum DwoMode {
106 AllSections,
107 NonDwoOnly,
108 DwoOnly,
109 } Mode;
110
111 static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
112 static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
113 bool Used, bool Renamed);
114
115 /// Helper struct for containing some precomputed information on symbols.
116 struct ELFSymbolData {
117 const MCSymbolELF *Symbol;
118 StringRef Name;
119 uint32_t SectionIndex;
120 uint32_t Order;
121 };
122
123 /// @}
124 /// @name Symbol Table Data
125 /// @{
126
128
129 /// @}
130
131 // This holds the symbol table index of the last local symbol.
132 unsigned LastLocalSymbolIndex = ~0u;
133 // This holds the .strtab section index.
134 unsigned StringTableIndex = ~0u;
135 // This holds the .symtab section index.
136 unsigned SymbolTableIndex = ~0u;
137
138 // Sections in the order they are to be output in the section table.
139 std::vector<const MCSectionELF *> SectionTable;
140 unsigned addToSectionTable(const MCSectionELF *Sec);
141
142 // TargetObjectWriter wrappers.
143 bool is64Bit() const;
144 bool usesRela(const MCSectionELF &Sec) const;
145
146 uint64_t align(Align Alignment);
147
148 bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
149 SmallVectorImpl<uint8_t> &CompressedContents,
150 Align Alignment);
151
152public:
153 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
154 bool IsLittleEndian, DwoMode Mode)
155 : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little
157 Mode(Mode) {}
158
159 void WriteWord(uint64_t Word) {
160 if (is64Bit())
161 W.write<uint64_t>(Word);
162 else
163 W.write<uint32_t>(Word);
164 }
165
166 template <typename T> void write(T Val) {
167 W.write(Val);
168 }
169
170 void writeHeader(const MCAssembler &Asm);
171
172 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
173 ELFSymbolData &MSD, const MCAsmLayout &Layout);
174
175 // Start and end offset of each section
176 using SectionOffsetsTy =
177 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
178
179 // Map from a signature symbol to the group section index
180 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
181
182 /// Compute the symbol table data
183 ///
184 /// \param Asm - The assembler.
185 /// \param SectionIndexMap - Maps a section to its index.
186 /// \param RevGroupMap - Maps a signature symbol to the group section.
187 void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
188 const SectionIndexMapTy &SectionIndexMap,
189 const RevGroupMapTy &RevGroupMap,
190 SectionOffsetsTy &SectionOffsets);
191
192 void writeAddrsigSection();
193
194 MCSectionELF *createRelocationSection(MCContext &Ctx,
195 const MCSectionELF &Sec);
196
197 void createMemtagRelocs(MCAssembler &Asm);
198
199 void writeSectionHeader(const MCAsmLayout &Layout,
200 const SectionIndexMapTy &SectionIndexMap,
201 const SectionOffsetsTy &SectionOffsets);
202
203 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
204 const MCAsmLayout &Layout);
205
206 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
208 uint32_t Link, uint32_t Info, MaybeAlign Alignment,
209 uint64_t EntrySize);
210
211 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
212
213 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
214 void writeSection(const SectionIndexMapTy &SectionIndexMap,
215 uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
216 const MCSectionELF &Section);
217};
218
219class ELFObjectWriter : public MCObjectWriter {
220 /// The target specific ELF writer instance.
221 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
222
224
226
227 bool SeenGnuAbi = false;
228
229 bool hasRelocationAddend() const;
230
231 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
232 const MCSymbolELF *Sym, uint64_t C,
233 unsigned Type) const;
234
235public:
236 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
237 : TargetObjectWriter(std::move(MOTW)) {}
238
239 void reset() override {
240 SeenGnuAbi = false;
241 Relocations.clear();
242 Renames.clear();
244 }
245
247 const MCSymbol &SymA,
248 const MCFragment &FB, bool InSet,
249 bool IsPCRel) const override;
250
251 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
252 const MCSectionELF *From,
253 const MCSectionELF *To) {
254 return true;
255 }
256
257 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
258 const MCFragment *Fragment, const MCFixup &Fixup,
259 MCValue Target, uint64_t &FixedValue) override;
260
262 const MCAsmLayout &Layout) override;
263
264 void markGnuAbi() override { SeenGnuAbi = true; }
265 bool seenGnuAbi() const { return SeenGnuAbi; }
266
267 friend struct ELFWriter;
268};
269
270class ELFSingleObjectWriter : public ELFObjectWriter {
272 bool IsLittleEndian;
273
274public:
275 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
276 raw_pwrite_stream &OS, bool IsLittleEndian)
277 : ELFObjectWriter(std::move(MOTW)), OS(OS),
278 IsLittleEndian(IsLittleEndian) {}
279
280 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
281 return ELFWriter(*this, OS, IsLittleEndian, ELFWriter::AllSections)
282 .writeObject(Asm, Layout);
283 }
284
285 friend struct ELFWriter;
286};
287
288class ELFDwoObjectWriter : public ELFObjectWriter {
289 raw_pwrite_stream &OS, &DwoOS;
290 bool IsLittleEndian;
291
292public:
293 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
295 bool IsLittleEndian)
296 : ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
297 IsLittleEndian(IsLittleEndian) {}
298
299 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
300 const MCSectionELF *To) override {
301 if (isDwoSection(*From)) {
302 Ctx.reportError(Loc, "A dwo section may not contain relocations");
303 return false;
304 }
305 if (To && isDwoSection(*To)) {
306 Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
307 return false;
308 }
309 return true;
310 }
311
312 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
313 uint64_t Size = ELFWriter(*this, OS, IsLittleEndian, ELFWriter::NonDwoOnly)
314 .writeObject(Asm, Layout);
315 Size += ELFWriter(*this, DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
316 .writeObject(Asm, Layout);
317 return Size;
318 }
319};
320
321} // end anonymous namespace
322
323uint64_t ELFWriter::align(Align Alignment) {
324 uint64_t Offset = W.OS.tell();
325 uint64_t NewOffset = alignTo(Offset, Alignment);
326 W.OS.write_zeros(NewOffset - Offset);
327 return NewOffset;
328}
329
330unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
331 SectionTable.push_back(Sec);
332 StrTabBuilder.add(Sec->getName());
333 return SectionTable.size();
334}
335
336void SymbolTableWriter::createSymtabShndx() {
337 if (!ShndxIndexes.empty())
338 return;
339
340 ShndxIndexes.resize(NumWritten);
341}
342
343template <typename T> void SymbolTableWriter::write(T Value) {
344 EWriter.write(Value);
345}
346
347SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
348 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
349
350void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
351 uint64_t size, uint8_t other,
352 uint32_t shndx, bool Reserved) {
353 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
354
355 if (LargeIndex)
356 createSymtabShndx();
357
358 if (!ShndxIndexes.empty()) {
359 if (LargeIndex)
360 ShndxIndexes.push_back(shndx);
361 else
362 ShndxIndexes.push_back(0);
363 }
364
365 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
366
367 if (Is64Bit) {
368 write(name); // st_name
369 write(info); // st_info
370 write(other); // st_other
371 write(Index); // st_shndx
372 write(value); // st_value
373 write(size); // st_size
374 } else {
375 write(name); // st_name
376 write(uint32_t(value)); // st_value
377 write(uint32_t(size)); // st_size
378 write(info); // st_info
379 write(other); // st_other
380 write(Index); // st_shndx
381 }
382
383 ++NumWritten;
384}
385
386bool ELFWriter::is64Bit() const {
387 return OWriter.TargetObjectWriter->is64Bit();
388}
389
390bool ELFWriter::usesRela(const MCSectionELF &Sec) const {
391 return OWriter.hasRelocationAddend() &&
393}
394
395// Emit the ELF header.
396void ELFWriter::writeHeader(const MCAssembler &Asm) {
397 // ELF Header
398 // ----------
399 //
400 // Note
401 // ----
402 // emitWord method behaves differently for ELF32 and ELF64, writing
403 // 4 bytes in the former and 8 in the latter.
404
405 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
406
407 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
408
409 // e_ident[EI_DATA]
412
413 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
414 // e_ident[EI_OSABI]
415 uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
416 W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()
417 ? int(ELF::ELFOSABI_GNU)
418 : OSABI);
419 // e_ident[EI_ABIVERSION]
420 W.OS << char(OWriter.TargetObjectWriter->getABIVersion());
421
422 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
423
424 W.write<uint16_t>(ELF::ET_REL); // e_type
425
426 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
427
428 W.write<uint32_t>(ELF::EV_CURRENT); // e_version
429 WriteWord(0); // e_entry, no entry point in .o file
430 WriteWord(0); // e_phoff, no program header for .o
431 WriteWord(0); // e_shoff = sec hdr table off in bytes
432
433 // e_flags = whatever the target wants
434 W.write<uint32_t>(Asm.getELFHeaderEFlags());
435
436 // e_ehsize = ELF header size
437 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
438 : sizeof(ELF::Elf32_Ehdr));
439
440 W.write<uint16_t>(0); // e_phentsize = prog header entry size
441 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
442
443 // e_shentsize = Section header entry size
444 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
445 : sizeof(ELF::Elf32_Shdr));
446
447 // e_shnum = # of section header ents
448 W.write<uint16_t>(0);
449
450 // e_shstrndx = Section # of '.strtab'
451 assert(StringTableIndex < ELF::SHN_LORESERVE);
452 W.write<uint16_t>(StringTableIndex);
453}
454
455uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
456 const MCAsmLayout &Layout) {
457 if (Sym.isCommon())
458 return Sym.getCommonAlignment()->value();
459
460 uint64_t Res;
461 if (!Layout.getSymbolOffset(Sym, Res))
462 return 0;
463
464 if (Layout.getAssembler().isThumbFunc(&Sym))
465 Res |= 1;
466
467 return Res;
468}
469
470static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
471 uint8_t Type = newType;
472
473 // Propagation rules:
474 // IFUNC > FUNC > OBJECT > NOTYPE
475 // TLS_OBJECT > OBJECT > NOTYPE
476 //
477 // dont let the new type degrade the old type
478 switch (origType) {
479 default:
480 break;
482 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
485 break;
486 case ELF::STT_FUNC:
490 break;
491 case ELF::STT_OBJECT:
492 if (Type == ELF::STT_NOTYPE)
494 break;
495 case ELF::STT_TLS:
499 break;
500 }
501
502 return Type;
503}
504
505static bool isIFunc(const MCSymbolELF *Symbol) {
506 while (Symbol->getType() != ELF::STT_GNU_IFUNC) {
507 const MCSymbolRefExpr *Value;
508 if (!Symbol->isVariable() ||
509 !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) ||
510 Value->getKind() != MCSymbolRefExpr::VK_None ||
512 return false;
513 Symbol = &cast<MCSymbolELF>(Value->getSymbol());
514 }
515 return true;
516}
517
518void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
519 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
520 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
521 const MCSymbolELF *Base =
522 cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
523
524 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
525 // SHN_COMMON.
526 bool IsReserved = !Base || Symbol.isCommon();
527
528 // Binding and Type share the same byte as upper and lower nibbles
529 uint8_t Binding = Symbol.getBinding();
530 uint8_t Type = Symbol.getType();
531 if (isIFunc(&Symbol))
533 if (Base) {
534 Type = mergeTypeForSet(Type, Base->getType());
535 }
536 uint8_t Info = (Binding << 4) | Type;
537
538 // Other and Visibility share the same byte with Visibility using the lower
539 // 2 bits
540 uint8_t Visibility = Symbol.getVisibility();
541 uint8_t Other = Symbol.getOther() | Visibility;
542
543 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
544 uint64_t Size = 0;
545
546 const MCExpr *ESize = MSD.Symbol->getSize();
547 if (!ESize && Base) {
548 // For expressions like .set y, x+1, if y's size is unset, inherit from x.
549 ESize = Base->getSize();
550
551 // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
552 // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
553 // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
554 // needs. MCBinaryExpr is not handled.
555 const MCSymbolELF *Sym = &Symbol;
556 while (Sym->isVariable()) {
557 if (auto *Expr =
558 dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
559 Sym = cast<MCSymbolELF>(&Expr->getSymbol());
560 if (!Sym->getSize())
561 continue;
562 ESize = Sym->getSize();
563 }
564 break;
565 }
566 }
567
568 if (ESize) {
569 int64_t Res;
570 if (!ESize->evaluateKnownAbsolute(Res, Layout))
571 report_fatal_error("Size expression must be absolute.");
572 Size = Res;
573 }
574
575 // Write out the symbol table entry
576 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
577 IsReserved);
578}
579
580bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
581 bool Used, bool Renamed) {
582 if (Symbol.isVariable()) {
583 const MCExpr *Expr = Symbol.getVariableValue();
584 // Target Expressions that are always inlined do not appear in the symtab
585 if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
586 if (T->inlineAssignedExpr())
587 return false;
588 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
589 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
590 return false;
591 }
592 }
593
594 if (Used)
595 return true;
596
597 if (Renamed)
598 return false;
599
600 if (Symbol.isVariable() && Symbol.isUndefined()) {
601 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
602 Layout.getBaseSymbol(Symbol);
603 return false;
604 }
605
606 if (Symbol.isTemporary())
607 return false;
608
609 if (Symbol.getType() == ELF::STT_SECTION)
610 return false;
611
612 return true;
613}
614
615void ELFWriter::createMemtagRelocs(MCAssembler &Asm) {
616 MCSectionELF *MemtagRelocs = nullptr;
617 for (const MCSymbol &Sym : Asm.symbols()) {
618 const auto &SymE = cast<MCSymbolELF>(Sym);
619 if (!SymE.isMemtag())
620 continue;
621 if (MemtagRelocs == nullptr) {
622 MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(Asm.getContext());
623 if (MemtagRelocs == nullptr)
624 report_fatal_error("Tagged globals are not available on this architecture.");
625 Asm.registerSection(*MemtagRelocs);
626 }
627 ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
628 OWriter.Relocations[MemtagRelocs].push_back(Rec);
629 }
630}
631
632void ELFWriter::computeSymbolTable(
633 MCAssembler &Asm, const MCAsmLayout &Layout,
634 const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
635 SectionOffsetsTy &SectionOffsets) {
636 MCContext &Ctx = Asm.getContext();
637 SymbolTableWriter Writer(*this, is64Bit());
638
639 // Symbol table
640 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
641 MCSectionELF *SymtabSection =
642 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
643 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
644 SymbolTableIndex = addToSectionTable(SymtabSection);
645
646 uint64_t SecStart = align(SymtabSection->getAlign());
647
648 // The first entry is the undefined symbol entry.
649 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
650
651 std::vector<ELFSymbolData> LocalSymbolData;
652 std::vector<ELFSymbolData> ExternalSymbolData;
654 Asm.getFileNames();
655 for (const std::pair<std::string, size_t> &F : FileNames)
656 StrTabBuilder.add(F.first);
657
658 // Add the data for the symbols.
659 bool HasLargeSectionIndex = false;
660 for (auto It : llvm::enumerate(Asm.symbols())) {
661 const auto &Symbol = cast<MCSymbolELF>(It.value());
662 bool Used = Symbol.isUsedInReloc();
663 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
664 bool isSignature = Symbol.isSignature();
665
666 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
667 OWriter.Renames.count(&Symbol)))
668 continue;
669
670 if (Symbol.isTemporary() && Symbol.isUndefined()) {
671 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
672 continue;
673 }
674
675 ELFSymbolData MSD;
676 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
677 MSD.Order = It.index();
678
679 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
680 assert(Local || !Symbol.isTemporary());
681
682 if (Symbol.isAbsolute()) {
683 MSD.SectionIndex = ELF::SHN_ABS;
684 } else if (Symbol.isCommon()) {
685 if (Symbol.isTargetCommon()) {
686 MSD.SectionIndex = Symbol.getIndex();
687 } else {
688 assert(!Local);
689 MSD.SectionIndex = ELF::SHN_COMMON;
690 }
691 } else if (Symbol.isUndefined()) {
692 if (isSignature && !Used) {
693 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
694 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
695 HasLargeSectionIndex = true;
696 } else {
697 MSD.SectionIndex = ELF::SHN_UNDEF;
698 }
699 } else {
700 const MCSectionELF &Section =
701 static_cast<const MCSectionELF &>(Symbol.getSection());
702
703 // We may end up with a situation when section symbol is technically
704 // defined, but should not be. That happens because we explicitly
705 // pre-create few .debug_* sections to have accessors.
706 // And if these sections were not really defined in the code, but were
707 // referenced, we simply error out.
708 if (!Section.isRegistered()) {
709 assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
711 Ctx.reportError(SMLoc(),
712 "Undefined section reference: " + Symbol.getName());
713 continue;
714 }
715
716 if (Mode == NonDwoOnly && isDwoSection(Section))
717 continue;
718 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
719 assert(MSD.SectionIndex && "Invalid section index!");
720 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
721 HasLargeSectionIndex = true;
722 }
723
724 StringRef Name = Symbol.getName();
725
726 // Sections have their own string table
727 if (Symbol.getType() != ELF::STT_SECTION) {
728 MSD.Name = Name;
729 StrTabBuilder.add(Name);
730 }
731
732 if (Local)
733 LocalSymbolData.push_back(MSD);
734 else
735 ExternalSymbolData.push_back(MSD);
736 }
737
738 // This holds the .symtab_shndx section index.
739 unsigned SymtabShndxSectionIndex = 0;
740
741 if (HasLargeSectionIndex) {
742 MCSectionELF *SymtabShndxSection =
743 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
744 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
745 SymtabShndxSection->setAlignment(Align(4));
746 }
747
748 StrTabBuilder.finalize();
749
750 // Make the first STT_FILE precede previous local symbols.
751 unsigned Index = 1;
752 auto FileNameIt = FileNames.begin();
753 if (!FileNames.empty())
754 FileNames[0].second = 0;
755
756 for (ELFSymbolData &MSD : LocalSymbolData) {
757 // Emit STT_FILE symbols before their associated local symbols.
758 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
759 ++FileNameIt) {
760 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
762 ELF::SHN_ABS, true);
763 ++Index;
764 }
765
766 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
767 ? 0
768 : StrTabBuilder.getOffset(MSD.Name);
769 MSD.Symbol->setIndex(Index++);
770 writeSymbol(Writer, StringIndex, MSD, Layout);
771 }
772 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
773 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
775 ELF::SHN_ABS, true);
776 ++Index;
777 }
778
779 // Write the symbol table entries.
780 LastLocalSymbolIndex = Index;
781
782 for (ELFSymbolData &MSD : ExternalSymbolData) {
783 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
784 MSD.Symbol->setIndex(Index++);
785 writeSymbol(Writer, StringIndex, MSD, Layout);
786 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
787 }
788
789 uint64_t SecEnd = W.OS.tell();
790 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
791
792 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
793 if (ShndxIndexes.empty()) {
794 assert(SymtabShndxSectionIndex == 0);
795 return;
796 }
797 assert(SymtabShndxSectionIndex != 0);
798
799 SecStart = W.OS.tell();
800 const MCSectionELF *SymtabShndxSection =
801 SectionTable[SymtabShndxSectionIndex - 1];
802 for (uint32_t Index : ShndxIndexes)
803 write(Index);
804 SecEnd = W.OS.tell();
805 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
806}
807
808void ELFWriter::writeAddrsigSection() {
809 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
810 if (Sym->getIndex() != 0)
811 encodeULEB128(Sym->getIndex(), W.OS);
812}
813
814MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
815 const MCSectionELF &Sec) {
816 if (OWriter.Relocations[&Sec].empty())
817 return nullptr;
818
819 const StringRef SectionName = Sec.getName();
820 bool Rela = usesRela(Sec);
821 std::string RelaSectionName = Rela ? ".rela" : ".rel";
822 RelaSectionName += SectionName;
823
824 unsigned EntrySize;
825 if (Rela)
826 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
827 else
828 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
829
830 unsigned Flags = ELF::SHF_INFO_LINK;
831 if (Sec.getFlags() & ELF::SHF_GROUP)
832 Flags = ELF::SHF_GROUP;
833
834 MCSectionELF *RelaSection = Ctx.createELFRelSection(
835 RelaSectionName, Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, EntrySize,
836 Sec.getGroup(), &Sec);
837 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
838 return RelaSection;
839}
840
841// Include the debug info compression header.
842bool ELFWriter::maybeWriteCompression(
843 uint32_t ChType, uint64_t Size,
844 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
845 uint64_t HdrSize =
846 is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
847 if (Size <= HdrSize + CompressedContents.size())
848 return false;
849 // Platform specific header is followed by compressed data.
850 if (is64Bit()) {
851 // Write Elf64_Chdr header.
852 write(static_cast<ELF::Elf64_Word>(ChType));
853 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
854 write(static_cast<ELF::Elf64_Xword>(Size));
855 write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
856 } else {
857 // Write Elf32_Chdr header otherwise.
858 write(static_cast<ELF::Elf32_Word>(ChType));
859 write(static_cast<ELF::Elf32_Word>(Size));
860 write(static_cast<ELF::Elf32_Word>(Alignment.value()));
861 }
862 return true;
863}
864
865void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
866 const MCAsmLayout &Layout) {
867 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
868 StringRef SectionName = Section.getName();
869
870 auto &MC = Asm.getContext();
871 const auto &MAI = MC.getAsmInfo();
872
873 const DebugCompressionType CompressionType = MAI->compressDebugSections();
874 if (CompressionType == DebugCompressionType::None ||
875 !SectionName.startswith(".debug_")) {
876 Asm.writeSectionData(W.OS, &Section, Layout);
877 return;
878 }
879
880 SmallVector<char, 128> UncompressedData;
881 raw_svector_ostream VecOS(UncompressedData);
882 Asm.writeSectionData(VecOS, &Section, Layout);
883 ArrayRef<uint8_t> Uncompressed =
884 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
885 UncompressedData.size());
886
887 SmallVector<uint8_t, 128> Compressed;
888 uint32_t ChType;
889 switch (CompressionType) {
890 case DebugCompressionType::None:
891 llvm_unreachable("has been handled");
892 case DebugCompressionType::Zlib:
893 ChType = ELF::ELFCOMPRESS_ZLIB;
894 break;
895 case DebugCompressionType::Zstd:
896 ChType = ELF::ELFCOMPRESS_ZSTD;
897 break;
898 }
899 compression::compress(compression::Params(CompressionType), Uncompressed,
900 Compressed);
901 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
902 Sec.getAlign())) {
903 W.OS << UncompressedData;
904 return;
905 }
906
907 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
908 // Alignment field should reflect the requirements of
909 // the compressed section header.
910 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
911 W.OS << toStringRef(Compressed);
912}
913
914void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
915 uint64_t Address, uint64_t Offset,
916 uint64_t Size, uint32_t Link, uint32_t Info,
917 MaybeAlign Alignment, uint64_t EntrySize) {
918 W.write<uint32_t>(Name); // sh_name: index into string table
919 W.write<uint32_t>(Type); // sh_type
920 WriteWord(Flags); // sh_flags
921 WriteWord(Address); // sh_addr
922 WriteWord(Offset); // sh_offset
923 WriteWord(Size); // sh_size
924 W.write<uint32_t>(Link); // sh_link
925 W.write<uint32_t>(Info); // sh_info
926 WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
927 WriteWord(EntrySize); // sh_entsize
928}
929
930void ELFWriter::writeRelocations(const MCAssembler &Asm,
931 const MCSectionELF &Sec) {
932 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
933
934 // We record relocations by pushing to the end of a vector. Reverse the vector
935 // to get the relocations in the order they were created.
936 // In most cases that is not important, but it can be for special sections
937 // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
938 std::reverse(Relocs.begin(), Relocs.end());
939
940 // Sort the relocation entries. MIPS needs this.
941 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
942
943 const bool Rela = usesRela(Sec);
944 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
945 const ELFRelocationEntry &Entry = Relocs[e - i - 1];
946 unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
947
948 if (is64Bit()) {
949 write(Entry.Offset);
950 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
952
953 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
954 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
955 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
956 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
957 } else {
958 struct ELF::Elf64_Rela ERE64;
959 ERE64.setSymbolAndType(Index, Entry.Type);
960 write(ERE64.r_info);
961 }
962 if (Rela)
963 write(Entry.Addend);
964 } else {
965 write(uint32_t(Entry.Offset));
966
967 struct ELF::Elf32_Rela ERE32;
968 ERE32.setSymbolAndType(Index, Entry.Type);
969 write(ERE32.r_info);
970
971 if (Rela)
972 write(uint32_t(Entry.Addend));
973
974 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
975 if (uint32_t RType =
976 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
977 write(uint32_t(Entry.Offset));
978
979 ERE32.setSymbolAndType(0, RType);
980 write(ERE32.r_info);
981 write(uint32_t(0));
982 }
983 if (uint32_t RType =
984 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
985 write(uint32_t(Entry.Offset));
986
987 ERE32.setSymbolAndType(0, RType);
988 write(ERE32.r_info);
989 write(uint32_t(0));
990 }
991 }
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.startswith("@@@"))
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.startswith("@@") &&
1272 !Rest.startswith("@@@")) {
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().startswith(".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 (hasRelocationAddend()) {
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::isSymbolRefDifferenceFullyResolvedImpl(
1525 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1526 bool InSet, bool IsPCRel) const {
1527 const auto &SymA = cast<MCSymbolELF>(SA);
1528 if (IsPCRel) {
1529 assert(!InSet);
1530 if (SymA.getBinding() != ELF::STB_LOCAL ||
1531 SymA.getType() == ELF::STT_GNU_IFUNC)
1532 return false;
1533 }
1535 InSet, IsPCRel);
1536}
1537
1538std::unique_ptr<MCObjectWriter>
1539llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1540 raw_pwrite_stream &OS, bool IsLittleEndian) {
1541 return std::make_unique<ELFSingleObjectWriter>(std::move(MOTW), OS,
1542 IsLittleEndian);
1543}
1544
1545std::unique_ptr<MCObjectWriter>
1546llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1548 bool IsLittleEndian) {
1549 return std::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1550 IsLittleEndian);
1551}
#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:1275
Symbol * Sym
Definition: ELF_riscv.cpp:477
lazy value info
#define F(x, y, z)
Definition: MD5.cpp:55
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:49
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
static bool isInSymtab(const MCSymbolWasm &Sym)
static bool isDwoSection(const MCSection &Sec)
static bool is64Bit(const char *name)
static const X86InstrFMA3Group Groups[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:43
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const
If this symbol is equivalent to A + Constant, return A.
Definition: MCFragment.cpp:162
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
Definition: MCFragment.cpp:198
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
Definition: MCFragment.cpp:152
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Definition: MCFragment.cpp:96
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:50
bool isThumbFunc(const MCSymbol *Func) const
Check whether a given symbol has been flagged with .thumb_func.
Context object for machine code objects.
Definition: MCContext.h:76
MCSectionELF * createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, const MCSectionELF *RelInfoSection)
Definition: MCContext.cpp:504
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:565
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1058
MCSectionELF * createELFGroupSection(const MCSymbolELF *Group, bool IsComdat)
Definition: MCContext.cpp:607
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const
Definition: MCExpr.cpp:567
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 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:402
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:389
VariantKind getKind() const
Definition: MCExpr.h:404
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
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:577
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:289
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
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:575
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:301
bool endswith(StringRef Suffix) const
Definition: StringRef.h:280
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:428
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:672
#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
@ EI_PAD
Definition: ELF.h:57
@ EI_NIDENT
Definition: ELF.h:58
@ STB_GLOBAL
Definition: ELF.h:1247
@ STB_LOCAL
Definition: ELF.h:1246
@ STB_GNU_UNIQUE
Definition: ELF.h:1249
@ STB_WEAK
Definition: ELF.h:1248
@ EV_CURRENT
Definition: ELF.h:127
@ ET_REL
Definition: ELF.h:116
@ EM_386
Definition: ELF.h:136
@ EM_MIPS
Definition: ELF.h:141
@ ELFDATA2MSB
Definition: ELF.h:336
@ ELFDATA2LSB
Definition: ELF.h:335
@ ELFOSABI_GNU
Definition: ELF.h:344
@ ELFOSABI_NONE
Definition: ELF.h:341
static const char ElfMagic[]
Definition: ELF.h:44
@ SHT_STRTAB
Definition: ELF.h:1006
@ SHT_GROUP
Definition: ELF.h:1018
@ SHT_REL
Definition: ELF.h:1012
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition: ELF.h:1040
@ SHT_NOBITS
Definition: ELF.h:1011
@ SHT_SYMTAB
Definition: ELF.h:1005
@ SHT_DYNAMIC
Definition: ELF.h:1009
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1019
@ SHT_LLVM_ADDRSIG
Definition: ELF.h:1030
@ SHT_RELA
Definition: ELF.h:1007
@ SHN_XINDEX
Definition: ELF.h:997
@ SHN_ABS
Definition: ELF.h:995
@ SHN_COMMON
Definition: ELF.h:996
@ SHN_UNDEF
Definition: ELF.h:989
@ SHN_LORESERVE
Definition: ELF.h:990
@ STV_DEFAULT
Definition: ELF.h:1276
@ ELFCOMPRESS_ZSTD
Definition: ELF.h:1842
@ ELFCOMPRESS_ZLIB
Definition: ELF.h:1841
@ ELFCLASS64
Definition: ELF.h:329
@ ELFCLASS32
Definition: ELF.h:328
@ SHF_MERGE
Definition: ELF.h:1099
@ SHF_INFO_LINK
Definition: ELF.h:1105
@ SHF_EXCLUDE
Definition: ELF.h:1127
@ SHF_LINK_ORDER
Definition: ELF.h:1108
@ SHF_GROUP
Definition: ELF.h:1115
@ SHF_COMPRESSED
Definition: ELF.h:1121
@ SHF_TLS
Definition: ELF.h:1118
@ STT_FUNC
Definition: ELF.h:1260
@ STT_NOTYPE
Definition: ELF.h:1258
@ STT_SECTION
Definition: ELF.h:1261
@ STT_FILE
Definition: ELF.h:1262
@ STT_GNU_IFUNC
Definition: ELF.h:1265
@ STT_OBJECT
Definition: ELF.h:1259
@ STT_TLS
Definition: ELF.h:1264
@ GRP_COMDAT
Definition: ELF.h:1193
@ SYMENTRY_SIZE32
Definition: ELF.h:1240
@ SYMENTRY_SIZE64
Definition: ELF.h:1241
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1430
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.
constexpr double e
Definition: MathExtras.h:31
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:1684
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:2375
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
void setSymbolAndType(Elf32_Word s, unsigned char t)
Definition: ELF.h:1321
void setSymbolAndType(Elf64_Word s, Elf64_Word t)
Definition: ELF.h:1357
const MCSymbol * Sym
Definition: MCAssembler.h:230
@ 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