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