1//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements ELF object file writer information.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/STLExtras.h"
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>
61
62using namespace llvm;
63
64#undef DEBUG_TYPE
65#define DEBUG_TYPE "reloc-info"
66
67namespace {
68
69using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
70
71class ELFObjectWriter;
72struct ELFWriter;
73
74bool isDwoSection(const MCSectionELF &Sec) {
75 return Sec.getName().ends_with(Suffix: ".dwo");
76}
77
78class SymbolTableWriter {
79 ELFWriter &EWriter;
80 bool Is64Bit;
81
82 // indexes we are going to write to .symtab_shndx.
83 std::vector<uint32_t> ShndxIndexes;
84
85 // The numbel of symbols written so far.
86 unsigned NumWritten;
87
88 void createSymtabShndx();
89
90 template <typename T> void write(T Value);
91
92public:
93 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
94
95 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
96 uint8_t other, uint32_t shndx, bool Reserved);
97
98 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
99};
100
101struct ELFWriter {
102 ELFObjectWriter &OWriter;
103 support::endian::Writer W;
104
105 enum DwoMode {
106 AllSections,
107 NonDwoOnly,
108 DwoOnly,
109 } Mode;
110
111 static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
112 static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
113 bool Used, bool Renamed);
114
115 /// Helper struct for containing some precomputed information on symbols.
116 struct ELFSymbolData {
117 const MCSymbolELF *Symbol;
118 StringRef Name;
119 uint32_t SectionIndex;
120 uint32_t Order;
121 };
122
123 /// @}
124 /// @name Symbol Table Data
125 /// @{
126
127 StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
128
129 /// @}
130
131 // This holds the symbol table index of the last local symbol.
132 unsigned LastLocalSymbolIndex = ~0u;
133 // This holds the .strtab section index.
134 unsigned StringTableIndex = ~0u;
135 // This holds the .symtab section index.
136 unsigned SymbolTableIndex = ~0u;
137
138 // Sections in the order they are to be output in the section table.
139 std::vector<const MCSectionELF *> SectionTable;
140 unsigned addToSectionTable(const MCSectionELF *Sec);
141
142 // TargetObjectWriter wrappers.
143 bool is64Bit() const;
144 bool usesRela(const MCSectionELF &Sec) const;
145
146 uint64_t align(Align Alignment);
147
148 bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
149 SmallVectorImpl<uint8_t> &CompressedContents,
150 Align Alignment);
151
152public:
153 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
154 bool IsLittleEndian, DwoMode Mode)
155 : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little
156 : llvm::endianness::big),
157 Mode(Mode) {}
158
159 void WriteWord(uint64_t Word) {
160 if (is64Bit())
161 W.write<uint64_t>(Val: Word);
162 else
163 W.write<uint32_t>(Val: Word);
164 }
165
166 template <typename T> void write(T Val) {
167 W.write(Val);
168 }
169
170 void writeHeader(const MCAssembler &Asm);
171
172 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
173 ELFSymbolData &MSD, const MCAsmLayout &Layout);
174
175 // Start and end offset of each section
176 using SectionOffsetsTy =
177 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
178
179 // Map from a signature symbol to the group section index
180 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
181
182 /// Compute the symbol table data
183 ///
184 /// \param Asm - The assembler.
185 /// \param SectionIndexMap - Maps a section to its index.
186 /// \param RevGroupMap - Maps a signature symbol to the group section.
187 void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
188 const SectionIndexMapTy &SectionIndexMap,
189 const RevGroupMapTy &RevGroupMap,
190 SectionOffsetsTy &SectionOffsets);
191
192 void writeAddrsigSection();
193
194 MCSectionELF *createRelocationSection(MCContext &Ctx,
195 const MCSectionELF &Sec);
196
197 void createMemtagRelocs(MCAssembler &Asm);
198
199 void writeSectionHeader(const MCAsmLayout &Layout,
200 const SectionIndexMapTy &SectionIndexMap,
201 const SectionOffsetsTy &SectionOffsets);
202
203 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
204 const MCAsmLayout &Layout);
205
206 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
207 uint64_t Address, uint64_t Offset, uint64_t Size,
208 uint32_t Link, uint32_t Info, MaybeAlign Alignment,
209 uint64_t EntrySize);
210
211 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
212
213 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
214 void writeSection(const SectionIndexMapTy &SectionIndexMap,
215 uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
216 const MCSectionELF &Section);
217};
218
219class ELFObjectWriter : public MCObjectWriter {
220 /// The target specific ELF writer instance.
221 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
222
223 DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
224
225 DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
226
227 bool SeenGnuAbi = false;
228
229 std::optional<uint8_t> OverrideABIVersion;
230
231 bool hasRelocationAddend() const;
232
233 bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val,
234 const MCSymbolELF *Sym, uint64_t C,
235 unsigned Type) const;
236
237public:
238 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
239 : TargetObjectWriter(std::move(MOTW)) {}
240
241 void reset() override {
242 SeenGnuAbi = false;
243 OverrideABIVersion.reset();
244 Relocations.clear();
245 Renames.clear();
246 MCObjectWriter::reset();
247 }
248
249 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
250 const MCSymbol &SymA,
251 const MCFragment &FB, bool InSet,
252 bool IsPCRel) const override;
253
254 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
255 const MCSectionELF *From,
256 const MCSectionELF *To) {
257 return true;
258 }
259
260 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
261 const MCFragment *Fragment, const MCFixup &Fixup,
262 MCValue Target, uint64_t &FixedValue) override;
263
264 void executePostLayoutBinding(MCAssembler &Asm,
265 const MCAsmLayout &Layout) override;
266
267 void markGnuAbi() override { SeenGnuAbi = true; }
268 bool seenGnuAbi() const { return SeenGnuAbi; }
269
270 bool seenOverrideABIVersion() const { return OverrideABIVersion.has_value(); }
271 uint8_t getOverrideABIVersion() const { return OverrideABIVersion.value(); }
272 void setOverrideABIVersion(uint8_t V) override { OverrideABIVersion = V; }
273
274 friend struct ELFWriter;
275};
276
277class ELFSingleObjectWriter : public ELFObjectWriter {
278 raw_pwrite_stream &OS;
279 bool IsLittleEndian;
280
281public:
282 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
283 raw_pwrite_stream &OS, bool IsLittleEndian)
284 : ELFObjectWriter(std::move(MOTW)), OS(OS),
285 IsLittleEndian(IsLittleEndian) {}
286
287 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
288 return ELFWriter(*this, OS, IsLittleEndian, ELFWriter::AllSections)
289 .writeObject(Asm, Layout);
290 }
291
292 friend struct ELFWriter;
293};
294
295class ELFDwoObjectWriter : public ELFObjectWriter {
296 raw_pwrite_stream &OS, &DwoOS;
297 bool IsLittleEndian;
298
299public:
300 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
301 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
302 bool IsLittleEndian)
303 : ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
304 IsLittleEndian(IsLittleEndian) {}
305
306 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
307 const MCSectionELF *To) override {
308 if (isDwoSection(Sec: *From)) {
309 Ctx.reportError(L: Loc, Msg: "A dwo section may not contain relocations");
310 return false;
311 }
312 if (To && isDwoSection(Sec: *To)) {
313 Ctx.reportError(L: Loc, Msg: "A relocation may not refer to a dwo section");
314 return false;
315 }
316 return true;
317 }
318
319 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
320 uint64_t Size = ELFWriter(*this, OS, IsLittleEndian, ELFWriter::NonDwoOnly)
321 .writeObject(Asm, Layout);
322 Size += ELFWriter(*this, DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
323 .writeObject(Asm, Layout);
324 return Size;
325 }
326};
327
328} // end anonymous namespace
329
330uint64_t ELFWriter::align(Align Alignment) {
331 uint64_t Offset = W.OS.tell();
332 uint64_t NewOffset = alignTo(Size: Offset, A: Alignment);
333 W.OS.write_zeros(NumZeros: NewOffset - Offset);
334 return NewOffset;
335}
336
337unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
338 SectionTable.push_back(x: Sec);
339 StrTabBuilder.add(S: Sec->getName());
340 return SectionTable.size();
341}
342
343void SymbolTableWriter::createSymtabShndx() {
344 if (!ShndxIndexes.empty())
345 return;
346
347 ShndxIndexes.resize(new_size: NumWritten);
348}
349
350template <typename T> void SymbolTableWriter::write(T Value) {
351 EWriter.write(Value);
352}
353
354SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
355 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
356
357void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
358 uint64_t size, uint8_t other,
359 uint32_t shndx, bool Reserved) {
360 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
361
362 if (LargeIndex)
363 createSymtabShndx();
364
365 if (!ShndxIndexes.empty()) {
366 if (LargeIndex)
367 ShndxIndexes.push_back(x: shndx);
368 else
369 ShndxIndexes.push_back(x: 0);
370 }
371
372 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
373
374 if (Is64Bit) {
375 write(Value: name); // st_name
376 write(Value: info); // st_info
377 write(Value: other); // st_other
378 write(Value: Index); // st_shndx
379 write(Value: value); // st_value
380 write(Value: size); // st_size
381 } else {
382 write(Value: name); // st_name
383 write(Value: uint32_t(value)); // st_value
384 write(Value: uint32_t(size)); // st_size
385 write(Value: info); // st_info
386 write(Value: other); // st_other
387 write(Value: Index); // st_shndx
388 }
389
390 ++NumWritten;
391}
392
393bool ELFWriter::is64Bit() const {
394 return OWriter.TargetObjectWriter->is64Bit();
395}
396
397bool ELFWriter::usesRela(const MCSectionELF &Sec) const {
398 return OWriter.hasRelocationAddend() &&
399 Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
400}
401
402// Emit the ELF header.
403void ELFWriter::writeHeader(const MCAssembler &Asm) {
404 // ELF Header
405 // ----------
406 //
407 // Note
408 // ----
409 // emitWord method behaves differently for ELF32 and ELF64, writing
410 // 4 bytes in the former and 8 in the latter.
411
412 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
413
414 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
415
416 // e_ident[EI_DATA]
417 W.OS << char(W.Endian == llvm::endianness::little ? ELF::ELFDATA2LSB
418 : ELF::ELFDATA2MSB);
419
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());
430
431 W.OS.write_zeros(NumZeros: ELF::EI_NIDENT - ELF::EI_PAD);
432
433 W.write<uint16_t>(Val: ELF::ET_REL); // e_type
434
435 W.write<uint16_t>(Val: OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
436
437 W.write<uint32_t>(Val: ELF::EV_CURRENT); // e_version
438 WriteWord(Word: 0); // e_entry, no entry point in .o file
439 WriteWord(Word: 0); // e_phoff, no program header for .o
440 WriteWord(Word: 0); // e_shoff = sec hdr table off in bytes
441
442 // e_flags = whatever the target wants
443 W.write<uint32_t>(Val: Asm.getELFHeaderEFlags());
444
445 // e_ehsize = ELF header size
446 W.write<uint16_t>(Val: is64Bit() ? sizeof(ELF::Elf64_Ehdr)
447 : sizeof(ELF::Elf32_Ehdr));
448
449 W.write<uint16_t>(Val: 0); // e_phentsize = prog header entry size
450 W.write<uint16_t>(Val: 0); // e_phnum = # prog header entries = 0
451
452 // e_shentsize = Section header entry size
453 W.write<uint16_t>(Val: is64Bit() ? sizeof(ELF::Elf64_Shdr)
454 : sizeof(ELF::Elf32_Shdr));
455
456 // e_shnum = # of section header ents
457 W.write<uint16_t>(Val: 0);
458
459 // e_shstrndx = Section # of '.strtab'
460 assert(StringTableIndex < ELF::SHN_LORESERVE);
461 W.write<uint16_t>(Val: StringTableIndex);
462}
463
464uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
465 const MCAsmLayout &Layout) {
466 if (Sym.isCommon())
467 return Sym.getCommonAlignment()->value();
468
469 uint64_t Res;
470 if (!Layout.getSymbolOffset(S: Sym, Val&: Res))
471 return 0;
472
473 if (Layout.getAssembler().isThumbFunc(Func: &Sym))
474 Res |= 1;
475
476 return Res;
477}
478
479static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
480 uint8_t Type = newType;
481
482 // Propagation rules:
483 // IFUNC > FUNC > OBJECT > NOTYPE
484 // TLS_OBJECT > OBJECT > NOTYPE
485 //
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;
509 }
510
511 return Type;
512}
513
514static 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>(Val: Symbol->getVariableValue())) ||
519 Value->getKind() != MCSymbolRefExpr::VK_None ||
520 mergeTypeForSet(origType: Symbol->getType(), newType: ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC)
521 return false;
522 Symbol = &cast<MCSymbolELF>(Val: Value->getSymbol());
523 }
524 return true;
525}
526
527void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
528 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
529 const auto &Symbol = cast<MCSymbolELF>(Val: *MSD.Symbol);
530 const MCSymbolELF *Base =
531 cast_or_null<MCSymbolELF>(Val: Layout.getBaseSymbol(Symbol));
532
533 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
534 // SHN_COMMON.
535 bool IsReserved = !Base || Symbol.isCommon();
536
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: &Symbol))
541 Type = ELF::STT_GNU_IFUNC;
542 if (Base) {
543 Type = mergeTypeForSet(origType: Type, newType: Base->getType());
544 }
545 uint8_t Info = (Binding << 4) | Type;
546
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;
551
552 uint64_t Value = SymbolValue(Sym: *MSD.Symbol, Layout);
553 uint64_t Size = 0;
554
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();
559
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>(Val: Sym->getVariableValue(SetUsed: false))) {
568 Sym = cast<MCSymbolELF>(Val: &Expr->getSymbol());
569 if (!Sym->getSize())
570 continue;
571 ESize = Sym->getSize();
572 }
573 break;
574 }
575 }
576
577 if (ESize) {
578 int64_t Res;
579 if (!ESize->evaluateKnownAbsolute(Res, Layout))
580 report_fatal_error(reason: "Size expression must be absolute.");
581 Size = Res;
582 }
583
584 // Write out the symbol table entry
585 Writer.writeSymbol(name: StringIndex, info: Info, value: Value, size: Size, other: Other, shndx: MSD.SectionIndex,
586 Reserved: IsReserved);
587}
588
589bool 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>(Val: Expr))
595 if (T->inlineAssignedExpr())
596 return false;
597 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Val: Expr)) {
598 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
599 return false;
600 }
601 }
602
603 if (Used)
604 return true;
605
606 if (Renamed)
607 return false;
608
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;
613 }
614
615 if (Symbol.isTemporary())
616 return false;
617
618 if (Symbol.getType() == ELF::STT_SECTION)
619 return false;
620
621 return true;
622}
623
624void ELFWriter::createMemtagRelocs(MCAssembler &Asm) {
625 MCSectionELF *MemtagRelocs = nullptr;
626 for (const MCSymbol &Sym : Asm.symbols()) {
627 const auto &SymE = cast<MCSymbolELF>(Val: Sym);
628 if (!SymE.isMemtag())
629 continue;
630 if (MemtagRelocs == nullptr) {
631 MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(Ctx&: Asm.getContext());
632 if (MemtagRelocs == nullptr)
633 report_fatal_error(reason: "Tagged globals are not available on this architecture.");
634 Asm.registerSection(Section&: *MemtagRelocs);
635 }
636 ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
637 OWriter.Relocations[MemtagRelocs].push_back(x: Rec);
638 }
639}
640
641void 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());
647
648 // Symbol table
649 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
650 MCSectionELF *SymtabSection =
651 Ctx.getELFSection(Section: ".symtab", Type: ELF::SHT_SYMTAB, Flags: 0, EntrySize);
652 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
653 SymbolTableIndex = addToSectionTable(Sec: SymtabSection);
654
655 uint64_t SecStart = align(Alignment: SymtabSection->getAlign());
656
657 // The first entry is the undefined symbol entry.
658 Writer.writeSymbol(name: 0, info: 0, value: 0, size: 0, other: 0, shndx: 0, Reserved: false);
659
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(S: F.first);
666
667 // Add the data for the symbols.
668 bool HasLargeSectionIndex = false;
669 for (auto It : llvm::enumerate(First: Asm.symbols())) {
670 const auto &Symbol = cast<MCSymbolELF>(Val: It.value());
671 bool Used = Symbol.isUsedInReloc();
672 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
673 bool isSignature = Symbol.isSignature();
674
675 if (!isInSymtab(Layout, Symbol, Used: Used || WeakrefUsed || isSignature,
676 Renamed: OWriter.Renames.count(Val: &Symbol)))
677 continue;
678
679 if (Symbol.isTemporary() && Symbol.isUndefined()) {
680 Ctx.reportError(L: SMLoc(), Msg: "Undefined temporary symbol " + Symbol.getName());
681 continue;
682 }
683
684 ELFSymbolData MSD;
685 MSD.Symbol = cast<MCSymbolELF>(Val: &Symbol);
686 MSD.Order = It.index();
687
688 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
689 assert(Local || !Symbol.isTemporary());
690
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;
699 }
700 } else if (Symbol.isUndefined()) {
701 if (isSignature && !Used) {
702 MSD.SectionIndex = RevGroupMap.lookup(Val: &Symbol);
703 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
704 HasLargeSectionIndex = true;
705 } else {
706 MSD.SectionIndex = ELF::SHN_UNDEF;
707 }
708 } else {
709 const MCSectionELF &Section =
710 static_cast<const MCSectionELF &>(Symbol.getSection());
711
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(L: SMLoc(),
721 Msg: "Undefined section reference: " + Symbol.getName());
722 continue;
723 }
724
725 if (Mode == NonDwoOnly && isDwoSection(Sec: Section))
726 continue;
727 MSD.SectionIndex = SectionIndexMap.lookup(Val: &Section);
728 assert(MSD.SectionIndex && "Invalid section index!");
729 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
730 HasLargeSectionIndex = true;
731 }
732
733 StringRef Name = Symbol.getName();
734
735 // Sections have their own string table
736 if (Symbol.getType() != ELF::STT_SECTION) {
737 MSD.Name = Name;
738 StrTabBuilder.add(S: Name);
739 }
740
741 if (Local)
742 LocalSymbolData.push_back(x: MSD);
743 else
744 ExternalSymbolData.push_back(x: MSD);
745 }
746
747 // This holds the .symtab_shndx section index.
748 unsigned SymtabShndxSectionIndex = 0;
749
750 if (HasLargeSectionIndex) {
751 MCSectionELF *SymtabShndxSection =
752 Ctx.getELFSection(Section: ".symtab_shndx", Type: ELF::SHT_SYMTAB_SHNDX, Flags: 0, EntrySize: 4);
753 SymtabShndxSectionIndex = addToSectionTable(Sec: SymtabShndxSection);
754 SymtabShndxSection->setAlignment(Align(4));
755 }
756
757 StrTabBuilder.finalize();
758
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;
764
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(name: StrTabBuilder.getOffset(S: FileNameIt->first),
770 info: ELF::STT_FILE | ELF::STB_LOCAL, value: 0, size: 0, other: ELF::STV_DEFAULT,
771 shndx: ELF::SHN_ABS, Reserved: true);
772 ++Index;
773 }
774
775 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
776 ? 0
777 : StrTabBuilder.getOffset(S: MSD.Name);
778 MSD.Symbol->setIndex(Index++);
779 writeSymbol(Writer, StringIndex, MSD, Layout);
780 }
781 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
782 Writer.writeSymbol(name: StrTabBuilder.getOffset(S: FileNameIt->first),
783 info: ELF::STT_FILE | ELF::STB_LOCAL, value: 0, size: 0, other: ELF::STV_DEFAULT,
784 shndx: ELF::SHN_ABS, Reserved: true);
785 ++Index;
786 }
787
788 // Write the symbol table entries.
789 LastLocalSymbolIndex = Index;
790
791 for (ELFSymbolData &MSD : ExternalSymbolData) {
792 unsigned StringIndex = StrTabBuilder.getOffset(S: MSD.Name);
793 MSD.Symbol->setIndex(Index++);
794 writeSymbol(Writer, StringIndex, MSD, Layout);
795 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
796 }
797
798 uint64_t SecEnd = W.OS.tell();
799 SectionOffsets[SymtabSection] = std::make_pair(x&: SecStart, y&: SecEnd);
800
801 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
802 if (ShndxIndexes.empty()) {
803 assert(SymtabShndxSectionIndex == 0);
804 return;
805 }
806 assert(SymtabShndxSectionIndex != 0);
807
808 SecStart = W.OS.tell();
809 const MCSectionELF *SymtabShndxSection =
810 SectionTable[SymtabShndxSectionIndex - 1];
811 for (uint32_t Index : ShndxIndexes)
812 write(Val: Index);
813 SecEnd = W.OS.tell();
814 SectionOffsets[SymtabShndxSection] = std::make_pair(x&: SecStart, y&: SecEnd);
815}
816
817void ELFWriter::writeAddrsigSection() {
818 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
819 if (Sym->getIndex() != 0)
820 encodeULEB128(Value: Sym->getIndex(), OS&: W.OS);
821}
822
823MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
824 const MCSectionELF &Sec) {
825 if (OWriter.Relocations[&Sec].empty())
826 return nullptr;
827
828 const StringRef SectionName = Sec.getName();
829 bool Rela = usesRela(Sec);
830 std::string RelaSectionName = Rela ? ".rela" : ".rel";
831 RelaSectionName += SectionName;
832
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);
838
839 unsigned Flags = ELF::SHF_INFO_LINK;
840 if (Sec.getFlags() & ELF::SHF_GROUP)
841 Flags = ELF::SHF_GROUP;
842
843 MCSectionELF *RelaSection = Ctx.createELFRelSection(
844 Name: RelaSectionName, Type: Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, EntrySize,
845 Group: Sec.getGroup(), RelInfoSection: &Sec);
846 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
847 return RelaSection;
848}
849
850// Include the debug info compression header.
851bool 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(Val: static_cast<ELF::Elf64_Word>(ChType));
862 write(Val: static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
863 write(Val: static_cast<ELF::Elf64_Xword>(Size));
864 write(Val: static_cast<ELF::Elf64_Xword>(Alignment.value()));
865 } else {
866 // Write Elf32_Chdr header otherwise.
867 write(Val: static_cast<ELF::Elf32_Word>(ChType));
868 write(Val: static_cast<ELF::Elf32_Word>(Size));
869 write(Val: static_cast<ELF::Elf32_Word>(Alignment.value()));
870 }
871 return true;
872}
873
874void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
875 const MCAsmLayout &Layout) {
876 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
877 StringRef SectionName = Section.getName();
878
879 auto &MC = Asm.getContext();
880 const auto &MAI = MC.getAsmInfo();
881
882 const DebugCompressionType CompressionType = MAI->compressDebugSections();
883 if (CompressionType == DebugCompressionType::None ||
884 !SectionName.starts_with(Prefix: ".debug_")) {
885 Asm.writeSectionData(OS&: W.OS, Section: &Section, Layout);
886 return;
887 }
888
889 SmallVector<char, 128> UncompressedData;
890 raw_svector_ostream VecOS(UncompressedData);
891 Asm.writeSectionData(OS&: VecOS, Section: &Section, Layout);
892 ArrayRef<uint8_t> Uncompressed =
893 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
894 UncompressedData.size());
895
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;
907 }
908 compression::compress(P: compression::Params(CompressionType), Input: Uncompressed,
909 Output&: Compressed);
910 if (!maybeWriteCompression(ChType, Size: UncompressedData.size(), CompressedContents&: Compressed,
911 Alignment: Sec.getAlign())) {
912 W.OS << UncompressedData;
913 return;
914 }
915
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(Input: Compressed);
921}
922
923void 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>(Val: Name); // sh_name: index into string table
928 W.write<uint32_t>(Val: Type); // sh_type
929 WriteWord(Word: Flags); // sh_flags
930 WriteWord(Word: Address); // sh_addr
931 WriteWord(Word: Offset); // sh_offset
932 WriteWord(Word: Size); // sh_size
933 W.write<uint32_t>(Val: Link); // sh_link
934 W.write<uint32_t>(Val: Info); // sh_info
935 WriteWord(Word: Alignment ? Alignment->value() : 0); // sh_addralign
936 WriteWord(Word: EntrySize); // sh_entsize
937}
938
939void ELFWriter::writeRelocations(const MCAssembler &Asm,
940 const MCSectionELF &Sec) {
941 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
942
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(first: Relocs.begin(), last: Relocs.end());
948
949 // Sort the relocation entries. MIPS needs this.
950 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
951
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;
956
957 if (is64Bit()) {
958 write(Val: Entry.Offset);
959 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
960 write(Val: uint32_t(Index));
961
962 write(Val: OWriter.TargetObjectWriter->getRSsym(Type: Entry.Type));
963 write(Val: OWriter.TargetObjectWriter->getRType3(Type: Entry.Type));
964 write(Val: OWriter.TargetObjectWriter->getRType2(Type: Entry.Type));
965 write(Val: OWriter.TargetObjectWriter->getRType(Type: Entry.Type));
966 } else {
967 struct ELF::Elf64_Rela ERE64;
968 ERE64.setSymbolAndType(s: Index, t: Entry.Type);
969 write(Val: ERE64.r_info);
970 }
971 if (Rela)
972 write(Val: Entry.Addend);
973 } else {
974 write(Val: uint32_t(Entry.Offset));
975
976 struct ELF::Elf32_Rela ERE32;
977 ERE32.setSymbolAndType(s: Index, t: Entry.Type);
978 write(Val: ERE32.r_info);
979
980 if (Rela)
981 write(Val: uint32_t(Entry.Addend));
982
983 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
984 if (uint32_t RType =
985 OWriter.TargetObjectWriter->getRType2(Type: Entry.Type)) {
986 write(Val: uint32_t(Entry.Offset));
987
988 ERE32.setSymbolAndType(s: 0, t: RType);
989 write(Val: ERE32.r_info);
990 write(Val: uint32_t(0));
991 }
992 if (uint32_t RType =
993 OWriter.TargetObjectWriter->getRType3(Type: Entry.Type)) {
994 write(Val: uint32_t(Entry.Offset));
995
996 ERE32.setSymbolAndType(s: 0, t: RType);
997 write(Val: ERE32.r_info);
998 write(Val: uint32_t(0));
999 }
1000 }
1001 }
1002 }
1003}
1004
1005void 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;
1010
1011 switch(Section.getType()) {
1012 default:
1013 // Nothing to do.
1014 break;
1015
1016 case ELF::SHT_DYNAMIC:
1017 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1018
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(Val: cast<MCSectionELF>(Val: InfoSection));
1025 break;
1026 }
1027
1028 case ELF::SHT_SYMTAB:
1029 sh_link = StringTableIndex;
1030 sh_info = LastLocalSymbolIndex;
1031 break;
1032
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;
1038
1039 case ELF::SHT_GROUP:
1040 sh_link = SymbolTableIndex;
1041 sh_info = GroupSymbolIndex;
1042 break;
1043 }
1044
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>(Val: &Sym->getSection());
1051 sh_link = SectionIndexMap.lookup(Val: Sec);
1052 }
1053 }
1054
1055 WriteSecHdrEntry(Name: StrTabBuilder.getOffset(S: Section.getName()),
1056 Type: Section.getType(), Flags: Section.getFlags(), Address: 0, Offset, Size,
1057 Link: sh_link, Info: sh_info, Alignment: Section.getAlign(),
1058 EntrySize: Section.getEntrySize());
1059}
1060
1061void ELFWriter::writeSectionHeader(
1062 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1063 const SectionOffsetsTy &SectionOffsets) {
1064 const unsigned NumSections = SectionTable.size();
1065
1066 // Null section first.
1067 uint64_t FirstSectionSize =
1068 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
1069 WriteSecHdrEntry(Name: 0, Type: 0, Flags: 0, Address: 0, Offset: 0, Size: FirstSectionSize, Link: 0, Info: 0, Alignment: std::nullopt, EntrySize: 0);
1070
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();
1078
1079 const std::pair<uint64_t, uint64_t> &Offsets =
1080 SectionOffsets.find(x: Section)->second;
1081 uint64_t Size;
1082 if (Type == ELF::SHT_NOBITS)
1083 Size = Layout.getSectionAddressSize(Sec: Section);
1084 else
1085 Size = Offsets.second - Offsets.first;
1086
1087 writeSection(SectionIndexMap, GroupSymbolIndex, Offset: Offsets.first, Size,
1088 Section: *Section);
1089 }
1090}
1091
1092uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
1093 uint64_t StartOffset = W.OS.tell();
1094
1095 MCContext &Ctx = Asm.getContext();
1096 MCSectionELF *StrtabSection =
1097 Ctx.getELFSection(Section: ".strtab", Type: ELF::SHT_STRTAB, Flags: 0);
1098 StringTableIndex = addToSectionTable(Sec: StrtabSection);
1099
1100 createMemtagRelocs(Asm);
1101
1102 RevGroupMapTy RevGroupMap;
1103 SectionIndexMapTy SectionIndexMap;
1104
1105 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1106
1107 // Write out the ELF header ...
1108 writeHeader(Asm);
1109
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(Sec: Section))
1117 continue;
1118 if (Mode == DwoOnly && !isDwoSection(Sec: Section))
1119 continue;
1120
1121 // Remember the offset into the file for this section.
1122 const uint64_t SecStart = align(Alignment: Section.getAlign());
1123
1124 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1125 writeSectionData(Asm, Sec&: Section, Layout);
1126
1127 uint64_t SecEnd = W.OS.tell();
1128 SectionOffsets[&Section] = std::make_pair(x: SecStart, y&: SecEnd);
1129
1130 MCSectionELF *RelSection = createRelocationSection(Ctx, Sec: Section);
1131
1132 if (SignatureSymbol) {
1133 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1134 if (!GroupIdx) {
1135 MCSectionELF *Group =
1136 Ctx.createELFGroupSection(Group: SignatureSymbol, IsComdat: Section.isComdat());
1137 GroupIdx = addToSectionTable(Sec: Group);
1138 Group->setAlignment(Align(4));
1139 Groups.push_back(x: Group);
1140 }
1141 std::vector<const MCSectionELF *> &Members =
1142 GroupMembers[SignatureSymbol];
1143 Members.push_back(x: &Section);
1144 if (RelSection)
1145 Members.push_back(x: RelSection);
1146 }
1147
1148 SectionIndexMap[&Section] = addToSectionTable(Sec: &Section);
1149 if (RelSection) {
1150 SectionIndexMap[RelSection] = addToSectionTable(Sec: RelSection);
1151 Relocations.push_back(x: RelSection);
1152 }
1153
1154 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Sec&: Section);
1155 }
1156
1157 for (MCSectionELF *Group : Groups) {
1158 // Remember the offset into the file for this section.
1159 const uint64_t SecStart = align(Alignment: Group->getAlign());
1160
1161 const MCSymbol *SignatureSymbol = Group->getGroup();
1162 assert(SignatureSymbol);
1163 write(Val: uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1164 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1165 uint32_t SecIndex = SectionIndexMap.lookup(Val: Member);
1166 write(Val: SecIndex);
1167 }
1168
1169 uint64_t SecEnd = W.OS.tell();
1170 SectionOffsets[Group] = std::make_pair(x: SecStart, y&: SecEnd);
1171 }
1172
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(Section: ".llvm_addrsig", Type: ELF::SHT_LLVM_ADDRSIG,
1181 Flags: ELF::SHF_EXCLUDE);
1182 addToSectionTable(Sec: AddrsigSection);
1183 }
1184
1185 // Compute symbol table information.
1186 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1187 SectionOffsets);
1188
1189 for (MCSectionELF *RelSection : Relocations) {
1190 // Remember the offset into the file for this section.
1191 const uint64_t SecStart = align(Alignment: RelSection->getAlign());
1192
1193 writeRelocations(Asm,
1194 Sec: cast<MCSectionELF>(Val: *RelSection->getLinkedToSection()));
1195
1196 uint64_t SecEnd = W.OS.tell();
1197 SectionOffsets[RelSection] = std::make_pair(x: SecStart, y&: SecEnd);
1198 }
1199
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(x&: SecStart, y&: SecEnd);
1205 }
1206 }
1207
1208 {
1209 uint64_t SecStart = W.OS.tell();
1210 StrTabBuilder.write(OS&: W.OS);
1211 SectionOffsets[StrtabSection] = std::make_pair(x&: SecStart, y: W.OS.tell());
1212 }
1213
1214 const uint64_t SectionHeaderOffset = align(Alignment: is64Bit() ? Align(8) : Align(4));
1215
1216 // ... then the section header table ...
1217 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1218
1219 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1220 value: (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1221 : SectionTable.size() + 1,
1222 endian: W.Endian);
1223 unsigned NumSectionsOffset;
1224
1225 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1226 if (is64Bit()) {
1227 uint64_t Val =
1228 support::endian::byte_swap<uint64_t>(value: SectionHeaderOffset, endian: W.Endian);
1229 Stream.pwrite(Ptr: reinterpret_cast<char *>(&Val), Size: 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>(value: SectionHeaderOffset, endian: W.Endian);
1235 Stream.pwrite(Ptr: reinterpret_cast<char *>(&Val), Size: sizeof(Val),
1236 offsetof(ELF::Elf32_Ehdr, e_shoff));
1237 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1238 }
1239 Stream.pwrite(Ptr: reinterpret_cast<char *>(&NumSections), Size: sizeof(NumSections),
1240 Offset: NumSectionsOffset);
1241
1242 return W.OS.tell() - StartOffset;
1243}
1244
1245bool ELFObjectWriter::hasRelocationAddend() const {
1246 return TargetObjectWriter->hasRelocationAddend();
1247}
1248
1249void 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>(Val: *S.Sym);
1256 size_t Pos = AliasName.find(C: '@');
1257 assert(Pos != StringRef::npos);
1258
1259 StringRef Prefix = AliasName.substr(Start: 0, N: Pos);
1260 StringRef Rest = AliasName.substr(Start: Pos);
1261 StringRef Tail = Rest;
1262 if (Rest.starts_with(Prefix: "@@@"))
1263 Tail = Rest.substr(Start: Symbol.isUndefined() ? 2 : 1);
1264
1265 auto *Alias =
1266 cast<MCSymbolELF>(Val: Asm.getContext().getOrCreateSymbol(Name: Prefix + Tail));
1267 Asm.registerSymbol(Symbol: *Alias);
1268 const MCExpr *Value = MCSymbolRefExpr::create(Symbol: &Symbol, Ctx&: Asm.getContext());
1269 Alias->setVariableValue(Value);
1270
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());
1276
1277 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1278 continue;
1279
1280 if (Symbol.isUndefined() && Rest.starts_with(Prefix: "@@") &&
1281 !Rest.starts_with(Prefix: "@@@")) {
1282 Asm.getContext().reportError(L: S.Loc, Msg: "default version symbol " +
1283 AliasName + " must be defined");
1284 continue;
1285 }
1286
1287 if (Renames.count(Val: &Symbol) && Renames[&Symbol] != Alias) {
1288 Asm.getContext().reportError(L: S.Loc, Msg: Twine("multiple versions for ") +
1289 Symbol.getName());
1290 continue;
1291 }
1292
1293 Renames.insert(KV: std::make_pair(x: &Symbol, y&: Alias));
1294 }
1295
1296 for (const MCSymbol *&Sym : AddrsigSyms) {
1297 if (const MCSymbol *R = Renames.lookup(Val: cast<MCSymbolELF>(Val: Sym)))
1298 Sym = R;
1299 if (Sym->isInSection() && Sym->getName().starts_with(Prefix: ".L"))
1300 Sym = Sym->getSection().getBeginSymbol();
1301 Sym->setUsedInReloc();
1302 }
1303}
1304
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.
1308bool 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;
1318
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;
1331
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;
1344 }
1345
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;
1351
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;
1360
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;
1377 }
1378
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;
1384
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>(Val&: Sym->getSection());
1394 unsigned Flags = Sec.getFlags();
1395 if (Flags & ELF::SHF_MERGE) {
1396 if (C != 0)
1397 return true;
1398
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;
1404
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;
1415 }
1416
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;
1423 }
1424
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(Func: Sym))
1430 return true;
1431
1432 if (TargetObjectWriter->needsRelocateWithSymbol(Val, Sym: *Sym, Type))
1433 return true;
1434 return false;
1435}
1436
1437void 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(Kind: Fixup.getKind()).Flags &
1444 MCFixupKindInfo::FKF_IsPCRel;
1445 const MCSectionELF &FixupSection = cast<MCSectionELF>(Val&: *Fragment->getParent());
1446 uint64_t C = Target.getConstant();
1447 uint64_t FixupOffset = Layout.getFragmentOffset(F: Fragment) + Fixup.getOffset();
1448 MCContext &Ctx = Asm.getContext();
1449
1450 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1451 const auto &SymB = cast<MCSymbolELF>(Val: RefB->getSymbol());
1452 if (SymB.isUndefined()) {
1453 Ctx.reportError(L: Fixup.getLoc(),
1454 Msg: Twine("symbol '") + SymB.getName() +
1455 "' can not be undefined in a subtraction expression");
1456 return;
1457 }
1458
1459 assert(!SymB.isAbsolute() && "Should have been folded");
1460 const MCSection &SecB = SymB.getSection();
1461 if (&SecB != &FixupSection) {
1462 Ctx.reportError(L: Fixup.getLoc(),
1463 Msg: "Cannot represent a difference across sections");
1464 return;
1465 }
1466
1467 assert(!IsPCRel && "should have been folded");
1468 IsPCRel = true;
1469 C += FixupOffset - Layout.getSymbolOffset(S: SymB);
1470 }
1471
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>(Val: &RefA->getSymbol()) : nullptr;
1475
1476 bool ViaWeakRef = false;
1477 if (SymA && SymA->isVariable()) {
1478 const MCExpr *Expr = SymA->getVariableValue();
1479 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Val: Expr)) {
1480 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1481 SymA = cast<MCSymbolELF>(Val: &Inner->getSymbol());
1482 ViaWeakRef = true;
1483 }
1484 }
1485 }
1486
1487 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1488 ? cast<MCSectionELF>(Val: &SymA->getSection())
1489 : nullptr;
1490 if (!checkRelocation(Ctx, Loc: Fixup.getLoc(), From: &FixupSection, To: SecA))
1491 return;
1492
1493 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1494 const auto *Parent = cast<MCSectionELF>(Val: Fragment->getParent());
1495 // Emiting relocation with sybmol for CG Profile to help with --cg-profile.
1496 bool RelocateWithSymbol =
1497 shouldRelocateWithSymbol(Asm, Val: Target, Sym: SymA, C, Type) ||
1498 (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
1499 uint64_t Addend = 0;
1500
1501 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1502 ? C + Layout.getSymbolOffset(S: *SymA)
1503 : C;
1504 if (hasRelocationAddend()) {
1505 Addend = FixedValue;
1506 FixedValue = 0;
1507 }
1508
1509 if (!RelocateWithSymbol) {
1510 const auto *SectionSymbol =
1511 SecA ? cast<MCSymbolELF>(Val: SecA->getBeginSymbol()) : nullptr;
1512 if (SectionSymbol)
1513 SectionSymbol->setUsedInReloc();
1514 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
1515 Relocations[&FixupSection].push_back(x: Rec);
1516 return;
1517 }
1518
1519 const MCSymbolELF *RenamedSymA = SymA;
1520 if (SymA) {
1521 if (const MCSymbolELF *R = Renames.lookup(Val: SymA))
1522 RenamedSymA = R;
1523
1524 if (ViaWeakRef)
1525 RenamedSymA->setIsWeakrefUsedInReloc();
1526 else
1527 RenamedSymA->setUsedInReloc();
1528 }
1529 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1530 Relocations[&FixupSection].push_back(x: Rec);
1531}
1532
1533bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1534 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1535 bool InSet, bool IsPCRel) const {
1536 const auto &SymA = cast<MCSymbolELF>(Val: SA);
1537 if (IsPCRel) {
1538 assert(!InSet);
1539 if (SymA.getBinding() != ELF::STB_LOCAL ||
1540 SymA.getType() == ELF::STT_GNU_IFUNC)
1541 return false;
1542 }
1543 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
1544 InSet, IsPCRel);
1545}
1546
1547std::unique_ptr<MCObjectWriter>
1548llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1549 raw_pwrite_stream &OS, bool IsLittleEndian) {
1550 return std::make_unique<ELFSingleObjectWriter>(args: std::move(MOTW), args&: OS,
1551 args&: IsLittleEndian);
1552}
1553
1554std::unique_ptr<MCObjectWriter>
1555llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1556 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
1557 bool IsLittleEndian) {
1558 return std::make_unique<ELFDwoObjectWriter>(args: std::move(MOTW), args&: OS, args&: DwoOS,
1559 args&: IsLittleEndian);
1560}
1561

source code of llvm/lib/MC/ELFObjectWriter.cpp