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