xref: /llvm-project/llvm/lib/MC/ELFObjectWriter.cpp (revision 1baa6f75f34068a0b3fc772457deeed2d44287f8)
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/ADT/iterator.h"
22 #include "llvm/BinaryFormat/ELF.h"
23 #include "llvm/MC/MCAsmBackend.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCAssembler.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCELFExtras.h"
28 #include "llvm/MC/MCELFObjectWriter.h"
29 #include "llvm/MC/MCExpr.h"
30 #include "llvm/MC/MCFixup.h"
31 #include "llvm/MC/MCFixupKindInfo.h"
32 #include "llvm/MC/MCFragment.h"
33 #include "llvm/MC/MCObjectWriter.h"
34 #include "llvm/MC/MCSection.h"
35 #include "llvm/MC/MCSectionELF.h"
36 #include "llvm/MC/MCSymbol.h"
37 #include "llvm/MC/MCSymbolELF.h"
38 #include "llvm/MC/MCTargetOptions.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/StringTableBuilder.h"
41 #include "llvm/Support/Alignment.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Compression.h"
45 #include "llvm/Support/Endian.h"
46 #include "llvm/Support/EndianStream.h"
47 #include "llvm/Support/Error.h"
48 #include "llvm/Support/ErrorHandling.h"
49 #include "llvm/Support/LEB128.h"
50 #include "llvm/Support/MathExtras.h"
51 #include "llvm/Support/SMLoc.h"
52 #include "llvm/Support/raw_ostream.h"
53 #include "llvm/TargetParser/Host.h"
54 #include <algorithm>
55 #include <cassert>
56 #include <cstddef>
57 #include <cstdint>
58 #include <map>
59 #include <memory>
60 #include <string>
61 #include <utility>
62 #include <vector>
63 
64 using namespace llvm;
65 
66 #define DEBUG_TYPE "elf-object-writer"
67 
68 namespace {
69 namespace stats {
70 
71 STATISTIC(AllocTextBytes, "Total size of SHF_ALLOC text sections");
72 STATISTIC(AllocROBytes, "Total size of SHF_ALLOC readonly sections");
73 STATISTIC(AllocRWBytes, "Total size of SHF_ALLOC read-write sections");
74 STATISTIC(StrtabBytes, "Total size of SHT_STRTAB sections");
75 STATISTIC(SymtabBytes, "Total size of SHT_SYMTAB sections");
76 STATISTIC(RelocationBytes, "Total size of relocation sections");
77 STATISTIC(DynsymBytes, "Total size of SHT_DYNSYM sections");
78 STATISTIC(DebugBytes, "Total size of debug info sections");
79 STATISTIC(UnwindBytes, "Total size of unwind sections");
80 STATISTIC(OtherBytes, "Total size of uncategorized sections");
81 
82 } // namespace stats
83 
84 struct ELFWriter;
85 
86 bool isDwoSection(const MCSectionELF &Sec) {
87   return Sec.getName().ends_with(".dwo");
88 }
89 
90 class SymbolTableWriter {
91   ELFWriter &EWriter;
92   bool Is64Bit;
93 
94   // indexes we are going to write to .symtab_shndx.
95   std::vector<uint32_t> ShndxIndexes;
96 
97   // The numbel of symbols written so far.
98   unsigned NumWritten;
99 
100   void createSymtabShndx();
101 
102   template <typename T> void write(T Value);
103 
104 public:
105   SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
106 
107   void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
108                    uint8_t other, uint32_t shndx, bool Reserved);
109 
110   ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
111 };
112 
113 struct ELFWriter {
114   ELFObjectWriter &OWriter;
115   support::endian::Writer W;
116 
117   enum DwoMode {
118     AllSections,
119     NonDwoOnly,
120     DwoOnly,
121   } Mode;
122 
123   static uint64_t symbolValue(const MCAssembler &Asm, const MCSymbol &Sym);
124   static bool isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol,
125                          bool Used, bool Renamed);
126 
127   /// Helper struct for containing some precomputed information on symbols.
128   struct ELFSymbolData {
129     const MCSymbolELF *Symbol;
130     StringRef Name;
131     uint32_t SectionIndex;
132     uint32_t Order;
133   };
134 
135   /// @}
136   /// @name Symbol Table Data
137   /// @{
138 
139   StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
140 
141   /// @}
142 
143   // This holds the symbol table index of the last local symbol.
144   unsigned LastLocalSymbolIndex = ~0u;
145   // This holds the .strtab section index.
146   unsigned StringTableIndex = ~0u;
147   // This holds the .symtab section index.
148   unsigned SymbolTableIndex = ~0u;
149 
150   // Sections in the order they are to be output in the section table.
151   std::vector<MCSectionELF *> SectionTable;
152   unsigned addToSectionTable(MCSectionELF *Sec);
153 
154   // TargetObjectWriter wrappers.
155   bool is64Bit() const;
156 
157   uint64_t align(Align Alignment);
158 
159   bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
160                              SmallVectorImpl<uint8_t> &CompressedContents,
161                              Align Alignment);
162 
163 public:
164   ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
165             bool IsLittleEndian, DwoMode Mode)
166       : OWriter(OWriter), W(OS, IsLittleEndian ? llvm::endianness::little
167                                                : llvm::endianness::big),
168         Mode(Mode) {}
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(const MCAssembler &Asm);
182 
183   void writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer,
184                    uint32_t StringIndex, 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(MCAssembler &Asm, const RevGroupMapTy &RevGroupMap);
194 
195   void writeAddrsigSection();
196 
197   MCSectionELF *createRelocationSection(MCContext &Ctx,
198                                         const MCSectionELF &Sec);
199 
200   void writeSectionHeader(const MCAssembler &Asm);
201 
202   void writeSectionData(const MCAssembler &Asm, MCSection &Sec);
203 
204   void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
205                         uint64_t Address, uint64_t Offset, uint64_t Size,
206                         uint32_t Link, uint32_t Info, MaybeAlign Alignment,
207                         uint64_t EntrySize);
208 
209   void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
210 
211   uint64_t writeObject(MCAssembler &Asm);
212   void writeSection(uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
213                     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(const MCAssembler &Asm) {
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 MCAssembler &Asm, 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->getKind() != MCSymbolRefExpr::VK_None ||
401         mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC)
402       return false;
403     Symbol = &cast<MCSymbolELF>(Value->getSymbol());
404   }
405   return true;
406 }
407 
408 void ELFWriter::writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer,
409                             uint32_t StringIndex, ELFSymbolData &MSD) {
410   const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
411   const MCSymbolELF *Base =
412       cast_or_null<MCSymbolELF>(Asm.getBaseSymbol(Symbol));
413 
414   // This has to be in sync with when computeSymbolTable uses SHN_ABS or
415   // SHN_COMMON.
416   bool IsReserved = !Base || Symbol.isCommon();
417 
418   // Binding and Type share the same byte as upper and lower nibbles
419   uint8_t Binding = Symbol.getBinding();
420   uint8_t Type = Symbol.getType();
421   if (isIFunc(&Symbol))
422     Type = ELF::STT_GNU_IFUNC;
423   if (Base) {
424     Type = mergeTypeForSet(Type, Base->getType());
425   }
426   uint8_t Info = (Binding << 4) | Type;
427 
428   // Other and Visibility share the same byte with Visibility using the lower
429   // 2 bits
430   uint8_t Visibility = Symbol.getVisibility();
431   uint8_t Other = Symbol.getOther() | Visibility;
432 
433   uint64_t Value = symbolValue(Asm, *MSD.Symbol);
434   uint64_t Size = 0;
435 
436   const MCExpr *ESize = MSD.Symbol->getSize();
437   if (!ESize && Base) {
438     // For expressions like .set y, x+1, if y's size is unset, inherit from x.
439     ESize = Base->getSize();
440 
441     // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
442     // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
443     // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
444     // needs. MCBinaryExpr is not handled.
445     const MCSymbolELF *Sym = &Symbol;
446     while (Sym->isVariable()) {
447       if (auto *Expr =
448               dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
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 MCAssembler &Asm, const MCSymbolELF &Symbol,
471                            bool Used, bool Renamed) {
472   if (Symbol.isVariable()) {
473     const MCExpr *Expr = Symbol.getVariableValue();
474     // Target Expressions that are always inlined do not appear in the symtab
475     if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
476       if (T->inlineAssignedExpr())
477         return false;
478     if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
479       if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
480         return false;
481     }
482   }
483 
484   if (Used)
485     return true;
486 
487   if (Renamed)
488     return false;
489 
490   if (Symbol.isVariable() && Symbol.isUndefined()) {
491     // FIXME: this is here just to diagnose the case of a var = commmon_sym.
492     Asm.getBaseSymbol(Symbol);
493     return false;
494   }
495 
496   if (Symbol.isTemporary())
497     return false;
498 
499   if (Symbol.getType() == ELF::STT_SECTION)
500     return false;
501 
502   return true;
503 }
504 
505 void ELFWriter::computeSymbolTable(MCAssembler &Asm,
506                                    const RevGroupMapTy &RevGroupMap) {
507   MCContext &Ctx = Asm.getContext();
508   SymbolTableWriter Writer(*this, is64Bit());
509 
510   // Symbol table
511   unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
512   MCSectionELF *SymtabSection =
513       Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
514   SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
515   SymbolTableIndex = addToSectionTable(SymtabSection);
516 
517   uint64_t SecStart = align(SymtabSection->getAlign());
518 
519   // The first entry is the undefined symbol entry.
520   Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
521 
522   std::vector<ELFSymbolData> LocalSymbolData;
523   std::vector<ELFSymbolData> ExternalSymbolData;
524   MutableArrayRef<std::pair<std::string, size_t>> FileNames =
525       OWriter.getFileNames();
526   for (const std::pair<std::string, size_t> &F : FileNames)
527     StrTabBuilder.add(F.first);
528 
529   // Add the data for the symbols.
530   bool HasLargeSectionIndex = false;
531   for (auto It : llvm::enumerate(Asm.symbols())) {
532     const auto &Symbol = cast<MCSymbolELF>(It.value());
533     bool Used = Symbol.isUsedInReloc();
534     bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
535     bool isSignature = Symbol.isSignature();
536 
537     if (!isInSymtab(Asm, Symbol, Used || WeakrefUsed || isSignature,
538                     OWriter.Renames.count(&Symbol)))
539       continue;
540 
541     if (Symbol.isTemporary() && Symbol.isUndefined()) {
542       Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
543       continue;
544     }
545 
546     ELFSymbolData MSD;
547     MSD.Symbol = cast<MCSymbolELF>(&Symbol);
548     MSD.Order = It.index();
549 
550     bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
551     assert(Local || !Symbol.isTemporary());
552 
553     if (Symbol.isAbsolute()) {
554       MSD.SectionIndex = ELF::SHN_ABS;
555     } else if (Symbol.isCommon()) {
556       if (Symbol.isTargetCommon()) {
557         MSD.SectionIndex = Symbol.getIndex();
558       } else {
559         assert(!Local);
560         MSD.SectionIndex = ELF::SHN_COMMON;
561       }
562     } else if (Symbol.isUndefined()) {
563       if (isSignature && !Used) {
564         MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
565         if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
566           HasLargeSectionIndex = true;
567       } else {
568         MSD.SectionIndex = ELF::SHN_UNDEF;
569       }
570     } else {
571       const MCSectionELF &Section =
572           static_cast<const MCSectionELF &>(Symbol.getSection());
573 
574       // We may end up with a situation when section symbol is technically
575       // defined, but should not be. That happens because we explicitly
576       // pre-create few .debug_* sections to have accessors.
577       // And if these sections were not really defined in the code, but were
578       // referenced, we simply error out.
579       if (!Section.isRegistered()) {
580         assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
581                ELF::STT_SECTION);
582         Ctx.reportError(SMLoc(),
583                         "Undefined section reference: " + Symbol.getName());
584         continue;
585       }
586 
587       if (Mode == NonDwoOnly && isDwoSection(Section))
588         continue;
589       MSD.SectionIndex = Section.getOrdinal();
590       assert(MSD.SectionIndex && "Invalid section index!");
591       if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
592         HasLargeSectionIndex = true;
593     }
594 
595     // Temporary symbols generated for certain assembler features (.eh_frame,
596     // .debug_line) of an empty name may be referenced by relocations due to
597     // linker relaxation. Rename them to ".L0 " to match the gas fake label name
598     // and allow ld/objcopy --discard-locals to discard such symbols.
599     StringRef Name = Symbol.getName();
600     if (Name.empty())
601       Name = ".L0 ";
602 
603     // Sections have their own string table
604     if (Symbol.getType() != ELF::STT_SECTION) {
605       MSD.Name = Name;
606       StrTabBuilder.add(Name);
607     }
608 
609     if (Local)
610       LocalSymbolData.push_back(MSD);
611     else
612       ExternalSymbolData.push_back(MSD);
613   }
614 
615   // This holds the .symtab_shndx section index.
616   unsigned SymtabShndxSectionIndex = 0;
617 
618   if (HasLargeSectionIndex) {
619     MCSectionELF *SymtabShndxSection =
620         Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
621     SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
622     SymtabShndxSection->setAlignment(Align(4));
623   }
624 
625   StrTabBuilder.finalize();
626 
627   // Make the first STT_FILE precede previous local symbols.
628   unsigned Index = 1;
629   auto FileNameIt = FileNames.begin();
630   if (!FileNames.empty())
631     FileNames[0].second = 0;
632 
633   for (ELFSymbolData &MSD : LocalSymbolData) {
634     // Emit STT_FILE symbols before their associated local symbols.
635     for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
636          ++FileNameIt) {
637       Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
638                          ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
639                          ELF::SHN_ABS, true);
640       ++Index;
641     }
642 
643     unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
644                                ? 0
645                                : StrTabBuilder.getOffset(MSD.Name);
646     MSD.Symbol->setIndex(Index++);
647     writeSymbol(Asm, Writer, StringIndex, MSD);
648   }
649   for (; FileNameIt != FileNames.end(); ++FileNameIt) {
650     Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
651                        ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
652                        ELF::SHN_ABS, true);
653     ++Index;
654   }
655 
656   // Write the symbol table entries.
657   LastLocalSymbolIndex = Index;
658 
659   for (ELFSymbolData &MSD : ExternalSymbolData) {
660     unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
661     MSD.Symbol->setIndex(Index++);
662     writeSymbol(Asm, Writer, StringIndex, MSD);
663     assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
664   }
665 
666   uint64_t SecEnd = W.OS.tell();
667   SymtabSection->setOffsets(SecStart, SecEnd);
668 
669   ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
670   if (ShndxIndexes.empty()) {
671     assert(SymtabShndxSectionIndex == 0);
672     return;
673   }
674   assert(SymtabShndxSectionIndex != 0);
675 
676   SecStart = W.OS.tell();
677   MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1];
678   for (uint32_t Index : ShndxIndexes)
679     write(Index);
680   SecEnd = W.OS.tell();
681   SymtabShndxSection->setOffsets(SecStart, SecEnd);
682 }
683 
684 void ELFWriter::writeAddrsigSection() {
685   for (const MCSymbol *Sym : OWriter.getAddrsigSyms())
686     if (Sym->getIndex() != 0)
687       encodeULEB128(Sym->getIndex(), W.OS);
688 }
689 
690 MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
691                                                  const MCSectionELF &Sec) {
692   if (OWriter.Relocations[&Sec].empty())
693     return nullptr;
694 
695   unsigned Flags = ELF::SHF_INFO_LINK;
696   if (Sec.getFlags() & ELF::SHF_GROUP)
697     Flags = ELF::SHF_GROUP;
698 
699   const StringRef SectionName = Sec.getName();
700   const MCTargetOptions *TO = Ctx.getTargetOptions();
701   if (TO && TO->Crel) {
702     MCSectionELF *RelaSection =
703         Ctx.createELFRelSection(".crel" + SectionName, ELF::SHT_CREL, Flags,
704                                 /*EntrySize=*/1, Sec.getGroup(), &Sec);
705     return RelaSection;
706   }
707 
708   const bool Rela = OWriter.usesRela(TO, Sec);
709   unsigned EntrySize;
710   if (Rela)
711     EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
712   else
713     EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
714 
715   MCSectionELF *RelaSection =
716       Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName),
717                               Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags,
718                               EntrySize, Sec.getGroup(), &Sec);
719   RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
720   return RelaSection;
721 }
722 
723 // Include the debug info compression header.
724 bool ELFWriter::maybeWriteCompression(
725     uint32_t ChType, uint64_t Size,
726     SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
727   uint64_t HdrSize =
728       is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
729   if (Size <= HdrSize + CompressedContents.size())
730     return false;
731   // Platform specific header is followed by compressed data.
732   if (is64Bit()) {
733     // Write Elf64_Chdr header.
734     write(static_cast<ELF::Elf64_Word>(ChType));
735     write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
736     write(static_cast<ELF::Elf64_Xword>(Size));
737     write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
738   } else {
739     // Write Elf32_Chdr header otherwise.
740     write(static_cast<ELF::Elf32_Word>(ChType));
741     write(static_cast<ELF::Elf32_Word>(Size));
742     write(static_cast<ELF::Elf32_Word>(Alignment.value()));
743   }
744   return true;
745 }
746 
747 void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec) {
748   MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
749   StringRef SectionName = Section.getName();
750   auto &Ctx = Asm.getContext();
751   const DebugCompressionType CompressionType =
752       Ctx.getTargetOptions() ? Ctx.getTargetOptions()->CompressDebugSections
753                              : DebugCompressionType::None;
754   if (CompressionType == DebugCompressionType::None ||
755       !SectionName.starts_with(".debug_")) {
756     Asm.writeSectionData(W.OS, &Section);
757     return;
758   }
759 
760   SmallVector<char, 128> UncompressedData;
761   raw_svector_ostream VecOS(UncompressedData);
762   Asm.writeSectionData(VecOS, &Section);
763   ArrayRef<uint8_t> Uncompressed =
764       ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
765                UncompressedData.size());
766 
767   SmallVector<uint8_t, 128> Compressed;
768   uint32_t ChType;
769   switch (CompressionType) {
770   case DebugCompressionType::None:
771     llvm_unreachable("has been handled");
772   case DebugCompressionType::Zlib:
773     ChType = ELF::ELFCOMPRESS_ZLIB;
774     break;
775   case DebugCompressionType::Zstd:
776     ChType = ELF::ELFCOMPRESS_ZSTD;
777     break;
778   }
779   compression::compress(compression::Params(CompressionType), Uncompressed,
780                         Compressed);
781   if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
782                              Sec.getAlign())) {
783     W.OS << UncompressedData;
784     return;
785   }
786 
787   Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
788   // Alignment field should reflect the requirements of
789   // the compressed section header.
790   Section.setAlignment(is64Bit() ? Align(8) : Align(4));
791   W.OS << toStringRef(Compressed);
792 }
793 
794 void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
795                                  uint64_t Address, uint64_t Offset,
796                                  uint64_t Size, uint32_t Link, uint32_t Info,
797                                  MaybeAlign Alignment, uint64_t EntrySize) {
798   W.write<uint32_t>(Name);        // sh_name: index into string table
799   W.write<uint32_t>(Type);        // sh_type
800   WriteWord(Flags);     // sh_flags
801   WriteWord(Address);   // sh_addr
802   WriteWord(Offset);    // sh_offset
803   WriteWord(Size);      // sh_size
804   W.write<uint32_t>(Link);        // sh_link
805   W.write<uint32_t>(Info);        // sh_info
806   WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
807   WriteWord(EntrySize); // sh_entsize
808 }
809 
810 template <bool Is64>
811 static void encodeCrel(ArrayRef<ELFRelocationEntry> Relocs, raw_ostream &OS) {
812   using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
813   ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) {
814     uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0;
815     return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type,
816                                std::make_signed_t<uint>(R.Addend)};
817   });
818 }
819 
820 void ELFWriter::writeRelocations(const MCAssembler &Asm,
821                                        const MCSectionELF &Sec) {
822   std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
823   const MCTargetOptions *TO = Asm.getContext().getTargetOptions();
824   const bool Rela = OWriter.usesRela(TO, Sec);
825 
826   // Sort the relocation entries. MIPS needs this.
827   OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
828 
829   if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
830     for (const ELFRelocationEntry &Entry : Relocs) {
831       uint32_t SymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
832       if (is64Bit()) {
833         write(Entry.Offset);
834         write(uint32_t(SymIdx));
835         write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
836         write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
837         write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
838         write(OWriter.TargetObjectWriter->getRType(Entry.Type));
839         if (Rela)
840           write(Entry.Addend);
841       } else {
842         write(uint32_t(Entry.Offset));
843         ELF::Elf32_Rela ERE32;
844         ERE32.setSymbolAndType(SymIdx, Entry.Type);
845         write(ERE32.r_info);
846         if (Rela)
847           write(uint32_t(Entry.Addend));
848         if (uint32_t RType =
849                 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
850           write(uint32_t(Entry.Offset));
851           ERE32.setSymbolAndType(0, RType);
852           write(ERE32.r_info);
853           write(uint32_t(0));
854         }
855         if (uint32_t RType =
856                 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
857           write(uint32_t(Entry.Offset));
858           ERE32.setSymbolAndType(0, RType);
859           write(ERE32.r_info);
860           write(uint32_t(0));
861         }
862       }
863     }
864   } else if (TO && TO->Crel) {
865     if (is64Bit())
866       encodeCrel<true>(Relocs, W.OS);
867     else
868       encodeCrel<false>(Relocs, W.OS);
869   } else {
870     for (const ELFRelocationEntry &Entry : Relocs) {
871       uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
872       if (is64Bit()) {
873         write(Entry.Offset);
874         ELF::Elf64_Rela ERE;
875         ERE.setSymbolAndType(Symidx, Entry.Type);
876         write(ERE.r_info);
877         if (Rela)
878           write(Entry.Addend);
879       } else {
880         write(uint32_t(Entry.Offset));
881         ELF::Elf32_Rela ERE;
882         ERE.setSymbolAndType(Symidx, Entry.Type);
883         write(ERE.r_info);
884         if (Rela)
885           write(uint32_t(Entry.Addend));
886       }
887     }
888   }
889 }
890 
891 void ELFWriter::writeSection(uint32_t GroupSymbolIndex, uint64_t Offset,
892                              uint64_t Size, const MCSectionELF &Section) {
893   uint64_t sh_link = 0;
894   uint64_t sh_info = 0;
895 
896   switch(Section.getType()) {
897   default:
898     // Nothing to do.
899     break;
900 
901   case ELF::SHT_DYNAMIC:
902     llvm_unreachable("SHT_DYNAMIC in a relocatable object");
903 
904   case ELF::SHT_REL:
905   case ELF::SHT_RELA:
906   case ELF::SHT_CREL: {
907     sh_link = SymbolTableIndex;
908     assert(sh_link && ".symtab not found");
909     const MCSection *InfoSection = Section.getLinkedToSection();
910     sh_info = InfoSection->getOrdinal();
911     break;
912   }
913 
914   case ELF::SHT_SYMTAB:
915     sh_link = StringTableIndex;
916     sh_info = LastLocalSymbolIndex;
917     break;
918 
919   case ELF::SHT_SYMTAB_SHNDX:
920   case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
921   case ELF::SHT_LLVM_ADDRSIG:
922     sh_link = SymbolTableIndex;
923     break;
924 
925   case ELF::SHT_GROUP:
926     sh_link = SymbolTableIndex;
927     sh_info = GroupSymbolIndex;
928     break;
929   }
930 
931   if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
932     // If the value in the associated metadata is not a definition, Sym will be
933     // undefined. Represent this with sh_link=0.
934     const MCSymbol *Sym = Section.getLinkedToSymbol();
935     if (Sym && Sym->isInSection())
936       sh_link = Sym->getSection().getOrdinal();
937   }
938 
939   WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
940                    Section.getType(), Section.getFlags(), 0, Offset, Size,
941                    sh_link, sh_info, Section.getAlign(),
942                    Section.getEntrySize());
943 }
944 
945 void ELFWriter::writeSectionHeader(const MCAssembler &Asm) {
946   const unsigned NumSections = SectionTable.size();
947 
948   // Null section first.
949   uint64_t FirstSectionSize =
950       (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
951   WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
952 
953   for (const MCSectionELF *Section : SectionTable) {
954     uint32_t GroupSymbolIndex;
955     unsigned Type = Section->getType();
956     if (Type != ELF::SHT_GROUP)
957       GroupSymbolIndex = 0;
958     else
959       GroupSymbolIndex = Section->getGroup()->getIndex();
960 
961     std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets();
962     uint64_t Size;
963     if (Type == ELF::SHT_NOBITS)
964       Size = Asm.getSectionAddressSize(*Section);
965     else
966       Size = Offsets.second - Offsets.first;
967 
968     auto SectionHasFlag = [&](uint64_t Flag) -> bool {
969       return Section->getFlags() & Flag;
970     };
971 
972     if (Section->getName().starts_with(".debug")) {
973       stats::DebugBytes += Size;
974     } else if (Section->getName().starts_with(".eh_frame")) {
975       stats::UnwindBytes += Size;
976     } else if (SectionHasFlag(ELF::SHF_ALLOC)) {
977       if (SectionHasFlag(ELF::SHF_EXECINSTR)) {
978         stats::AllocTextBytes += Size;
979       } else if (SectionHasFlag(ELF::SHF_WRITE)) {
980         stats::AllocRWBytes += Size;
981       } else {
982         stats::AllocROBytes += Size;
983       }
984     } else {
985       switch (Section->getType()) {
986       case ELF::SHT_STRTAB:
987         stats::StrtabBytes += Size;
988         break;
989       case ELF::SHT_SYMTAB:
990         stats::SymtabBytes += Size;
991         break;
992       case ELF::SHT_DYNSYM:
993         stats::DynsymBytes += Size;
994         break;
995       case ELF::SHT_REL:
996       case ELF::SHT_RELA:
997       case ELF::SHT_CREL:
998         stats::RelocationBytes += Size;
999         break;
1000       default:
1001         stats::OtherBytes += Size;
1002         break;
1003       }
1004     }
1005 
1006     writeSection(GroupSymbolIndex, Offsets.first, Size, *Section);
1007   }
1008 }
1009 
1010 uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
1011   uint64_t StartOffset = W.OS.tell();
1012 
1013   MCContext &Ctx = Asm.getContext();
1014   MCSectionELF *StrtabSection =
1015       Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1016   StringTableIndex = addToSectionTable(StrtabSection);
1017 
1018   RevGroupMapTy RevGroupMap;
1019 
1020   // Write out the ELF header ...
1021   writeHeader(Asm);
1022 
1023   // ... then the sections ...
1024   SmallVector<std::pair<MCSectionELF *, SmallVector<unsigned>>, 0> Groups;
1025   // Map from group section index to group
1026   SmallVector<unsigned, 0> GroupMap;
1027   SmallVector<MCSectionELF *> Relocations;
1028   for (MCSection &Sec : Asm) {
1029     MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1030     if (Mode == NonDwoOnly && isDwoSection(Section))
1031       continue;
1032     if (Mode == DwoOnly && !isDwoSection(Section))
1033       continue;
1034 
1035     // Remember the offset into the file for this section.
1036     const uint64_t SecStart = align(Section.getAlign());
1037 
1038     const MCSymbolELF *SignatureSymbol = Section.getGroup();
1039     writeSectionData(Asm, Section);
1040 
1041     uint64_t SecEnd = W.OS.tell();
1042     Section.setOffsets(SecStart, SecEnd);
1043 
1044     MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1045 
1046     unsigned *GroupIdxEntry = nullptr;
1047     if (SignatureSymbol) {
1048       GroupIdxEntry = &RevGroupMap[SignatureSymbol];
1049       if (!*GroupIdxEntry) {
1050         MCSectionELF *Group =
1051             Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1052         *GroupIdxEntry = addToSectionTable(Group);
1053         Group->setAlignment(Align(4));
1054 
1055         GroupMap.resize(*GroupIdxEntry + 1);
1056         GroupMap[*GroupIdxEntry] = Groups.size();
1057         Groups.emplace_back(Group, SmallVector<unsigned>{});
1058       }
1059     }
1060 
1061     Section.setOrdinal(addToSectionTable(&Section));
1062     if (RelSection) {
1063       RelSection->setOrdinal(addToSectionTable(RelSection));
1064       Relocations.push_back(RelSection);
1065     }
1066 
1067     if (GroupIdxEntry) {
1068       auto &Members = Groups[GroupMap[*GroupIdxEntry]];
1069       Members.second.push_back(Section.getOrdinal());
1070       if (RelSection)
1071         Members.second.push_back(RelSection->getOrdinal());
1072     }
1073   }
1074 
1075   for (auto &[Group, Members] : Groups) {
1076     // Remember the offset into the file for this section.
1077     const uint64_t SecStart = align(Group->getAlign());
1078 
1079     write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1080     W.write<unsigned>(Members);
1081 
1082     uint64_t SecEnd = W.OS.tell();
1083     Group->setOffsets(SecStart, SecEnd);
1084   }
1085 
1086   if (Mode == DwoOnly) {
1087     // dwo files don't have symbol tables or relocations, but they do have
1088     // string tables.
1089     StrTabBuilder.finalize();
1090   } else {
1091     MCSectionELF *AddrsigSection;
1092     if (OWriter.getEmitAddrsigSection()) {
1093       AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1094                                          ELF::SHF_EXCLUDE);
1095       addToSectionTable(AddrsigSection);
1096     }
1097 
1098     // Compute symbol table information.
1099     computeSymbolTable(Asm, RevGroupMap);
1100 
1101     for (MCSectionELF *RelSection : Relocations) {
1102       // Remember the offset into the file for this section.
1103       const uint64_t SecStart = align(RelSection->getAlign());
1104 
1105       writeRelocations(Asm,
1106                        cast<MCSectionELF>(*RelSection->getLinkedToSection()));
1107 
1108       uint64_t SecEnd = W.OS.tell();
1109       RelSection->setOffsets(SecStart, SecEnd);
1110     }
1111 
1112     if (OWriter.getEmitAddrsigSection()) {
1113       uint64_t SecStart = W.OS.tell();
1114       writeAddrsigSection();
1115       uint64_t SecEnd = W.OS.tell();
1116       AddrsigSection->setOffsets(SecStart, SecEnd);
1117     }
1118   }
1119 
1120   {
1121     uint64_t SecStart = W.OS.tell();
1122     StrTabBuilder.write(W.OS);
1123     StrtabSection->setOffsets(SecStart, W.OS.tell());
1124   }
1125 
1126   const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1127 
1128   // ... then the section header table ...
1129   writeSectionHeader(Asm);
1130 
1131   uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1132       (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1133                                                       : SectionTable.size() + 1,
1134       W.Endian);
1135   unsigned NumSectionsOffset;
1136 
1137   auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1138   if (is64Bit()) {
1139     uint64_t Val =
1140         support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1141     Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1142                   offsetof(ELF::Elf64_Ehdr, e_shoff));
1143     NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1144   } else {
1145     uint32_t Val =
1146         support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1147     Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1148                   offsetof(ELF::Elf32_Ehdr, e_shoff));
1149     NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1150   }
1151   Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1152                 NumSectionsOffset);
1153 
1154   return W.OS.tell() - StartOffset;
1155 }
1156 
1157 ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1158                                  raw_pwrite_stream &OS, bool IsLittleEndian)
1159     : TargetObjectWriter(std::move(MOTW)), OS(OS),
1160       IsLittleEndian(IsLittleEndian) {}
1161 ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1162                                  raw_pwrite_stream &OS,
1163                                  raw_pwrite_stream &DwoOS, bool IsLittleEndian)
1164     : TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS),
1165       IsLittleEndian(IsLittleEndian) {}
1166 
1167 void ELFObjectWriter::reset() {
1168   ELFHeaderEFlags = 0;
1169   SeenGnuAbi = false;
1170   OverrideABIVersion.reset();
1171   Relocations.clear();
1172   Renames.clear();
1173   Symvers.clear();
1174   MCObjectWriter::reset();
1175 }
1176 
1177 bool ELFObjectWriter::hasRelocationAddend() const {
1178   return TargetObjectWriter->hasRelocationAddend();
1179 }
1180 
1181 void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) {
1182   // The presence of symbol versions causes undefined symbols and
1183   // versions declared with @@@ to be renamed.
1184   for (const Symver &S : Symvers) {
1185     StringRef AliasName = S.Name;
1186     const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
1187     size_t Pos = AliasName.find('@');
1188     assert(Pos != StringRef::npos);
1189 
1190     StringRef Prefix = AliasName.substr(0, Pos);
1191     StringRef Rest = AliasName.substr(Pos);
1192     StringRef Tail = Rest;
1193     if (Rest.starts_with("@@@"))
1194       Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1195 
1196     auto *Alias =
1197         cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1198     Asm.registerSymbol(*Alias);
1199     const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1200     Alias->setVariableValue(Value);
1201 
1202     // Aliases defined with .symvar copy the binding from the symbol they alias.
1203     // This is the first place we are able to copy this information.
1204     Alias->setBinding(Symbol.getBinding());
1205     Alias->setVisibility(Symbol.getVisibility());
1206     Alias->setOther(Symbol.getOther());
1207 
1208     if (!Symbol.isUndefined() && S.KeepOriginalSym)
1209       continue;
1210 
1211     if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1212         !Rest.starts_with("@@@")) {
1213       Asm.getContext().reportError(S.Loc, "default version symbol " +
1214                                               AliasName + " must be defined");
1215       continue;
1216     }
1217 
1218     if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1219       Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1220                                               Symbol.getName());
1221       continue;
1222     }
1223 
1224     Renames.insert(std::make_pair(&Symbol, Alias));
1225   }
1226 
1227   for (const MCSymbol *&Sym : AddrsigSyms) {
1228     if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1229       Sym = R;
1230     if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1231       Sym = Sym->getSection().getBeginSymbol();
1232     Sym->setUsedInReloc();
1233   }
1234 }
1235 
1236 // It is always valid to create a relocation with a symbol. It is preferable
1237 // to use a relocation with a section if that is possible. Using the section
1238 // allows us to omit some local symbols from the symbol table.
1239 bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1240                                                const MCValue &Val,
1241                                                const MCSymbolELF *Sym,
1242                                                uint64_t C,
1243                                                unsigned Type) const {
1244   const MCSymbolRefExpr *RefA = Val.getSymA();
1245   // A PCRel relocation to an absolute value has no symbol (or section). We
1246   // represent that with a relocation to a null section.
1247   if (!RefA)
1248     return false;
1249 
1250   MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
1251   switch (Kind) {
1252   default:
1253     break;
1254   // The .odp creation emits a relocation against the symbol ".TOC." which
1255   // create a R_PPC64_TOC relocation. However the relocation symbol name
1256   // in final object creation should be NULL, since the symbol does not
1257   // really exist, it is just the reference to TOC base for the current
1258   // object file. Since the symbol is undefined, returning false results
1259   // in a relocation with a null section which is the desired result.
1260   case MCSymbolRefExpr::VK_PPC_TOCBASE:
1261     return false;
1262 
1263   // These VariantKind cause the relocation to refer to something other than
1264   // the symbol itself, like a linker generated table. Since the address of
1265   // symbol is not relevant, we cannot replace the symbol with the
1266   // section and patch the difference in the addend.
1267   case MCSymbolRefExpr::VK_GOT:
1268   case MCSymbolRefExpr::VK_PLT:
1269   case MCSymbolRefExpr::VK_GOTPCREL:
1270   case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
1271   case MCSymbolRefExpr::VK_PPC_GOT_LO:
1272   case MCSymbolRefExpr::VK_PPC_GOT_HI:
1273   case MCSymbolRefExpr::VK_PPC_GOT_HA:
1274     return true;
1275   }
1276 
1277   // An undefined symbol is not in any section, so the relocation has to point
1278   // to the symbol itself.
1279   assert(Sym && "Expected a symbol");
1280   if (Sym->isUndefined())
1281     return true;
1282 
1283   // For memory-tagged symbols, ensure that the relocation uses the symbol. For
1284   // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
1285   // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
1286   // this global needs to be tagged. In addition, the linker needs to know
1287   // whether to emit a special addend when relocating `end` symbols, and this
1288   // can only be determined by the attributes of the symbol itself.
1289   if (Sym->isMemtag())
1290     return true;
1291 
1292   unsigned Binding = Sym->getBinding();
1293   switch(Binding) {
1294   default:
1295     llvm_unreachable("Invalid Binding");
1296   case ELF::STB_LOCAL:
1297     break;
1298   case ELF::STB_WEAK:
1299     // If the symbol is weak, it might be overridden by a symbol in another
1300     // file. The relocation has to point to the symbol so that the linker
1301     // can update it.
1302     return true;
1303   case ELF::STB_GLOBAL:
1304   case ELF::STB_GNU_UNIQUE:
1305     // Global ELF symbols can be preempted by the dynamic linker. The relocation
1306     // has to point to the symbol for a reason analogous to the STB_WEAK case.
1307     return true;
1308   }
1309 
1310   // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1311   // reloc that the dynamic loader will use to resolve the address at startup
1312   // time.
1313   if (Sym->getType() == ELF::STT_GNU_IFUNC)
1314     return true;
1315 
1316   // If a relocation points to a mergeable section, we have to be careful.
1317   // If the offset is zero, a relocation with the section will encode the
1318   // same information. With a non-zero offset, the situation is different.
1319   // For example, a relocation can point 42 bytes past the end of a string.
1320   // If we change such a relocation to use the section, the linker would think
1321   // that it pointed to another string and subtracting 42 at runtime will
1322   // produce the wrong value.
1323   if (Sym->isInSection()) {
1324     auto &Sec = cast<MCSectionELF>(Sym->getSection());
1325     unsigned Flags = Sec.getFlags();
1326     if (Flags & ELF::SHF_MERGE) {
1327       if (C != 0)
1328         return true;
1329 
1330       // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1331       // (http://sourceware.org/PR16794).
1332       if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1333           Type == ELF::R_386_GOTOFF)
1334         return true;
1335 
1336       // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1337       // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1338       // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1339       // range of a MergeInputSection. We could introduce a new RelExpr member
1340       // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1341       // but the complexity is unnecessary given that GNU as keeps the original
1342       // symbol for this case as well.
1343       if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1344           !hasRelocationAddend())
1345         return true;
1346     }
1347 
1348     // Most TLS relocations use a got, so they need the symbol. Even those that
1349     // are just an offset (@tpoff), require a symbol in gold versions before
1350     // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1351     // http://sourceware.org/PR16773.
1352     if (Flags & ELF::SHF_TLS)
1353       return true;
1354   }
1355 
1356   // If the symbol is a thumb function the final relocation must set the lowest
1357   // bit. With a symbol that is done by just having the symbol have that bit
1358   // set, so we would lose the bit if we relocated with the section.
1359   // FIXME: We could use the section but add the bit to the relocation value.
1360   if (Asm.isThumbFunc(Sym))
1361     return true;
1362 
1363   if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type))
1364     return true;
1365   return false;
1366 }
1367 
1368 bool ELFObjectWriter::checkRelocation(MCContext &Ctx, SMLoc Loc,
1369                                       const MCSectionELF *From,
1370                                       const MCSectionELF *To) {
1371   if (DwoOS) {
1372     if (isDwoSection(*From)) {
1373       Ctx.reportError(Loc, "A dwo section may not contain relocations");
1374       return false;
1375     }
1376     if (To && isDwoSection(*To)) {
1377       Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
1378       return false;
1379     }
1380   }
1381   return true;
1382 }
1383 
1384 void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1385                                        const MCFragment *Fragment,
1386                                        const MCFixup &Fixup, MCValue Target,
1387                                        uint64_t &FixedValue) {
1388   MCAsmBackend &Backend = Asm.getBackend();
1389   bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1390                  MCFixupKindInfo::FKF_IsPCRel;
1391   const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1392   uint64_t C = Target.getConstant();
1393   uint64_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();
1394   MCContext &Ctx = Asm.getContext();
1395   const MCTargetOptions *TO = Ctx.getTargetOptions();
1396 
1397   if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1398     const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1399     if (SymB.isUndefined()) {
1400       Ctx.reportError(Fixup.getLoc(),
1401                       Twine("symbol '") + SymB.getName() +
1402                           "' can not be undefined in a subtraction expression");
1403       return;
1404     }
1405 
1406     assert(!SymB.isAbsolute() && "Should have been folded");
1407     const MCSection &SecB = SymB.getSection();
1408     if (&SecB != &FixupSection) {
1409       Ctx.reportError(Fixup.getLoc(),
1410                       "Cannot represent a difference across sections");
1411       return;
1412     }
1413 
1414     assert(!IsPCRel && "should have been folded");
1415     IsPCRel = true;
1416     C += FixupOffset - Asm.getSymbolOffset(SymB);
1417   }
1418 
1419   // We either rejected the fixup or folded B into C at this point.
1420   const MCSymbolRefExpr *RefA = Target.getSymA();
1421   const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1422 
1423   bool ViaWeakRef = false;
1424   if (SymA && SymA->isVariable()) {
1425     const MCExpr *Expr = SymA->getVariableValue();
1426     if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1427       if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1428         SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1429         ViaWeakRef = true;
1430       }
1431     }
1432   }
1433 
1434   const MCSectionELF *SecA = (SymA && SymA->isInSection())
1435                                  ? cast<MCSectionELF>(&SymA->getSection())
1436                                  : nullptr;
1437   if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1438     return;
1439 
1440   unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1441   const auto *Parent = cast<MCSectionELF>(Fragment->getParent());
1442   // Emiting relocation with sybmol for CG Profile to  help with --cg-profile.
1443   bool RelocateWithSymbol =
1444       shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||
1445       (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
1446   uint64_t Addend = 0;
1447 
1448   FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1449                    ? C + Asm.getSymbolOffset(*SymA)
1450                    : C;
1451   if (usesRela(TO, FixupSection)) {
1452     Addend = FixedValue;
1453     FixedValue = 0;
1454   }
1455 
1456   if (!RelocateWithSymbol) {
1457     const auto *SectionSymbol =
1458         SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1459     if (SectionSymbol)
1460       SectionSymbol->setUsedInReloc();
1461     ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
1462     Relocations[&FixupSection].push_back(Rec);
1463     return;
1464   }
1465 
1466   const MCSymbolELF *RenamedSymA = SymA;
1467   if (SymA) {
1468     if (const MCSymbolELF *R = Renames.lookup(SymA))
1469       RenamedSymA = R;
1470 
1471     if (ViaWeakRef)
1472       RenamedSymA->setIsWeakrefUsedInReloc();
1473     else
1474       RenamedSymA->setUsedInReloc();
1475   }
1476   ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1477   Relocations[&FixupSection].push_back(Rec);
1478 }
1479 
1480 bool ELFObjectWriter::usesRela(const MCTargetOptions *TO,
1481                                const MCSectionELF &Sec) const {
1482   return (hasRelocationAddend() &&
1483           Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE) ||
1484          (TO && TO->Crel);
1485 }
1486 
1487 bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1488     const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1489     bool InSet, bool IsPCRel) const {
1490   const auto &SymA = cast<MCSymbolELF>(SA);
1491   if (IsPCRel) {
1492     assert(!InSet);
1493     if (SymA.getBinding() != ELF::STB_LOCAL ||
1494         SymA.getType() == ELF::STT_GNU_IFUNC)
1495       return false;
1496   }
1497   return &SymA.getSection() == FB.getParent();
1498 }
1499 
1500 uint64_t ELFObjectWriter::writeObject(MCAssembler &Asm) {
1501   uint64_t Size =
1502       ELFWriter(*this, OS, IsLittleEndian,
1503                 DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections)
1504           .writeObject(Asm);
1505   if (DwoOS)
1506     Size += ELFWriter(*this, *DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
1507                 .writeObject(Asm);
1508   return Size;
1509 }
1510