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