[RISCV] Refactor predicates for rvv intrinsic patterns.
[llvm-project.git] / llvm / lib / MC / ELFObjectWriter.cpp
blobea2091dffe8b376f2648d27f2886e2585bdffa9f
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/StringRef.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/ADT/iterator.h"
20 #include "llvm/BinaryFormat/ELF.h"
21 #include "llvm/MC/MCAsmBackend.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"
26 #include "llvm/MC/MCELFObjectWriter.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCFixup.h"
29 #include "llvm/MC/MCFixupKindInfo.h"
30 #include "llvm/MC/MCFragment.h"
31 #include "llvm/MC/MCObjectWriter.h"
32 #include "llvm/MC/MCSection.h"
33 #include "llvm/MC/MCSectionELF.h"
34 #include "llvm/MC/MCSymbol.h"
35 #include "llvm/MC/MCSymbolELF.h"
36 #include "llvm/MC/MCTargetOptions.h"
37 #include "llvm/MC/MCValue.h"
38 #include "llvm/MC/StringTableBuilder.h"
39 #include "llvm/Support/Alignment.h"
40 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/Compression.h"
42 #include "llvm/Support/Endian.h"
43 #include "llvm/Support/EndianStream.h"
44 #include "llvm/Support/Error.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/LEB128.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/SMLoc.h"
49 #include "llvm/Support/raw_ostream.h"
50 #include "llvm/TargetParser/Host.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>
61 using namespace llvm;
63 #undef DEBUG_TYPE
64 #define DEBUG_TYPE "reloc-info"
66 namespace {
68 using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
70 class ELFObjectWriter;
71 struct ELFWriter;
73 bool isDwoSection(const MCSectionELF &Sec) {
74 return Sec.getName().endswith(".dwo");
77 class SymbolTableWriter {
78 ELFWriter &EWriter;
79 bool Is64Bit;
81 // indexes we are going to write to .symtab_shndx.
82 std::vector<uint32_t> ShndxIndexes;
84 // The numbel of symbols written so far.
85 unsigned NumWritten;
87 void createSymtabShndx();
89 template <typename T> void write(T Value);
91 public:
92 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
94 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
95 uint8_t other, uint32_t shndx, bool Reserved);
97 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
100 struct ELFWriter {
101 ELFObjectWriter &OWriter;
102 support::endian::Writer W;
104 enum DwoMode {
105 AllSections,
106 NonDwoOnly,
107 DwoOnly,
108 } Mode;
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);
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;
122 /// @}
123 /// @name Symbol Table Data
124 /// @{
126 StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
128 /// @}
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;
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);
141 // TargetObjectWriter wrappers.
142 bool is64Bit() const;
143 bool usesRela(const MCSectionELF &Sec) const;
145 uint64_t align(Align Alignment);
147 bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
148 SmallVectorImpl<uint8_t> &CompressedContents,
149 Align Alignment);
151 public:
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) {}
157 void WriteWord(uint64_t Word) {
158 if (is64Bit())
159 W.write<uint64_t>(Word);
160 else
161 W.write<uint32_t>(Word);
164 template <typename T> void write(T Val) {
165 W.write(Val);
168 void writeHeader(const MCAssembler &Asm);
170 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
171 ELFSymbolData &MSD, const MCAsmLayout &Layout);
173 // Start and end offset of each section
174 using SectionOffsetsTy =
175 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
177 // Map from a signature symbol to the group section index
178 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
180 /// Compute the symbol table data
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);
190 void writeAddrsigSection();
192 MCSectionELF *createRelocationSection(MCContext &Ctx,
193 const MCSectionELF &Sec);
195 void createMemtagRelocs(MCAssembler &Asm);
197 void writeSectionHeader(const MCAsmLayout &Layout,
198 const SectionIndexMapTy &SectionIndexMap,
199 const SectionOffsetsTy &SectionOffsets);
201 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
202 const MCAsmLayout &Layout);
204 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
205 uint64_t Address, uint64_t Offset, uint64_t Size,
206 uint32_t Link, uint32_t Info, MaybeAlign Alignment,
207 uint64_t EntrySize);
209 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
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);
217 class ELFObjectWriter : public MCObjectWriter {
218 /// The target specific ELF writer instance.
219 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
221 DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
223 DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
225 bool SeenGnuAbi = false;
227 bool hasRelocationAddend() const;
229 bool shouldRelocateWithSymbol(const MCAssembler &Asm,
230 const MCSymbolRefExpr *RefA,
231 const MCSymbolELF *Sym, uint64_t C,
232 unsigned Type) const;
234 public:
235 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
236 : TargetObjectWriter(std::move(MOTW)) {}
238 void reset() override {
239 SeenGnuAbi = false;
240 Relocations.clear();
241 Renames.clear();
242 MCObjectWriter::reset();
245 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
246 const MCSymbol &SymA,
247 const MCFragment &FB, bool InSet,
248 bool IsPCRel) const override;
250 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
251 const MCSectionELF *From,
252 const MCSectionELF *To) {
253 return true;
256 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
257 const MCFragment *Fragment, const MCFixup &Fixup,
258 MCValue Target, uint64_t &FixedValue) override;
260 void executePostLayoutBinding(MCAssembler &Asm,
261 const MCAsmLayout &Layout) override;
263 void markGnuAbi() override { SeenGnuAbi = true; }
264 bool seenGnuAbi() const { return SeenGnuAbi; }
266 friend struct ELFWriter;
269 class ELFSingleObjectWriter : public ELFObjectWriter {
270 raw_pwrite_stream &OS;
271 bool IsLittleEndian;
273 public:
274 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
275 raw_pwrite_stream &OS, bool IsLittleEndian)
276 : ELFObjectWriter(std::move(MOTW)), OS(OS),
277 IsLittleEndian(IsLittleEndian) {}
279 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
280 return ELFWriter(*this, OS, IsLittleEndian, ELFWriter::AllSections)
281 .writeObject(Asm, Layout);
284 friend struct ELFWriter;
287 class ELFDwoObjectWriter : public ELFObjectWriter {
288 raw_pwrite_stream &OS, &DwoOS;
289 bool IsLittleEndian;
291 public:
292 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
293 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
294 bool IsLittleEndian)
295 : ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
296 IsLittleEndian(IsLittleEndian) {}
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;
304 if (To && isDwoSection(*To)) {
305 Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
306 return false;
308 return true;
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;
320 } // end anonymous namespace
322 uint64_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;
329 unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
330 SectionTable.push_back(Sec);
331 StrTabBuilder.add(Sec->getName());
332 return SectionTable.size();
335 void SymbolTableWriter::createSymtabShndx() {
336 if (!ShndxIndexes.empty())
337 return;
339 ShndxIndexes.resize(NumWritten);
342 template <typename T> void SymbolTableWriter::write(T Value) {
343 EWriter.write(Value);
346 SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
347 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
349 void 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;
354 if (LargeIndex)
355 createSymtabShndx();
357 if (!ShndxIndexes.empty()) {
358 if (LargeIndex)
359 ShndxIndexes.push_back(shndx);
360 else
361 ShndxIndexes.push_back(0);
364 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
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
382 ++NumWritten;
385 bool ELFWriter::is64Bit() const {
386 return OWriter.TargetObjectWriter->is64Bit();
389 bool ELFWriter::usesRela(const MCSectionELF &Sec) const {
390 return OWriter.hasRelocationAddend() &&
391 Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
394 // Emit the ELF header.
395 void ELFWriter::writeHeader(const MCAssembler &Asm) {
396 // ELF Header
397 // ----------
399 // Note
400 // ----
401 // emitWord method behaves differently for ELF32 and ELF64, writing
402 // 4 bytes in the former and 8 in the latter.
404 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
406 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
408 // e_ident[EI_DATA]
409 W.OS << char(W.Endian == support::little ? ELF::ELFDATA2LSB
410 : ELF::ELFDATA2MSB);
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());
421 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
423 W.write<uint16_t>(ELF::ET_REL); // e_type
425 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
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
432 // e_flags = whatever the target wants
433 W.write<uint32_t>(Asm.getELFHeaderEFlags());
435 // e_ehsize = ELF header size
436 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
437 : sizeof(ELF::Elf32_Ehdr));
439 W.write<uint16_t>(0); // e_phentsize = prog header entry size
440 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
442 // e_shentsize = Section header entry size
443 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
444 : sizeof(ELF::Elf32_Shdr));
446 // e_shnum = # of section header ents
447 W.write<uint16_t>(0);
449 // e_shstrndx = Section # of '.strtab'
450 assert(StringTableIndex < ELF::SHN_LORESERVE);
451 W.write<uint16_t>(StringTableIndex);
454 uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
455 const MCAsmLayout &Layout) {
456 if (Sym.isCommon())
457 return Sym.getCommonAlignment()->value();
459 uint64_t Res;
460 if (!Layout.getSymbolOffset(Sym, Res))
461 return 0;
463 if (Layout.getAssembler().isThumbFunc(&Sym))
464 Res |= 1;
466 return Res;
469 static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
470 uint8_t Type = newType;
472 // Propagation rules:
473 // IFUNC > FUNC > OBJECT > NOTYPE
474 // TLS_OBJECT > OBJECT > NOTYPE
476 // dont let the new type degrade the old type
477 switch (origType) {
478 default:
479 break;
480 case ELF::STT_GNU_IFUNC:
481 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
482 Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
483 Type = ELF::STT_GNU_IFUNC;
484 break;
485 case ELF::STT_FUNC:
486 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
487 Type == ELF::STT_TLS)
488 Type = ELF::STT_FUNC;
489 break;
490 case ELF::STT_OBJECT:
491 if (Type == ELF::STT_NOTYPE)
492 Type = ELF::STT_OBJECT;
493 break;
494 case ELF::STT_TLS:
495 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
496 Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
497 Type = ELF::STT_TLS;
498 break;
501 return Type;
504 static 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 ||
510 mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC)
511 return false;
512 Symbol = &cast<MCSymbolELF>(Value->getSymbol());
514 return true;
517 void 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));
523 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
524 // SHN_COMMON.
525 bool IsReserved = !Base || Symbol.isCommon();
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))
531 Type = ELF::STT_GNU_IFUNC;
532 if (Base) {
533 Type = mergeTypeForSet(Type, Base->getType());
535 uint8_t Info = (Binding << 4) | Type;
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;
542 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
543 uint64_t Size = 0;
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();
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();
563 break;
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;
574 // Write out the symbol table entry
575 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
576 IsReserved);
579 bool 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;
593 if (Used)
594 return true;
596 if (Renamed)
597 return false;
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;
605 if (Symbol.isTemporary())
606 return false;
608 if (Symbol.getType() == ELF::STT_SECTION)
609 return false;
611 return true;
614 void 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);
626 ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
627 OWriter.Relocations[MemtagRelocs].push_back(Rec);
631 void 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());
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);
645 uint64_t SecStart = align(SymtabSection->getAlign());
647 // The first entry is the undefined symbol entry.
648 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
650 std::vector<ELFSymbolData> LocalSymbolData;
651 std::vector<ELFSymbolData> ExternalSymbolData;
652 MutableArrayRef<std::pair<std::string, size_t>> FileNames =
653 Asm.getFileNames();
654 for (const std::pair<std::string, size_t> &F : FileNames)
655 StrTabBuilder.add(F.first);
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();
665 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
666 OWriter.Renames.count(&Symbol)))
667 continue;
669 if (Symbol.isTemporary() && Symbol.isUndefined()) {
670 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
671 continue;
674 ELFSymbolData MSD;
675 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
676 MSD.Order = It.index();
678 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
679 assert(Local || !Symbol.isTemporary());
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;
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;
698 } else {
699 const MCSectionELF &Section =
700 static_cast<const MCSectionELF &>(Symbol.getSection());
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() ==
709 ELF::STT_SECTION);
710 Ctx.reportError(SMLoc(),
711 "Undefined section reference: " + Symbol.getName());
712 continue;
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;
723 StringRef Name = Symbol.getName();
725 // Sections have their own string table
726 if (Symbol.getType() != ELF::STT_SECTION) {
727 MSD.Name = Name;
728 StrTabBuilder.add(Name);
731 if (Local)
732 LocalSymbolData.push_back(MSD);
733 else
734 ExternalSymbolData.push_back(MSD);
737 // This holds the .symtab_shndx section index.
738 unsigned SymtabShndxSectionIndex = 0;
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));
747 StrTabBuilder.finalize();
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;
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),
760 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
761 ELF::SHN_ABS, true);
762 ++Index;
765 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
767 : StrTabBuilder.getOffset(MSD.Name);
768 MSD.Symbol->setIndex(Index++);
769 writeSymbol(Writer, StringIndex, MSD, Layout);
771 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
772 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
773 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
774 ELF::SHN_ABS, true);
775 ++Index;
778 // Write the symbol table entries.
779 LastLocalSymbolIndex = Index;
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);
788 uint64_t SecEnd = W.OS.tell();
789 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
791 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
792 if (ShndxIndexes.empty()) {
793 assert(SymtabShndxSectionIndex == 0);
794 return;
796 assert(SymtabShndxSectionIndex != 0);
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);
807 void ELFWriter::writeAddrsigSection() {
808 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
809 if (Sym->getIndex() != 0)
810 encodeULEB128(Sym->getIndex(), W.OS);
813 MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
814 const MCSectionELF &Sec) {
815 if (OWriter.Relocations[&Sec].empty())
816 return nullptr;
818 const StringRef SectionName = Sec.getName();
819 bool Rela = usesRela(Sec);
820 std::string RelaSectionName = Rela ? ".rela" : ".rel";
821 RelaSectionName += SectionName;
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);
829 unsigned Flags = ELF::SHF_INFO_LINK;
830 if (Sec.getFlags() & ELF::SHF_GROUP)
831 Flags = ELF::SHF_GROUP;
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;
840 // Include the debug info compression header.
841 bool 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()));
861 return true;
864 void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
865 const MCAsmLayout &Layout) {
866 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
867 StringRef SectionName = Section.getName();
869 auto &MC = Asm.getContext();
870 const auto &MAI = MC.getAsmInfo();
872 const DebugCompressionType CompressionType = MAI->compressDebugSections();
873 if (CompressionType == DebugCompressionType::None ||
874 !SectionName.startswith(".debug_")) {
875 Asm.writeSectionData(W.OS, &Section, Layout);
876 return;
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());
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;
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;
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);
913 void 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
929 void ELFWriter::writeRelocations(const MCAssembler &Asm,
930 const MCSectionELF &Sec) {
931 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
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());
939 // Sort the relocation entries. MIPS needs this.
940 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
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;
947 if (is64Bit()) {
948 write(Entry.Offset);
949 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
950 write(uint32_t(Index));
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);
961 if (Rela)
962 write(Entry.Addend);
963 } else {
964 write(uint32_t(Entry.Offset));
966 struct ELF::Elf32_Rela ERE32;
967 ERE32.setSymbolAndType(Index, Entry.Type);
968 write(ERE32.r_info);
970 if (Rela)
971 write(uint32_t(Entry.Addend));
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));
978 ERE32.setSymbolAndType(0, RType);
979 write(ERE32.r_info);
980 write(uint32_t(0));
982 if (uint32_t RType =
983 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
984 write(uint32_t(Entry.Offset));
986 ERE32.setSymbolAndType(0, RType);
987 write(ERE32.r_info);
988 write(uint32_t(0));
995 void 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;
1001 switch(Section.getType()) {
1002 default:
1003 // Nothing to do.
1004 break;
1006 case ELF::SHT_DYNAMIC:
1007 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
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;
1018 case ELF::SHT_SYMTAB:
1019 sh_link = StringTableIndex;
1020 sh_info = LastLocalSymbolIndex;
1021 break;
1023 case ELF::SHT_SYMTAB_SHNDX:
1024 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
1025 case ELF::SHT_LLVM_ADDRSIG:
1026 sh_link = SymbolTableIndex;
1027 break;
1029 case ELF::SHT_GROUP:
1030 sh_link = SymbolTableIndex;
1031 sh_info = GroupSymbolIndex;
1032 break;
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);
1045 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
1046 Section.getType(), Section.getFlags(), 0, Offset, Size,
1047 sh_link, sh_info, Section.getAlign(),
1048 Section.getEntrySize());
1051 void ELFWriter::writeSectionHeader(
1052 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1053 const SectionOffsetsTy &SectionOffsets) {
1054 const unsigned NumSections = SectionTable.size();
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);
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();
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;
1077 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1078 *Section);
1082 uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
1083 uint64_t StartOffset = W.OS.tell();
1085 MCContext &Ctx = Asm.getContext();
1086 MCSectionELF *StrtabSection =
1087 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1088 StringTableIndex = addToSectionTable(StrtabSection);
1090 createMemtagRelocs(Asm);
1092 RevGroupMapTy RevGroupMap;
1093 SectionIndexMapTy SectionIndexMap;
1095 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1097 // Write out the ELF header ...
1098 writeHeader(Asm);
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;
1111 // Remember the offset into the file for this section.
1112 const uint64_t SecStart = align(Section.getAlign());
1114 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1115 writeSectionData(Asm, Section, Layout);
1117 uint64_t SecEnd = W.OS.tell();
1118 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1120 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
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);
1131 std::vector<const MCSectionELF *> &Members =
1132 GroupMembers[SignatureSymbol];
1133 Members.push_back(&Section);
1134 if (RelSection)
1135 Members.push_back(RelSection);
1138 SectionIndexMap[&Section] = addToSectionTable(&Section);
1139 if (RelSection) {
1140 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1141 Relocations.push_back(RelSection);
1144 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
1147 for (MCSectionELF *Group : Groups) {
1148 // Remember the offset into the file for this section.
1149 const uint64_t SecStart = align(Group->getAlign());
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);
1159 uint64_t SecEnd = W.OS.tell();
1160 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
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,
1171 ELF::SHF_EXCLUDE);
1172 addToSectionTable(AddrsigSection);
1175 // Compute symbol table information.
1176 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1177 SectionOffsets);
1179 for (MCSectionELF *RelSection : Relocations) {
1180 // Remember the offset into the file for this section.
1181 const uint64_t SecStart = align(RelSection->getAlign());
1183 writeRelocations(Asm,
1184 cast<MCSectionELF>(*RelSection->getLinkedToSection()));
1186 uint64_t SecEnd = W.OS.tell();
1187 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
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);
1199 uint64_t SecStart = W.OS.tell();
1200 StrTabBuilder.write(W.OS);
1201 SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
1204 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1206 // ... then the section header table ...
1207 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
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;
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);
1229 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1230 NumSectionsOffset);
1232 return W.OS.tell() - StartOffset;
1235 bool ELFObjectWriter::hasRelocationAddend() const {
1236 return TargetObjectWriter->hasRelocationAddend();
1239 void 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);
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);
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);
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());
1267 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1268 continue;
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;
1277 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1278 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1279 Symbol.getName());
1280 continue;
1283 Renames.insert(std::make_pair(&Symbol, Alias));
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();
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.
1298 bool 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;
1308 MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
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.
1318 case MCSymbolRefExpr::VK_PPC_TOCBASE:
1319 return false;
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.
1325 case MCSymbolRefExpr::VK_GOT:
1326 case MCSymbolRefExpr::VK_PLT:
1327 case MCSymbolRefExpr::VK_GOTPCREL:
1328 case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
1329 case MCSymbolRefExpr::VK_PPC_GOT_LO:
1330 case MCSymbolRefExpr::VK_PPC_GOT_HI:
1331 case MCSymbolRefExpr::VK_PPC_GOT_HA:
1332 return true;
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;
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;
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:
1362 case ELF::STB_GNU_UNIQUE:
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;
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;
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;
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;
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;
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;
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;
1421 if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
1422 return true;
1423 return false;
1426 void 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 &
1433 MCFixupKindInfo::FKF_IsPCRel;
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();
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;
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;
1456 assert(!IsPCRel && "should have been folded");
1457 IsPCRel = true;
1458 C += FixupOffset - Layout.getSymbolOffset(SymB);
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;
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;
1476 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1477 ? cast<MCSectionELF>(&SymA->getSection())
1478 : nullptr;
1479 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1480 return;
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;
1490 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1491 ? C + Layout.getSymbolOffset(*SymA)
1492 : C;
1493 if (hasRelocationAddend()) {
1494 Addend = FixedValue;
1495 FixedValue = 0;
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;
1508 const MCSymbolELF *RenamedSymA = SymA;
1509 if (SymA) {
1510 if (const MCSymbolELF *R = Renames.lookup(SymA))
1511 RenamedSymA = R;
1513 if (ViaWeakRef)
1514 RenamedSymA->setIsWeakrefUsedInReloc();
1515 else
1516 RenamedSymA->setUsedInReloc();
1518 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1519 Relocations[&FixupSection].push_back(Rec);
1522 bool 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;
1532 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
1533 InSet, IsPCRel);
1536 std::unique_ptr<MCObjectWriter>
1537 llvm::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);
1543 std::unique_ptr<MCObjectWriter>
1544 llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1545 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
1546 bool IsLittleEndian) {
1547 return std::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1548 IsLittleEndian);