[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / MC / ELFObjectWriter.cpp
blob531d29954c382290755fb93aa873702b8f347bcb
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.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/ADT/iterator.h"
21 #include "llvm/BinaryFormat/ELF.h"
22 #include "llvm/MC/MCAsmBackend.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"
27 #include "llvm/MC/MCELFObjectWriter.h"
28 #include "llvm/MC/MCExpr.h"
29 #include "llvm/MC/MCFixup.h"
30 #include "llvm/MC/MCFixupKindInfo.h"
31 #include "llvm/MC/MCFragment.h"
32 #include "llvm/MC/MCObjectWriter.h"
33 #include "llvm/MC/MCSection.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCSymbol.h"
36 #include "llvm/MC/MCSymbolELF.h"
37 #include "llvm/MC/MCTargetOptions.h"
38 #include "llvm/MC/MCValue.h"
39 #include "llvm/MC/StringTableBuilder.h"
40 #include "llvm/Support/Alignment.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/Compression.h"
43 #include "llvm/Support/Endian.h"
44 #include "llvm/Support/EndianStream.h"
45 #include "llvm/Support/Error.h"
46 #include "llvm/Support/ErrorHandling.h"
47 #include "llvm/Support/LEB128.h"
48 #include "llvm/Support/MathExtras.h"
49 #include "llvm/Support/SMLoc.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include "llvm/TargetParser/Host.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>
62 using namespace llvm;
64 #undef DEBUG_TYPE
65 #define DEBUG_TYPE "reloc-info"
67 namespace {
69 using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
71 class ELFObjectWriter;
72 struct ELFWriter;
74 bool isDwoSection(const MCSectionELF &Sec) {
75 return Sec.getName().ends_with(".dwo");
78 class SymbolTableWriter {
79 ELFWriter &EWriter;
80 bool Is64Bit;
82 // indexes we are going to write to .symtab_shndx.
83 std::vector<uint32_t> ShndxIndexes;
85 // The numbel of symbols written so far.
86 unsigned NumWritten;
88 void createSymtabShndx();
90 template <typename T> void write(T Value);
92 public:
93 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
95 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
96 uint8_t other, uint32_t shndx, bool Reserved);
98 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
101 struct ELFWriter {
102 ELFObjectWriter &OWriter;
103 support::endian::Writer W;
105 enum DwoMode {
106 AllSections,
107 NonDwoOnly,
108 DwoOnly,
109 } Mode;
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);
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;
123 /// @}
124 /// @name Symbol Table Data
125 /// @{
127 StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
129 /// @}
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;
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);
142 // TargetObjectWriter wrappers.
143 bool is64Bit() const;
144 bool usesRela(const MCSectionELF &Sec) const;
146 uint64_t align(Align Alignment);
148 bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
149 SmallVectorImpl<uint8_t> &CompressedContents,
150 Align Alignment);
152 public:
153 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
154 bool IsLittleEndian, DwoMode Mode)
155 : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little
156 : llvm::endianness::big),
157 Mode(Mode) {}
159 void WriteWord(uint64_t Word) {
160 if (is64Bit())
161 W.write<uint64_t>(Word);
162 else
163 W.write<uint32_t>(Word);
166 template <typename T> void write(T Val) {
167 W.write(Val);
170 void writeHeader(const MCAssembler &Asm);
172 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
173 ELFSymbolData &MSD, const MCAsmLayout &Layout);
175 // Start and end offset of each section
176 using SectionOffsetsTy =
177 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
179 // Map from a signature symbol to the group section index
180 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
182 /// Compute the symbol table data
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);
192 void writeAddrsigSection();
194 MCSectionELF *createRelocationSection(MCContext &Ctx,
195 const MCSectionELF &Sec);
197 void createMemtagRelocs(MCAssembler &Asm);
199 void writeSectionHeader(const MCAsmLayout &Layout,
200 const SectionIndexMapTy &SectionIndexMap,
201 const SectionOffsetsTy &SectionOffsets);
203 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
204 const MCAsmLayout &Layout);
206 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
207 uint64_t Address, uint64_t Offset, uint64_t Size,
208 uint32_t Link, uint32_t Info, MaybeAlign Alignment,
209 uint64_t EntrySize);
211 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
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);
219 class ELFObjectWriter : public MCObjectWriter {
220 /// The target specific ELF writer instance.
221 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
223 DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
225 DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
227 bool SeenGnuAbi = false;
229 std::optional<uint8_t> OverrideABIVersion;
231 bool hasRelocationAddend() const;
233 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
234 const MCSymbolELF *Sym, uint64_t C,
235 unsigned Type) const;
237 public:
238 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
239 : TargetObjectWriter(std::move(MOTW)) {}
241 void reset() override {
242 SeenGnuAbi = false;
243 OverrideABIVersion.reset();
244 Relocations.clear();
245 Renames.clear();
246 MCObjectWriter::reset();
249 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
250 const MCSymbol &SymA,
251 const MCFragment &FB, bool InSet,
252 bool IsPCRel) const override;
254 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
255 const MCSectionELF *From,
256 const MCSectionELF *To) {
257 return true;
260 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
261 const MCFragment *Fragment, const MCFixup &Fixup,
262 MCValue Target, uint64_t &FixedValue) override;
264 void executePostLayoutBinding(MCAssembler &Asm,
265 const MCAsmLayout &Layout) override;
267 void markGnuAbi() override { SeenGnuAbi = true; }
268 bool seenGnuAbi() const { return SeenGnuAbi; }
270 bool seenOverrideABIVersion() const { return OverrideABIVersion.has_value(); }
271 uint8_t getOverrideABIVersion() const { return OverrideABIVersion.value(); }
272 void setOverrideABIVersion(uint8_t V) override { OverrideABIVersion = V; }
274 friend struct ELFWriter;
277 class ELFSingleObjectWriter : public ELFObjectWriter {
278 raw_pwrite_stream &OS;
279 bool IsLittleEndian;
281 public:
282 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
283 raw_pwrite_stream &OS, bool IsLittleEndian)
284 : ELFObjectWriter(std::move(MOTW)), OS(OS),
285 IsLittleEndian(IsLittleEndian) {}
287 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
288 return ELFWriter(*this, OS, IsLittleEndian, ELFWriter::AllSections)
289 .writeObject(Asm, Layout);
292 friend struct ELFWriter;
295 class ELFDwoObjectWriter : public ELFObjectWriter {
296 raw_pwrite_stream &OS, &DwoOS;
297 bool IsLittleEndian;
299 public:
300 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
301 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
302 bool IsLittleEndian)
303 : ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
304 IsLittleEndian(IsLittleEndian) {}
306 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
307 const MCSectionELF *To) override {
308 if (isDwoSection(*From)) {
309 Ctx.reportError(Loc, "A dwo section may not contain relocations");
310 return false;
312 if (To && isDwoSection(*To)) {
313 Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
314 return false;
316 return true;
319 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
320 uint64_t Size = ELFWriter(*this, OS, IsLittleEndian, ELFWriter::NonDwoOnly)
321 .writeObject(Asm, Layout);
322 Size += ELFWriter(*this, DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
323 .writeObject(Asm, Layout);
324 return Size;
328 } // end anonymous namespace
330 uint64_t ELFWriter::align(Align Alignment) {
331 uint64_t Offset = W.OS.tell();
332 uint64_t NewOffset = alignTo(Offset, Alignment);
333 W.OS.write_zeros(NewOffset - Offset);
334 return NewOffset;
337 unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
338 SectionTable.push_back(Sec);
339 StrTabBuilder.add(Sec->getName());
340 return SectionTable.size();
343 void SymbolTableWriter::createSymtabShndx() {
344 if (!ShndxIndexes.empty())
345 return;
347 ShndxIndexes.resize(NumWritten);
350 template <typename T> void SymbolTableWriter::write(T Value) {
351 EWriter.write(Value);
354 SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
355 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
357 void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
358 uint64_t size, uint8_t other,
359 uint32_t shndx, bool Reserved) {
360 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
362 if (LargeIndex)
363 createSymtabShndx();
365 if (!ShndxIndexes.empty()) {
366 if (LargeIndex)
367 ShndxIndexes.push_back(shndx);
368 else
369 ShndxIndexes.push_back(0);
372 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
374 if (Is64Bit) {
375 write(name); // st_name
376 write(info); // st_info
377 write(other); // st_other
378 write(Index); // st_shndx
379 write(value); // st_value
380 write(size); // st_size
381 } else {
382 write(name); // st_name
383 write(uint32_t(value)); // st_value
384 write(uint32_t(size)); // st_size
385 write(info); // st_info
386 write(other); // st_other
387 write(Index); // st_shndx
390 ++NumWritten;
393 bool ELFWriter::is64Bit() const {
394 return OWriter.TargetObjectWriter->is64Bit();
397 bool ELFWriter::usesRela(const MCSectionELF &Sec) const {
398 return OWriter.hasRelocationAddend() &&
399 Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
402 // Emit the ELF header.
403 void ELFWriter::writeHeader(const MCAssembler &Asm) {
404 // ELF Header
405 // ----------
407 // Note
408 // ----
409 // emitWord method behaves differently for ELF32 and ELF64, writing
410 // 4 bytes in the former and 8 in the latter.
412 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
414 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
416 // e_ident[EI_DATA]
417 W.OS << char(W.Endian == llvm::endianness::little ? ELF::ELFDATA2LSB
418 : ELF::ELFDATA2MSB);
420 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
421 // e_ident[EI_OSABI]
422 uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
423 W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()
424 ? int(ELF::ELFOSABI_GNU)
425 : OSABI);
426 // e_ident[EI_ABIVERSION]
427 W.OS << char(OWriter.seenOverrideABIVersion()
428 ? OWriter.getOverrideABIVersion()
429 : OWriter.TargetObjectWriter->getABIVersion());
431 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
433 W.write<uint16_t>(ELF::ET_REL); // e_type
435 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
437 W.write<uint32_t>(ELF::EV_CURRENT); // e_version
438 WriteWord(0); // e_entry, no entry point in .o file
439 WriteWord(0); // e_phoff, no program header for .o
440 WriteWord(0); // e_shoff = sec hdr table off in bytes
442 // e_flags = whatever the target wants
443 W.write<uint32_t>(Asm.getELFHeaderEFlags());
445 // e_ehsize = ELF header size
446 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
447 : sizeof(ELF::Elf32_Ehdr));
449 W.write<uint16_t>(0); // e_phentsize = prog header entry size
450 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
452 // e_shentsize = Section header entry size
453 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
454 : sizeof(ELF::Elf32_Shdr));
456 // e_shnum = # of section header ents
457 W.write<uint16_t>(0);
459 // e_shstrndx = Section # of '.strtab'
460 assert(StringTableIndex < ELF::SHN_LORESERVE);
461 W.write<uint16_t>(StringTableIndex);
464 uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
465 const MCAsmLayout &Layout) {
466 if (Sym.isCommon())
467 return Sym.getCommonAlignment()->value();
469 uint64_t Res;
470 if (!Layout.getSymbolOffset(Sym, Res))
471 return 0;
473 if (Layout.getAssembler().isThumbFunc(&Sym))
474 Res |= 1;
476 return Res;
479 static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
480 uint8_t Type = newType;
482 // Propagation rules:
483 // IFUNC > FUNC > OBJECT > NOTYPE
484 // TLS_OBJECT > OBJECT > NOTYPE
486 // dont let the new type degrade the old type
487 switch (origType) {
488 default:
489 break;
490 case ELF::STT_GNU_IFUNC:
491 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
492 Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
493 Type = ELF::STT_GNU_IFUNC;
494 break;
495 case ELF::STT_FUNC:
496 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
497 Type == ELF::STT_TLS)
498 Type = ELF::STT_FUNC;
499 break;
500 case ELF::STT_OBJECT:
501 if (Type == ELF::STT_NOTYPE)
502 Type = ELF::STT_OBJECT;
503 break;
504 case ELF::STT_TLS:
505 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
506 Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
507 Type = ELF::STT_TLS;
508 break;
511 return Type;
514 static bool isIFunc(const MCSymbolELF *Symbol) {
515 while (Symbol->getType() != ELF::STT_GNU_IFUNC) {
516 const MCSymbolRefExpr *Value;
517 if (!Symbol->isVariable() ||
518 !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) ||
519 Value->getKind() != MCSymbolRefExpr::VK_None ||
520 mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC)
521 return false;
522 Symbol = &cast<MCSymbolELF>(Value->getSymbol());
524 return true;
527 void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
528 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
529 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
530 const MCSymbolELF *Base =
531 cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
533 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
534 // SHN_COMMON.
535 bool IsReserved = !Base || Symbol.isCommon();
537 // Binding and Type share the same byte as upper and lower nibbles
538 uint8_t Binding = Symbol.getBinding();
539 uint8_t Type = Symbol.getType();
540 if (isIFunc(&Symbol))
541 Type = ELF::STT_GNU_IFUNC;
542 if (Base) {
543 Type = mergeTypeForSet(Type, Base->getType());
545 uint8_t Info = (Binding << 4) | Type;
547 // Other and Visibility share the same byte with Visibility using the lower
548 // 2 bits
549 uint8_t Visibility = Symbol.getVisibility();
550 uint8_t Other = Symbol.getOther() | Visibility;
552 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
553 uint64_t Size = 0;
555 const MCExpr *ESize = MSD.Symbol->getSize();
556 if (!ESize && Base) {
557 // For expressions like .set y, x+1, if y's size is unset, inherit from x.
558 ESize = Base->getSize();
560 // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
561 // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
562 // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
563 // needs. MCBinaryExpr is not handled.
564 const MCSymbolELF *Sym = &Symbol;
565 while (Sym->isVariable()) {
566 if (auto *Expr =
567 dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
568 Sym = cast<MCSymbolELF>(&Expr->getSymbol());
569 if (!Sym->getSize())
570 continue;
571 ESize = Sym->getSize();
573 break;
577 if (ESize) {
578 int64_t Res;
579 if (!ESize->evaluateKnownAbsolute(Res, Layout))
580 report_fatal_error("Size expression must be absolute.");
581 Size = Res;
584 // Write out the symbol table entry
585 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
586 IsReserved);
589 bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
590 bool Used, bool Renamed) {
591 if (Symbol.isVariable()) {
592 const MCExpr *Expr = Symbol.getVariableValue();
593 // Target Expressions that are always inlined do not appear in the symtab
594 if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
595 if (T->inlineAssignedExpr())
596 return false;
597 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
598 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
599 return false;
603 if (Used)
604 return true;
606 if (Renamed)
607 return false;
609 if (Symbol.isVariable() && Symbol.isUndefined()) {
610 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
611 Layout.getBaseSymbol(Symbol);
612 return false;
615 if (Symbol.isTemporary())
616 return false;
618 if (Symbol.getType() == ELF::STT_SECTION)
619 return false;
621 return true;
624 void ELFWriter::createMemtagRelocs(MCAssembler &Asm) {
625 MCSectionELF *MemtagRelocs = nullptr;
626 for (const MCSymbol &Sym : Asm.symbols()) {
627 const auto &SymE = cast<MCSymbolELF>(Sym);
628 if (!SymE.isMemtag())
629 continue;
630 if (MemtagRelocs == nullptr) {
631 MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(Asm.getContext());
632 if (MemtagRelocs == nullptr)
633 report_fatal_error("Tagged globals are not available on this architecture.");
634 Asm.registerSection(*MemtagRelocs);
636 ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
637 OWriter.Relocations[MemtagRelocs].push_back(Rec);
641 void ELFWriter::computeSymbolTable(
642 MCAssembler &Asm, const MCAsmLayout &Layout,
643 const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
644 SectionOffsetsTy &SectionOffsets) {
645 MCContext &Ctx = Asm.getContext();
646 SymbolTableWriter Writer(*this, is64Bit());
648 // Symbol table
649 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
650 MCSectionELF *SymtabSection =
651 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
652 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
653 SymbolTableIndex = addToSectionTable(SymtabSection);
655 uint64_t SecStart = align(SymtabSection->getAlign());
657 // The first entry is the undefined symbol entry.
658 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
660 std::vector<ELFSymbolData> LocalSymbolData;
661 std::vector<ELFSymbolData> ExternalSymbolData;
662 MutableArrayRef<std::pair<std::string, size_t>> FileNames =
663 Asm.getFileNames();
664 for (const std::pair<std::string, size_t> &F : FileNames)
665 StrTabBuilder.add(F.first);
667 // Add the data for the symbols.
668 bool HasLargeSectionIndex = false;
669 for (auto It : llvm::enumerate(Asm.symbols())) {
670 const auto &Symbol = cast<MCSymbolELF>(It.value());
671 bool Used = Symbol.isUsedInReloc();
672 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
673 bool isSignature = Symbol.isSignature();
675 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
676 OWriter.Renames.count(&Symbol)))
677 continue;
679 if (Symbol.isTemporary() && Symbol.isUndefined()) {
680 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
681 continue;
684 ELFSymbolData MSD;
685 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
686 MSD.Order = It.index();
688 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
689 assert(Local || !Symbol.isTemporary());
691 if (Symbol.isAbsolute()) {
692 MSD.SectionIndex = ELF::SHN_ABS;
693 } else if (Symbol.isCommon()) {
694 if (Symbol.isTargetCommon()) {
695 MSD.SectionIndex = Symbol.getIndex();
696 } else {
697 assert(!Local);
698 MSD.SectionIndex = ELF::SHN_COMMON;
700 } else if (Symbol.isUndefined()) {
701 if (isSignature && !Used) {
702 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
703 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
704 HasLargeSectionIndex = true;
705 } else {
706 MSD.SectionIndex = ELF::SHN_UNDEF;
708 } else {
709 const MCSectionELF &Section =
710 static_cast<const MCSectionELF &>(Symbol.getSection());
712 // We may end up with a situation when section symbol is technically
713 // defined, but should not be. That happens because we explicitly
714 // pre-create few .debug_* sections to have accessors.
715 // And if these sections were not really defined in the code, but were
716 // referenced, we simply error out.
717 if (!Section.isRegistered()) {
718 assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
719 ELF::STT_SECTION);
720 Ctx.reportError(SMLoc(),
721 "Undefined section reference: " + Symbol.getName());
722 continue;
725 if (Mode == NonDwoOnly && isDwoSection(Section))
726 continue;
727 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
728 assert(MSD.SectionIndex && "Invalid section index!");
729 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
730 HasLargeSectionIndex = true;
733 StringRef Name = Symbol.getName();
735 // Sections have their own string table
736 if (Symbol.getType() != ELF::STT_SECTION) {
737 MSD.Name = Name;
738 StrTabBuilder.add(Name);
741 if (Local)
742 LocalSymbolData.push_back(MSD);
743 else
744 ExternalSymbolData.push_back(MSD);
747 // This holds the .symtab_shndx section index.
748 unsigned SymtabShndxSectionIndex = 0;
750 if (HasLargeSectionIndex) {
751 MCSectionELF *SymtabShndxSection =
752 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
753 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
754 SymtabShndxSection->setAlignment(Align(4));
757 StrTabBuilder.finalize();
759 // Make the first STT_FILE precede previous local symbols.
760 unsigned Index = 1;
761 auto FileNameIt = FileNames.begin();
762 if (!FileNames.empty())
763 FileNames[0].second = 0;
765 for (ELFSymbolData &MSD : LocalSymbolData) {
766 // Emit STT_FILE symbols before their associated local symbols.
767 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
768 ++FileNameIt) {
769 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
770 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
771 ELF::SHN_ABS, true);
772 ++Index;
775 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
777 : StrTabBuilder.getOffset(MSD.Name);
778 MSD.Symbol->setIndex(Index++);
779 writeSymbol(Writer, StringIndex, MSD, Layout);
781 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
782 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
783 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
784 ELF::SHN_ABS, true);
785 ++Index;
788 // Write the symbol table entries.
789 LastLocalSymbolIndex = Index;
791 for (ELFSymbolData &MSD : ExternalSymbolData) {
792 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
793 MSD.Symbol->setIndex(Index++);
794 writeSymbol(Writer, StringIndex, MSD, Layout);
795 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
798 uint64_t SecEnd = W.OS.tell();
799 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
801 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
802 if (ShndxIndexes.empty()) {
803 assert(SymtabShndxSectionIndex == 0);
804 return;
806 assert(SymtabShndxSectionIndex != 0);
808 SecStart = W.OS.tell();
809 const MCSectionELF *SymtabShndxSection =
810 SectionTable[SymtabShndxSectionIndex - 1];
811 for (uint32_t Index : ShndxIndexes)
812 write(Index);
813 SecEnd = W.OS.tell();
814 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
817 void ELFWriter::writeAddrsigSection() {
818 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
819 if (Sym->getIndex() != 0)
820 encodeULEB128(Sym->getIndex(), W.OS);
823 MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
824 const MCSectionELF &Sec) {
825 if (OWriter.Relocations[&Sec].empty())
826 return nullptr;
828 const StringRef SectionName = Sec.getName();
829 bool Rela = usesRela(Sec);
830 std::string RelaSectionName = Rela ? ".rela" : ".rel";
831 RelaSectionName += SectionName;
833 unsigned EntrySize;
834 if (Rela)
835 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
836 else
837 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
839 unsigned Flags = ELF::SHF_INFO_LINK;
840 if (Sec.getFlags() & ELF::SHF_GROUP)
841 Flags = ELF::SHF_GROUP;
843 MCSectionELF *RelaSection = Ctx.createELFRelSection(
844 RelaSectionName, Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, EntrySize,
845 Sec.getGroup(), &Sec);
846 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
847 return RelaSection;
850 // Include the debug info compression header.
851 bool ELFWriter::maybeWriteCompression(
852 uint32_t ChType, uint64_t Size,
853 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
854 uint64_t HdrSize =
855 is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
856 if (Size <= HdrSize + CompressedContents.size())
857 return false;
858 // Platform specific header is followed by compressed data.
859 if (is64Bit()) {
860 // Write Elf64_Chdr header.
861 write(static_cast<ELF::Elf64_Word>(ChType));
862 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
863 write(static_cast<ELF::Elf64_Xword>(Size));
864 write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
865 } else {
866 // Write Elf32_Chdr header otherwise.
867 write(static_cast<ELF::Elf32_Word>(ChType));
868 write(static_cast<ELF::Elf32_Word>(Size));
869 write(static_cast<ELF::Elf32_Word>(Alignment.value()));
871 return true;
874 void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
875 const MCAsmLayout &Layout) {
876 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
877 StringRef SectionName = Section.getName();
879 auto &MC = Asm.getContext();
880 const auto &MAI = MC.getAsmInfo();
882 const DebugCompressionType CompressionType = MAI->compressDebugSections();
883 if (CompressionType == DebugCompressionType::None ||
884 !SectionName.starts_with(".debug_")) {
885 Asm.writeSectionData(W.OS, &Section, Layout);
886 return;
889 SmallVector<char, 128> UncompressedData;
890 raw_svector_ostream VecOS(UncompressedData);
891 Asm.writeSectionData(VecOS, &Section, Layout);
892 ArrayRef<uint8_t> Uncompressed =
893 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
894 UncompressedData.size());
896 SmallVector<uint8_t, 128> Compressed;
897 uint32_t ChType;
898 switch (CompressionType) {
899 case DebugCompressionType::None:
900 llvm_unreachable("has been handled");
901 case DebugCompressionType::Zlib:
902 ChType = ELF::ELFCOMPRESS_ZLIB;
903 break;
904 case DebugCompressionType::Zstd:
905 ChType = ELF::ELFCOMPRESS_ZSTD;
906 break;
908 compression::compress(compression::Params(CompressionType), Uncompressed,
909 Compressed);
910 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
911 Sec.getAlign())) {
912 W.OS << UncompressedData;
913 return;
916 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
917 // Alignment field should reflect the requirements of
918 // the compressed section header.
919 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
920 W.OS << toStringRef(Compressed);
923 void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
924 uint64_t Address, uint64_t Offset,
925 uint64_t Size, uint32_t Link, uint32_t Info,
926 MaybeAlign Alignment, uint64_t EntrySize) {
927 W.write<uint32_t>(Name); // sh_name: index into string table
928 W.write<uint32_t>(Type); // sh_type
929 WriteWord(Flags); // sh_flags
930 WriteWord(Address); // sh_addr
931 WriteWord(Offset); // sh_offset
932 WriteWord(Size); // sh_size
933 W.write<uint32_t>(Link); // sh_link
934 W.write<uint32_t>(Info); // sh_info
935 WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
936 WriteWord(EntrySize); // sh_entsize
939 void ELFWriter::writeRelocations(const MCAssembler &Asm,
940 const MCSectionELF &Sec) {
941 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
943 // We record relocations by pushing to the end of a vector. Reverse the vector
944 // to get the relocations in the order they were created.
945 // In most cases that is not important, but it can be for special sections
946 // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
947 std::reverse(Relocs.begin(), Relocs.end());
949 // Sort the relocation entries. MIPS needs this.
950 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
952 const bool Rela = usesRela(Sec);
953 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
954 const ELFRelocationEntry &Entry = Relocs[e - i - 1];
955 unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
957 if (is64Bit()) {
958 write(Entry.Offset);
959 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
960 write(uint32_t(Index));
962 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
963 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
964 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
965 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
966 } else {
967 struct ELF::Elf64_Rela ERE64;
968 ERE64.setSymbolAndType(Index, Entry.Type);
969 write(ERE64.r_info);
971 if (Rela)
972 write(Entry.Addend);
973 } else {
974 write(uint32_t(Entry.Offset));
976 struct ELF::Elf32_Rela ERE32;
977 ERE32.setSymbolAndType(Index, Entry.Type);
978 write(ERE32.r_info);
980 if (Rela)
981 write(uint32_t(Entry.Addend));
983 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
984 if (uint32_t RType =
985 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
986 write(uint32_t(Entry.Offset));
988 ERE32.setSymbolAndType(0, RType);
989 write(ERE32.r_info);
990 write(uint32_t(0));
992 if (uint32_t RType =
993 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
994 write(uint32_t(Entry.Offset));
996 ERE32.setSymbolAndType(0, RType);
997 write(ERE32.r_info);
998 write(uint32_t(0));
1005 void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
1006 uint32_t GroupSymbolIndex, uint64_t Offset,
1007 uint64_t Size, const MCSectionELF &Section) {
1008 uint64_t sh_link = 0;
1009 uint64_t sh_info = 0;
1011 switch(Section.getType()) {
1012 default:
1013 // Nothing to do.
1014 break;
1016 case ELF::SHT_DYNAMIC:
1017 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1019 case ELF::SHT_REL:
1020 case ELF::SHT_RELA: {
1021 sh_link = SymbolTableIndex;
1022 assert(sh_link && ".symtab not found");
1023 const MCSection *InfoSection = Section.getLinkedToSection();
1024 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
1025 break;
1028 case ELF::SHT_SYMTAB:
1029 sh_link = StringTableIndex;
1030 sh_info = LastLocalSymbolIndex;
1031 break;
1033 case ELF::SHT_SYMTAB_SHNDX:
1034 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
1035 case ELF::SHT_LLVM_ADDRSIG:
1036 sh_link = SymbolTableIndex;
1037 break;
1039 case ELF::SHT_GROUP:
1040 sh_link = SymbolTableIndex;
1041 sh_info = GroupSymbolIndex;
1042 break;
1045 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
1046 // If the value in the associated metadata is not a definition, Sym will be
1047 // undefined. Represent this with sh_link=0.
1048 const MCSymbol *Sym = Section.getLinkedToSymbol();
1049 if (Sym && Sym->isInSection()) {
1050 const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
1051 sh_link = SectionIndexMap.lookup(Sec);
1055 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
1056 Section.getType(), Section.getFlags(), 0, Offset, Size,
1057 sh_link, sh_info, Section.getAlign(),
1058 Section.getEntrySize());
1061 void ELFWriter::writeSectionHeader(
1062 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1063 const SectionOffsetsTy &SectionOffsets) {
1064 const unsigned NumSections = SectionTable.size();
1066 // Null section first.
1067 uint64_t FirstSectionSize =
1068 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
1069 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
1071 for (const MCSectionELF *Section : SectionTable) {
1072 uint32_t GroupSymbolIndex;
1073 unsigned Type = Section->getType();
1074 if (Type != ELF::SHT_GROUP)
1075 GroupSymbolIndex = 0;
1076 else
1077 GroupSymbolIndex = Section->getGroup()->getIndex();
1079 const std::pair<uint64_t, uint64_t> &Offsets =
1080 SectionOffsets.find(Section)->second;
1081 uint64_t Size;
1082 if (Type == ELF::SHT_NOBITS)
1083 Size = Layout.getSectionAddressSize(Section);
1084 else
1085 Size = Offsets.second - Offsets.first;
1087 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1088 *Section);
1092 uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
1093 uint64_t StartOffset = W.OS.tell();
1095 MCContext &Ctx = Asm.getContext();
1096 MCSectionELF *StrtabSection =
1097 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1098 StringTableIndex = addToSectionTable(StrtabSection);
1100 createMemtagRelocs(Asm);
1102 RevGroupMapTy RevGroupMap;
1103 SectionIndexMapTy SectionIndexMap;
1105 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1107 // Write out the ELF header ...
1108 writeHeader(Asm);
1110 // ... then the sections ...
1111 SectionOffsetsTy SectionOffsets;
1112 std::vector<MCSectionELF *> Groups;
1113 std::vector<MCSectionELF *> Relocations;
1114 for (MCSection &Sec : Asm) {
1115 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1116 if (Mode == NonDwoOnly && isDwoSection(Section))
1117 continue;
1118 if (Mode == DwoOnly && !isDwoSection(Section))
1119 continue;
1121 // Remember the offset into the file for this section.
1122 const uint64_t SecStart = align(Section.getAlign());
1124 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1125 writeSectionData(Asm, Section, Layout);
1127 uint64_t SecEnd = W.OS.tell();
1128 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1130 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1132 if (SignatureSymbol) {
1133 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1134 if (!GroupIdx) {
1135 MCSectionELF *Group =
1136 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1137 GroupIdx = addToSectionTable(Group);
1138 Group->setAlignment(Align(4));
1139 Groups.push_back(Group);
1141 std::vector<const MCSectionELF *> &Members =
1142 GroupMembers[SignatureSymbol];
1143 Members.push_back(&Section);
1144 if (RelSection)
1145 Members.push_back(RelSection);
1148 SectionIndexMap[&Section] = addToSectionTable(&Section);
1149 if (RelSection) {
1150 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1151 Relocations.push_back(RelSection);
1154 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
1157 for (MCSectionELF *Group : Groups) {
1158 // Remember the offset into the file for this section.
1159 const uint64_t SecStart = align(Group->getAlign());
1161 const MCSymbol *SignatureSymbol = Group->getGroup();
1162 assert(SignatureSymbol);
1163 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1164 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1165 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1166 write(SecIndex);
1169 uint64_t SecEnd = W.OS.tell();
1170 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1173 if (Mode == DwoOnly) {
1174 // dwo files don't have symbol tables or relocations, but they do have
1175 // string tables.
1176 StrTabBuilder.finalize();
1177 } else {
1178 MCSectionELF *AddrsigSection;
1179 if (OWriter.EmitAddrsigSection) {
1180 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1181 ELF::SHF_EXCLUDE);
1182 addToSectionTable(AddrsigSection);
1185 // Compute symbol table information.
1186 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1187 SectionOffsets);
1189 for (MCSectionELF *RelSection : Relocations) {
1190 // Remember the offset into the file for this section.
1191 const uint64_t SecStart = align(RelSection->getAlign());
1193 writeRelocations(Asm,
1194 cast<MCSectionELF>(*RelSection->getLinkedToSection()));
1196 uint64_t SecEnd = W.OS.tell();
1197 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1200 if (OWriter.EmitAddrsigSection) {
1201 uint64_t SecStart = W.OS.tell();
1202 writeAddrsigSection();
1203 uint64_t SecEnd = W.OS.tell();
1204 SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1209 uint64_t SecStart = W.OS.tell();
1210 StrTabBuilder.write(W.OS);
1211 SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
1214 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1216 // ... then the section header table ...
1217 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1219 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1220 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1221 : SectionTable.size() + 1,
1222 W.Endian);
1223 unsigned NumSectionsOffset;
1225 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1226 if (is64Bit()) {
1227 uint64_t Val =
1228 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1229 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1230 offsetof(ELF::Elf64_Ehdr, e_shoff));
1231 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1232 } else {
1233 uint32_t Val =
1234 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1235 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1236 offsetof(ELF::Elf32_Ehdr, e_shoff));
1237 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1239 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1240 NumSectionsOffset);
1242 return W.OS.tell() - StartOffset;
1245 bool ELFObjectWriter::hasRelocationAddend() const {
1246 return TargetObjectWriter->hasRelocationAddend();
1249 void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1250 const MCAsmLayout &Layout) {
1251 // The presence of symbol versions causes undefined symbols and
1252 // versions declared with @@@ to be renamed.
1253 for (const MCAssembler::Symver &S : Asm.Symvers) {
1254 StringRef AliasName = S.Name;
1255 const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
1256 size_t Pos = AliasName.find('@');
1257 assert(Pos != StringRef::npos);
1259 StringRef Prefix = AliasName.substr(0, Pos);
1260 StringRef Rest = AliasName.substr(Pos);
1261 StringRef Tail = Rest;
1262 if (Rest.starts_with("@@@"))
1263 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1265 auto *Alias =
1266 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1267 Asm.registerSymbol(*Alias);
1268 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1269 Alias->setVariableValue(Value);
1271 // Aliases defined with .symvar copy the binding from the symbol they alias.
1272 // This is the first place we are able to copy this information.
1273 Alias->setBinding(Symbol.getBinding());
1274 Alias->setVisibility(Symbol.getVisibility());
1275 Alias->setOther(Symbol.getOther());
1277 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1278 continue;
1280 if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1281 !Rest.starts_with("@@@")) {
1282 Asm.getContext().reportError(S.Loc, "default version symbol " +
1283 AliasName + " must be defined");
1284 continue;
1287 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1288 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1289 Symbol.getName());
1290 continue;
1293 Renames.insert(std::make_pair(&Symbol, Alias));
1296 for (const MCSymbol *&Sym : AddrsigSyms) {
1297 if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1298 Sym = R;
1299 if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1300 Sym = Sym->getSection().getBeginSymbol();
1301 Sym->setUsedInReloc();
1305 // It is always valid to create a relocation with a symbol. It is preferable
1306 // to use a relocation with a section if that is possible. Using the section
1307 // allows us to omit some local symbols from the symbol table.
1308 bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1309 const MCValue &Val,
1310 const MCSymbolELF *Sym,
1311 uint64_t C,
1312 unsigned Type) const {
1313 const MCSymbolRefExpr *RefA = Val.getSymA();
1314 // A PCRel relocation to an absolute value has no symbol (or section). We
1315 // represent that with a relocation to a null section.
1316 if (!RefA)
1317 return false;
1319 MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
1320 switch (Kind) {
1321 default:
1322 break;
1323 // The .odp creation emits a relocation against the symbol ".TOC." which
1324 // create a R_PPC64_TOC relocation. However the relocation symbol name
1325 // in final object creation should be NULL, since the symbol does not
1326 // really exist, it is just the reference to TOC base for the current
1327 // object file. Since the symbol is undefined, returning false results
1328 // in a relocation with a null section which is the desired result.
1329 case MCSymbolRefExpr::VK_PPC_TOCBASE:
1330 return false;
1332 // These VariantKind cause the relocation to refer to something other than
1333 // the symbol itself, like a linker generated table. Since the address of
1334 // symbol is not relevant, we cannot replace the symbol with the
1335 // section and patch the difference in the addend.
1336 case MCSymbolRefExpr::VK_GOT:
1337 case MCSymbolRefExpr::VK_PLT:
1338 case MCSymbolRefExpr::VK_GOTPCREL:
1339 case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
1340 case MCSymbolRefExpr::VK_PPC_GOT_LO:
1341 case MCSymbolRefExpr::VK_PPC_GOT_HI:
1342 case MCSymbolRefExpr::VK_PPC_GOT_HA:
1343 return true;
1346 // An undefined symbol is not in any section, so the relocation has to point
1347 // to the symbol itself.
1348 assert(Sym && "Expected a symbol");
1349 if (Sym->isUndefined())
1350 return true;
1352 // For memory-tagged symbols, ensure that the relocation uses the symbol. For
1353 // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
1354 // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
1355 // this global needs to be tagged. In addition, the linker needs to know
1356 // whether to emit a special addend when relocating `end` symbols, and this
1357 // can only be determined by the attributes of the symbol itself.
1358 if (Sym->isMemtag())
1359 return true;
1361 unsigned Binding = Sym->getBinding();
1362 switch(Binding) {
1363 default:
1364 llvm_unreachable("Invalid Binding");
1365 case ELF::STB_LOCAL:
1366 break;
1367 case ELF::STB_WEAK:
1368 // If the symbol is weak, it might be overridden by a symbol in another
1369 // file. The relocation has to point to the symbol so that the linker
1370 // can update it.
1371 return true;
1372 case ELF::STB_GLOBAL:
1373 case ELF::STB_GNU_UNIQUE:
1374 // Global ELF symbols can be preempted by the dynamic linker. The relocation
1375 // has to point to the symbol for a reason analogous to the STB_WEAK case.
1376 return true;
1379 // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1380 // reloc that the dynamic loader will use to resolve the address at startup
1381 // time.
1382 if (Sym->getType() == ELF::STT_GNU_IFUNC)
1383 return true;
1385 // If a relocation points to a mergeable section, we have to be careful.
1386 // If the offset is zero, a relocation with the section will encode the
1387 // same information. With a non-zero offset, the situation is different.
1388 // For example, a relocation can point 42 bytes past the end of a string.
1389 // If we change such a relocation to use the section, the linker would think
1390 // that it pointed to another string and subtracting 42 at runtime will
1391 // produce the wrong value.
1392 if (Sym->isInSection()) {
1393 auto &Sec = cast<MCSectionELF>(Sym->getSection());
1394 unsigned Flags = Sec.getFlags();
1395 if (Flags & ELF::SHF_MERGE) {
1396 if (C != 0)
1397 return true;
1399 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1400 // (http://sourceware.org/PR16794).
1401 if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1402 Type == ELF::R_386_GOTOFF)
1403 return true;
1405 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1406 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1407 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1408 // range of a MergeInputSection. We could introduce a new RelExpr member
1409 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1410 // but the complexity is unnecessary given that GNU as keeps the original
1411 // symbol for this case as well.
1412 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1413 !hasRelocationAddend())
1414 return true;
1417 // Most TLS relocations use a got, so they need the symbol. Even those that
1418 // are just an offset (@tpoff), require a symbol in gold versions before
1419 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1420 // http://sourceware.org/PR16773.
1421 if (Flags & ELF::SHF_TLS)
1422 return true;
1425 // If the symbol is a thumb function the final relocation must set the lowest
1426 // bit. With a symbol that is done by just having the symbol have that bit
1427 // set, so we would lose the bit if we relocated with the section.
1428 // FIXME: We could use the section but add the bit to the relocation value.
1429 if (Asm.isThumbFunc(Sym))
1430 return true;
1432 if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type))
1433 return true;
1434 return false;
1437 void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1438 const MCAsmLayout &Layout,
1439 const MCFragment *Fragment,
1440 const MCFixup &Fixup, MCValue Target,
1441 uint64_t &FixedValue) {
1442 MCAsmBackend &Backend = Asm.getBackend();
1443 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1444 MCFixupKindInfo::FKF_IsPCRel;
1445 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1446 uint64_t C = Target.getConstant();
1447 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1448 MCContext &Ctx = Asm.getContext();
1450 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1451 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1452 if (SymB.isUndefined()) {
1453 Ctx.reportError(Fixup.getLoc(),
1454 Twine("symbol '") + SymB.getName() +
1455 "' can not be undefined in a subtraction expression");
1456 return;
1459 assert(!SymB.isAbsolute() && "Should have been folded");
1460 const MCSection &SecB = SymB.getSection();
1461 if (&SecB != &FixupSection) {
1462 Ctx.reportError(Fixup.getLoc(),
1463 "Cannot represent a difference across sections");
1464 return;
1467 assert(!IsPCRel && "should have been folded");
1468 IsPCRel = true;
1469 C += FixupOffset - Layout.getSymbolOffset(SymB);
1472 // We either rejected the fixup or folded B into C at this point.
1473 const MCSymbolRefExpr *RefA = Target.getSymA();
1474 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1476 bool ViaWeakRef = false;
1477 if (SymA && SymA->isVariable()) {
1478 const MCExpr *Expr = SymA->getVariableValue();
1479 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1480 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1481 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1482 ViaWeakRef = true;
1487 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1488 ? cast<MCSectionELF>(&SymA->getSection())
1489 : nullptr;
1490 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1491 return;
1493 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1494 const auto *Parent = cast<MCSectionELF>(Fragment->getParent());
1495 // Emiting relocation with sybmol for CG Profile to help with --cg-profile.
1496 bool RelocateWithSymbol =
1497 shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||
1498 (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
1499 uint64_t Addend = 0;
1501 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1502 ? C + Layout.getSymbolOffset(*SymA)
1503 : C;
1504 if (hasRelocationAddend()) {
1505 Addend = FixedValue;
1506 FixedValue = 0;
1509 if (!RelocateWithSymbol) {
1510 const auto *SectionSymbol =
1511 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1512 if (SectionSymbol)
1513 SectionSymbol->setUsedInReloc();
1514 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
1515 Relocations[&FixupSection].push_back(Rec);
1516 return;
1519 const MCSymbolELF *RenamedSymA = SymA;
1520 if (SymA) {
1521 if (const MCSymbolELF *R = Renames.lookup(SymA))
1522 RenamedSymA = R;
1524 if (ViaWeakRef)
1525 RenamedSymA->setIsWeakrefUsedInReloc();
1526 else
1527 RenamedSymA->setUsedInReloc();
1529 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1530 Relocations[&FixupSection].push_back(Rec);
1533 bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1534 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1535 bool InSet, bool IsPCRel) const {
1536 const auto &SymA = cast<MCSymbolELF>(SA);
1537 if (IsPCRel) {
1538 assert(!InSet);
1539 if (SymA.getBinding() != ELF::STB_LOCAL ||
1540 SymA.getType() == ELF::STT_GNU_IFUNC)
1541 return false;
1543 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
1544 InSet, IsPCRel);
1547 std::unique_ptr<MCObjectWriter>
1548 llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1549 raw_pwrite_stream &OS, bool IsLittleEndian) {
1550 return std::make_unique<ELFSingleObjectWriter>(std::move(MOTW), OS,
1551 IsLittleEndian);
1554 std::unique_ptr<MCObjectWriter>
1555 llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1556 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
1557 bool IsLittleEndian) {
1558 return std::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1559 IsLittleEndian);