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