xref: /freebsd/contrib/llvm-project/llvm/lib/ObjectYAML/ELFEmitter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1  //===- yaml2elf - Convert YAML to a ELF object file -----------------------===//
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  /// \file
10  /// The ELF component of yaml2obj.
11  ///
12  //===----------------------------------------------------------------------===//
13  
14  #include "llvm/ADT/ArrayRef.h"
15  #include "llvm/ADT/DenseMap.h"
16  #include "llvm/ADT/SetVector.h"
17  #include "llvm/ADT/StringSet.h"
18  #include "llvm/BinaryFormat/ELF.h"
19  #include "llvm/MC/StringTableBuilder.h"
20  #include "llvm/Object/ELFObjectFile.h"
21  #include "llvm/Object/ELFTypes.h"
22  #include "llvm/ObjectYAML/DWARFEmitter.h"
23  #include "llvm/ObjectYAML/DWARFYAML.h"
24  #include "llvm/ObjectYAML/ELFYAML.h"
25  #include "llvm/ObjectYAML/yaml2obj.h"
26  #include "llvm/Support/EndianStream.h"
27  #include "llvm/Support/Errc.h"
28  #include "llvm/Support/Error.h"
29  #include "llvm/Support/LEB128.h"
30  #include "llvm/Support/MemoryBuffer.h"
31  #include "llvm/Support/WithColor.h"
32  #include "llvm/Support/YAMLTraits.h"
33  #include "llvm/Support/raw_ostream.h"
34  #include <optional>
35  #include <variant>
36  
37  using namespace llvm;
38  
39  // This class is used to build up a contiguous binary blob while keeping
40  // track of an offset in the output (which notionally begins at
41  // `InitialOffset`).
42  // The blob might be limited to an arbitrary size. All attempts to write data
43  // are ignored and the error condition is remembered once the limit is reached.
44  // Such an approach allows us to simplify the code by delaying error reporting
45  // and doing it at a convenient time.
46  namespace {
47  class ContiguousBlobAccumulator {
48    const uint64_t InitialOffset;
49    const uint64_t MaxSize;
50  
51    SmallVector<char, 128> Buf;
52    raw_svector_ostream OS;
53    Error ReachedLimitErr = Error::success();
54  
checkLimit(uint64_t Size)55    bool checkLimit(uint64_t Size) {
56      if (!ReachedLimitErr && getOffset() + Size <= MaxSize)
57        return true;
58      if (!ReachedLimitErr)
59        ReachedLimitErr = createStringError(errc::invalid_argument,
60                                            "reached the output size limit");
61      return false;
62    }
63  
64  public:
ContiguousBlobAccumulator(uint64_t BaseOffset,uint64_t SizeLimit)65    ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t SizeLimit)
66        : InitialOffset(BaseOffset), MaxSize(SizeLimit), OS(Buf) {}
67  
tell() const68    uint64_t tell() const { return OS.tell(); }
getOffset() const69    uint64_t getOffset() const { return InitialOffset + OS.tell(); }
writeBlobToStream(raw_ostream & Out) const70    void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); }
71  
takeLimitError()72    Error takeLimitError() {
73      // Request to write 0 bytes to check we did not reach the limit.
74      checkLimit(0);
75      return std::move(ReachedLimitErr);
76    }
77  
78    /// \returns The new offset.
padToAlignment(unsigned Align)79    uint64_t padToAlignment(unsigned Align) {
80      uint64_t CurrentOffset = getOffset();
81      if (ReachedLimitErr)
82        return CurrentOffset;
83  
84      uint64_t AlignedOffset = alignTo(CurrentOffset, Align == 0 ? 1 : Align);
85      uint64_t PaddingSize = AlignedOffset - CurrentOffset;
86      if (!checkLimit(PaddingSize))
87        return CurrentOffset;
88  
89      writeZeros(PaddingSize);
90      return AlignedOffset;
91    }
92  
getRawOS(uint64_t Size)93    raw_ostream *getRawOS(uint64_t Size) {
94      if (checkLimit(Size))
95        return &OS;
96      return nullptr;
97    }
98  
writeAsBinary(const yaml::BinaryRef & Bin,uint64_t N=UINT64_MAX)99    void writeAsBinary(const yaml::BinaryRef &Bin, uint64_t N = UINT64_MAX) {
100      if (!checkLimit(Bin.binary_size()))
101        return;
102      Bin.writeAsBinary(OS, N);
103    }
104  
writeZeros(uint64_t Num)105    void writeZeros(uint64_t Num) {
106      if (checkLimit(Num))
107        OS.write_zeros(Num);
108    }
109  
write(const char * Ptr,size_t Size)110    void write(const char *Ptr, size_t Size) {
111      if (checkLimit(Size))
112        OS.write(Ptr, Size);
113    }
114  
write(unsigned char C)115    void write(unsigned char C) {
116      if (checkLimit(1))
117        OS.write(C);
118    }
119  
writeULEB128(uint64_t Val)120    unsigned writeULEB128(uint64_t Val) {
121      if (!checkLimit(sizeof(uint64_t)))
122        return 0;
123      return encodeULEB128(Val, OS);
124    }
125  
writeSLEB128(int64_t Val)126    unsigned writeSLEB128(int64_t Val) {
127      if (!checkLimit(10))
128        return 0;
129      return encodeSLEB128(Val, OS);
130    }
131  
write(T Val,llvm::endianness E)132    template <typename T> void write(T Val, llvm::endianness E) {
133      if (checkLimit(sizeof(T)))
134        support::endian::write<T>(OS, Val, E);
135    }
136  
updateDataAt(uint64_t Pos,void * Data,size_t Size)137    void updateDataAt(uint64_t Pos, void *Data, size_t Size) {
138      assert(Pos >= InitialOffset && Pos + Size <= getOffset());
139      memcpy(&Buf[Pos - InitialOffset], Data, Size);
140    }
141  };
142  
143  // Used to keep track of section and symbol names, so that in the YAML file
144  // sections and symbols can be referenced by name instead of by index.
145  class NameToIdxMap {
146    StringMap<unsigned> Map;
147  
148  public:
149    /// \Returns false if name is already present in the map.
addName(StringRef Name,unsigned Ndx)150    bool addName(StringRef Name, unsigned Ndx) {
151      return Map.insert({Name, Ndx}).second;
152    }
153    /// \Returns false if name is not present in the map.
lookup(StringRef Name,unsigned & Idx) const154    bool lookup(StringRef Name, unsigned &Idx) const {
155      auto I = Map.find(Name);
156      if (I == Map.end())
157        return false;
158      Idx = I->getValue();
159      return true;
160    }
161    /// Asserts if name is not present in the map.
get(StringRef Name) const162    unsigned get(StringRef Name) const {
163      unsigned Idx;
164      if (lookup(Name, Idx))
165        return Idx;
166      assert(false && "Expected section not found in index");
167      return 0;
168    }
size() const169    unsigned size() const { return Map.size(); }
170  };
171  
172  namespace {
173  struct Fragment {
174    uint64_t Offset;
175    uint64_t Size;
176    uint32_t Type;
177    uint64_t AddrAlign;
178  };
179  } // namespace
180  
181  /// "Single point of truth" for the ELF file construction.
182  /// TODO: This class still has a ways to go before it is truly a "single
183  /// point of truth".
184  template <class ELFT> class ELFState {
185    LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
186  
187    enum class SymtabType { Static, Dynamic };
188  
189    /// The future symbol table string section.
190    StringTableBuilder DotStrtab{StringTableBuilder::ELF};
191  
192    /// The future section header string table section, if a unique string table
193    /// is needed. Don't reference this variable direectly: use the
194    /// ShStrtabStrings member instead.
195    StringTableBuilder DotShStrtab{StringTableBuilder::ELF};
196  
197    /// The future dynamic symbol string section.
198    StringTableBuilder DotDynstr{StringTableBuilder::ELF};
199  
200    /// The name of the section header string table section. If it is .strtab or
201    /// .dynstr, the section header strings will be written to the same string
202    /// table as the static/dynamic symbols respectively. Otherwise a dedicated
203    /// section will be created with that name.
204    StringRef SectionHeaderStringTableName = ".shstrtab";
205    StringTableBuilder *ShStrtabStrings = &DotShStrtab;
206  
207    NameToIdxMap SN2I;
208    NameToIdxMap SymN2I;
209    NameToIdxMap DynSymN2I;
210    ELFYAML::Object &Doc;
211  
212    StringSet<> ExcludedSectionHeaders;
213  
214    uint64_t LocationCounter = 0;
215    bool HasError = false;
216    yaml::ErrorHandler ErrHandler;
217    void reportError(const Twine &Msg);
218    void reportError(Error Err);
219  
220    std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
221                                      const StringTableBuilder &Strtab);
222    unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = "");
223    unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic);
224  
225    void buildSectionIndex();
226    void buildSymbolIndexes();
227    void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);
228    bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header,
229                            StringRef SecName, ELFYAML::Section *YAMLSec);
230    void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
231                            ContiguousBlobAccumulator &CBA);
232    void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType,
233                                 ContiguousBlobAccumulator &CBA,
234                                 ELFYAML::Section *YAMLSec);
235    void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
236                                 StringTableBuilder &STB,
237                                 ContiguousBlobAccumulator &CBA,
238                                 ELFYAML::Section *YAMLSec);
239    void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
240                                ContiguousBlobAccumulator &CBA,
241                                ELFYAML::Section *YAMLSec);
242    void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
243                                std::vector<Elf_Shdr> &SHeaders);
244  
245    std::vector<Fragment>
246    getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,
247                     ArrayRef<typename ELFT::Shdr> SHeaders);
248  
249    void finalizeStrings();
250    void writeELFHeader(raw_ostream &OS);
251    void writeSectionContent(Elf_Shdr &SHeader,
252                             const ELFYAML::NoBitsSection &Section,
253                             ContiguousBlobAccumulator &CBA);
254    void writeSectionContent(Elf_Shdr &SHeader,
255                             const ELFYAML::RawContentSection &Section,
256                             ContiguousBlobAccumulator &CBA);
257    void writeSectionContent(Elf_Shdr &SHeader,
258                             const ELFYAML::RelocationSection &Section,
259                             ContiguousBlobAccumulator &CBA);
260    void writeSectionContent(Elf_Shdr &SHeader,
261                             const ELFYAML::RelrSection &Section,
262                             ContiguousBlobAccumulator &CBA);
263    void writeSectionContent(Elf_Shdr &SHeader,
264                             const ELFYAML::GroupSection &Group,
265                             ContiguousBlobAccumulator &CBA);
266    void writeSectionContent(Elf_Shdr &SHeader,
267                             const ELFYAML::SymtabShndxSection &Shndx,
268                             ContiguousBlobAccumulator &CBA);
269    void writeSectionContent(Elf_Shdr &SHeader,
270                             const ELFYAML::SymverSection &Section,
271                             ContiguousBlobAccumulator &CBA);
272    void writeSectionContent(Elf_Shdr &SHeader,
273                             const ELFYAML::VerneedSection &Section,
274                             ContiguousBlobAccumulator &CBA);
275    void writeSectionContent(Elf_Shdr &SHeader,
276                             const ELFYAML::VerdefSection &Section,
277                             ContiguousBlobAccumulator &CBA);
278    void writeSectionContent(Elf_Shdr &SHeader,
279                             const ELFYAML::ARMIndexTableSection &Section,
280                             ContiguousBlobAccumulator &CBA);
281    void writeSectionContent(Elf_Shdr &SHeader,
282                             const ELFYAML::MipsABIFlags &Section,
283                             ContiguousBlobAccumulator &CBA);
284    void writeSectionContent(Elf_Shdr &SHeader,
285                             const ELFYAML::DynamicSection &Section,
286                             ContiguousBlobAccumulator &CBA);
287    void writeSectionContent(Elf_Shdr &SHeader,
288                             const ELFYAML::StackSizesSection &Section,
289                             ContiguousBlobAccumulator &CBA);
290    void writeSectionContent(Elf_Shdr &SHeader,
291                             const ELFYAML::BBAddrMapSection &Section,
292                             ContiguousBlobAccumulator &CBA);
293    void writeSectionContent(Elf_Shdr &SHeader,
294                             const ELFYAML::HashSection &Section,
295                             ContiguousBlobAccumulator &CBA);
296    void writeSectionContent(Elf_Shdr &SHeader,
297                             const ELFYAML::AddrsigSection &Section,
298                             ContiguousBlobAccumulator &CBA);
299    void writeSectionContent(Elf_Shdr &SHeader,
300                             const ELFYAML::NoteSection &Section,
301                             ContiguousBlobAccumulator &CBA);
302    void writeSectionContent(Elf_Shdr &SHeader,
303                             const ELFYAML::GnuHashSection &Section,
304                             ContiguousBlobAccumulator &CBA);
305    void writeSectionContent(Elf_Shdr &SHeader,
306                             const ELFYAML::LinkerOptionsSection &Section,
307                             ContiguousBlobAccumulator &CBA);
308    void writeSectionContent(Elf_Shdr &SHeader,
309                             const ELFYAML::DependentLibrariesSection &Section,
310                             ContiguousBlobAccumulator &CBA);
311    void writeSectionContent(Elf_Shdr &SHeader,
312                             const ELFYAML::CallGraphProfileSection &Section,
313                             ContiguousBlobAccumulator &CBA);
314  
315    void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);
316  
317    ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH);
318  
319    void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec);
320  
321    DenseMap<StringRef, size_t> buildSectionHeaderReorderMap();
322  
323    BumpPtrAllocator StringAlloc;
324    uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
325                           std::optional<llvm::yaml::Hex64> Offset);
326  
327    uint64_t getSectionNameOffset(StringRef Name);
328  
329  public:
330    static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
331                         yaml::ErrorHandler EH, uint64_t MaxSize);
332  };
333  } // end anonymous namespace
334  
arrayDataSize(ArrayRef<T> A)335  template <class T> static size_t arrayDataSize(ArrayRef<T> A) {
336    return A.size() * sizeof(T);
337  }
338  
writeArrayData(raw_ostream & OS,ArrayRef<T> A)339  template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) {
340    OS.write((const char *)A.data(), arrayDataSize(A));
341  }
342  
zero(T & Obj)343  template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
344  
345  template <class ELFT>
ELFState(ELFYAML::Object & D,yaml::ErrorHandler EH)346  ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
347      : Doc(D), ErrHandler(EH) {
348    // The input may explicitly request to store the section header table strings
349    // in the same string table as dynamic or static symbol names. Set the
350    // ShStrtabStrings member accordingly.
351    if (Doc.Header.SectionHeaderStringTable) {
352      SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable;
353      if (*Doc.Header.SectionHeaderStringTable == ".strtab")
354        ShStrtabStrings = &DotStrtab;
355      else if (*Doc.Header.SectionHeaderStringTable == ".dynstr")
356        ShStrtabStrings = &DotDynstr;
357      // Otherwise, the unique table will be used.
358    }
359  
360    std::vector<ELFYAML::Section *> Sections = Doc.getSections();
361    // Insert SHT_NULL section implicitly when it is not defined in YAML.
362    if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL)
363      Doc.Chunks.insert(
364          Doc.Chunks.begin(),
365          std::make_unique<ELFYAML::Section>(
366              ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/true));
367  
368    StringSet<> DocSections;
369    ELFYAML::SectionHeaderTable *SecHdrTable = nullptr;
370    for (size_t I = 0; I < Doc.Chunks.size(); ++I) {
371      const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I];
372  
373      // We might have an explicit section header table declaration.
374      if (auto S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) {
375        if (SecHdrTable)
376          reportError("multiple section header tables are not allowed");
377        SecHdrTable = S;
378        continue;
379      }
380  
381      // We add a technical suffix for each unnamed section/fill. It does not
382      // affect the output, but allows us to map them by name in the code and
383      // report better error messages.
384      if (C->Name.empty()) {
385        std::string NewName = ELFYAML::appendUniqueSuffix(
386            /*Name=*/"", "index " + Twine(I));
387        C->Name = StringRef(NewName).copy(StringAlloc);
388        assert(ELFYAML::dropUniqueSuffix(C->Name).empty());
389      }
390  
391      if (!DocSections.insert(C->Name).second)
392        reportError("repeated section/fill name: '" + C->Name +
393                    "' at YAML section/fill number " + Twine(I));
394    }
395  
396    SmallSetVector<StringRef, 8> ImplicitSections;
397    if (Doc.DynamicSymbols) {
398      if (SectionHeaderStringTableName == ".dynsym")
399        reportError("cannot use '.dynsym' as the section header name table when "
400                    "there are dynamic symbols");
401      ImplicitSections.insert(".dynsym");
402      ImplicitSections.insert(".dynstr");
403    }
404    if (Doc.Symbols) {
405      if (SectionHeaderStringTableName == ".symtab")
406        reportError("cannot use '.symtab' as the section header name table when "
407                    "there are symbols");
408      ImplicitSections.insert(".symtab");
409    }
410    if (Doc.DWARF)
411      for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) {
412        std::string SecName = ("." + DebugSecName).str();
413        // TODO: For .debug_str it should be possible to share the string table,
414        // in the same manner as the symbol string tables.
415        if (SectionHeaderStringTableName == SecName)
416          reportError("cannot use '" + SecName +
417                      "' as the section header name table when it is needed for "
418                      "DWARF output");
419        ImplicitSections.insert(StringRef(SecName).copy(StringAlloc));
420      }
421    // TODO: Only create the .strtab here if any symbols have been requested.
422    ImplicitSections.insert(".strtab");
423    if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(false))
424      ImplicitSections.insert(SectionHeaderStringTableName);
425  
426    // Insert placeholders for implicit sections that are not
427    // defined explicitly in YAML.
428    for (StringRef SecName : ImplicitSections) {
429      if (DocSections.count(SecName))
430        continue;
431  
432      std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>(
433          ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/);
434      Sec->Name = SecName;
435  
436      if (SecName == SectionHeaderStringTableName)
437        Sec->Type = ELF::SHT_STRTAB;
438      else if (SecName == ".dynsym")
439        Sec->Type = ELF::SHT_DYNSYM;
440      else if (SecName == ".symtab")
441        Sec->Type = ELF::SHT_SYMTAB;
442      else
443        Sec->Type = ELF::SHT_STRTAB;
444  
445      // When the section header table is explicitly defined at the end of the
446      // sections list, it is reasonable to assume that the user wants to reorder
447      // section headers, but still wants to place the section header table after
448      // all sections, like it normally happens. In this case we want to insert
449      // other implicit sections right before the section header table.
450      if (Doc.Chunks.back().get() == SecHdrTable)
451        Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec));
452      else
453        Doc.Chunks.push_back(std::move(Sec));
454    }
455  
456    // Insert the section header table implicitly at the end, when it is not
457    // explicitly defined.
458    if (!SecHdrTable)
459      Doc.Chunks.push_back(
460          std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/true));
461  }
462  
463  template <class ELFT>
writeELFHeader(raw_ostream & OS)464  void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) {
465    using namespace llvm::ELF;
466  
467    Elf_Ehdr Header;
468    zero(Header);
469    Header.e_ident[EI_MAG0] = 0x7f;
470    Header.e_ident[EI_MAG1] = 'E';
471    Header.e_ident[EI_MAG2] = 'L';
472    Header.e_ident[EI_MAG3] = 'F';
473    Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
474    Header.e_ident[EI_DATA] = Doc.Header.Data;
475    Header.e_ident[EI_VERSION] = EV_CURRENT;
476    Header.e_ident[EI_OSABI] = Doc.Header.OSABI;
477    Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion;
478    Header.e_type = Doc.Header.Type;
479  
480    if (Doc.Header.Machine)
481      Header.e_machine = *Doc.Header.Machine;
482    else
483      Header.e_machine = EM_NONE;
484  
485    Header.e_version = EV_CURRENT;
486    Header.e_entry = Doc.Header.Entry;
487    Header.e_flags = Doc.Header.Flags;
488    Header.e_ehsize = sizeof(Elf_Ehdr);
489  
490    if (Doc.Header.EPhOff)
491      Header.e_phoff = *Doc.Header.EPhOff;
492    else if (!Doc.ProgramHeaders.empty())
493      Header.e_phoff = sizeof(Header);
494    else
495      Header.e_phoff = 0;
496  
497    if (Doc.Header.EPhEntSize)
498      Header.e_phentsize = *Doc.Header.EPhEntSize;
499    else if (!Doc.ProgramHeaders.empty())
500      Header.e_phentsize = sizeof(Elf_Phdr);
501    else
502      Header.e_phentsize = 0;
503  
504    if (Doc.Header.EPhNum)
505      Header.e_phnum = *Doc.Header.EPhNum;
506    else if (!Doc.ProgramHeaders.empty())
507      Header.e_phnum = Doc.ProgramHeaders.size();
508    else
509      Header.e_phnum = 0;
510  
511    Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize
512                                               : sizeof(Elf_Shdr);
513  
514    const ELFYAML::SectionHeaderTable &SectionHeaders =
515        Doc.getSectionHeaderTable();
516  
517    if (Doc.Header.EShOff)
518      Header.e_shoff = *Doc.Header.EShOff;
519    else if (SectionHeaders.Offset)
520      Header.e_shoff = *SectionHeaders.Offset;
521    else
522      Header.e_shoff = 0;
523  
524    if (Doc.Header.EShNum)
525      Header.e_shnum = *Doc.Header.EShNum;
526    else
527      Header.e_shnum = SectionHeaders.getNumHeaders(Doc.getSections().size());
528  
529    if (Doc.Header.EShStrNdx)
530      Header.e_shstrndx = *Doc.Header.EShStrNdx;
531    else if (SectionHeaders.Offset &&
532             !ExcludedSectionHeaders.count(SectionHeaderStringTableName))
533      Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName);
534    else
535      Header.e_shstrndx = 0;
536  
537    OS.write((const char *)&Header, sizeof(Header));
538  }
539  
540  template <class ELFT>
initProgramHeaders(std::vector<Elf_Phdr> & PHeaders)541  void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) {
542    DenseMap<StringRef, ELFYAML::Fill *> NameToFill;
543    DenseMap<StringRef, size_t> NameToIndex;
544    for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) {
545      if (auto S = dyn_cast<ELFYAML::Fill>(Doc.Chunks[I].get()))
546        NameToFill[S->Name] = S;
547      NameToIndex[Doc.Chunks[I]->Name] = I + 1;
548    }
549  
550    std::vector<ELFYAML::Section *> Sections = Doc.getSections();
551    for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) {
552      ELFYAML::ProgramHeader &YamlPhdr = Doc.ProgramHeaders[I];
553      Elf_Phdr Phdr;
554      zero(Phdr);
555      Phdr.p_type = YamlPhdr.Type;
556      Phdr.p_flags = YamlPhdr.Flags;
557      Phdr.p_vaddr = YamlPhdr.VAddr;
558      Phdr.p_paddr = YamlPhdr.PAddr;
559      PHeaders.push_back(Phdr);
560  
561      if (!YamlPhdr.FirstSec && !YamlPhdr.LastSec)
562        continue;
563  
564      // Get the index of the section, or 0 in the case when the section doesn't exist.
565      size_t First = NameToIndex[*YamlPhdr.FirstSec];
566      if (!First)
567        reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec +
568                    "' by the 'FirstSec' key of the program header with index " +
569                    Twine(I));
570      size_t Last = NameToIndex[*YamlPhdr.LastSec];
571      if (!Last)
572        reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec +
573                    "' by the 'LastSec' key of the program header with index " +
574                    Twine(I));
575      if (!First || !Last)
576        continue;
577  
578      if (First > Last)
579        reportError("program header with index " + Twine(I) +
580                    ": the section index of " + *YamlPhdr.FirstSec +
581                    " is greater than the index of " + *YamlPhdr.LastSec);
582  
583      for (size_t I = First; I <= Last; ++I)
584        YamlPhdr.Chunks.push_back(Doc.Chunks[I - 1].get());
585    }
586  }
587  
588  template <class ELFT>
toSectionIndex(StringRef S,StringRef LocSec,StringRef LocSym)589  unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec,
590                                          StringRef LocSym) {
591    assert(LocSec.empty() || LocSym.empty());
592  
593    unsigned Index;
594    if (!SN2I.lookup(S, Index) && !to_integer(S, Index)) {
595      if (!LocSym.empty())
596        reportError("unknown section referenced: '" + S + "' by YAML symbol '" +
597                    LocSym + "'");
598      else
599        reportError("unknown section referenced: '" + S + "' by YAML section '" +
600                    LocSec + "'");
601      return 0;
602    }
603  
604    const ELFYAML::SectionHeaderTable &SectionHeaders =
605        Doc.getSectionHeaderTable();
606    if (SectionHeaders.IsImplicit ||
607        (SectionHeaders.NoHeaders && !*SectionHeaders.NoHeaders) ||
608        SectionHeaders.isDefault())
609      return Index;
610  
611    assert(!SectionHeaders.NoHeaders.value_or(false) || !SectionHeaders.Sections);
612    size_t FirstExcluded =
613        SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0;
614    if (Index > FirstExcluded) {
615      if (LocSym.empty())
616        reportError("unable to link '" + LocSec + "' to excluded section '" + S +
617                    "'");
618      else
619        reportError("excluded section referenced: '" + S + "'  by symbol '" +
620                    LocSym + "'");
621    }
622    return Index;
623  }
624  
625  template <class ELFT>
toSymbolIndex(StringRef S,StringRef LocSec,bool IsDynamic)626  unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec,
627                                         bool IsDynamic) {
628    const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I;
629    unsigned Index;
630    // Here we try to look up S in the symbol table. If it is not there,
631    // treat its value as a symbol index.
632    if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) {
633      reportError("unknown symbol referenced: '" + S + "' by YAML section '" +
634                  LocSec + "'");
635      return 0;
636    }
637    return Index;
638  }
639  
640  template <class ELFT>
overrideFields(ELFYAML::Section * From,typename ELFT::Shdr & To)641  static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) {
642    if (!From)
643      return;
644    if (From->ShAddrAlign)
645      To.sh_addralign = *From->ShAddrAlign;
646    if (From->ShFlags)
647      To.sh_flags = *From->ShFlags;
648    if (From->ShName)
649      To.sh_name = *From->ShName;
650    if (From->ShOffset)
651      To.sh_offset = *From->ShOffset;
652    if (From->ShSize)
653      To.sh_size = *From->ShSize;
654    if (From->ShType)
655      To.sh_type = *From->ShType;
656  }
657  
658  template <class ELFT>
initImplicitHeader(ContiguousBlobAccumulator & CBA,Elf_Shdr & Header,StringRef SecName,ELFYAML::Section * YAMLSec)659  bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,
660                                          Elf_Shdr &Header, StringRef SecName,
661                                          ELFYAML::Section *YAMLSec) {
662    // Check if the header was already initialized.
663    if (Header.sh_offset)
664      return false;
665  
666    if (SecName == ".strtab")
667      initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec);
668    else if (SecName == ".dynstr")
669      initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec);
670    else if (SecName == SectionHeaderStringTableName)
671      initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec);
672    else if (SecName == ".symtab")
673      initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec);
674    else if (SecName == ".dynsym")
675      initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec);
676    else if (SecName.starts_with(".debug_")) {
677      // If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we
678      // will not treat it as a debug section.
679      if (YAMLSec && !isa<ELFYAML::RawContentSection>(YAMLSec))
680        return false;
681      initDWARFSectionHeader(Header, SecName, CBA, YAMLSec);
682    } else
683      return false;
684  
685    LocationCounter += Header.sh_size;
686  
687    // Override section fields if requested.
688    overrideFields<ELFT>(YAMLSec, Header);
689    return true;
690  }
691  
692  constexpr char SuffixStart = '(';
693  constexpr char SuffixEnd = ')';
694  
appendUniqueSuffix(StringRef Name,const Twine & Msg)695  std::string llvm::ELFYAML::appendUniqueSuffix(StringRef Name,
696                                                const Twine &Msg) {
697    // Do not add a space when a Name is empty.
698    std::string Ret = Name.empty() ? "" : Name.str() + ' ';
699    return Ret + (Twine(SuffixStart) + Msg + Twine(SuffixEnd)).str();
700  }
701  
dropUniqueSuffix(StringRef S)702  StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) {
703    if (S.empty() || S.back() != SuffixEnd)
704      return S;
705  
706    // A special case for empty names. See appendUniqueSuffix() above.
707    size_t SuffixPos = S.rfind(SuffixStart);
708    if (SuffixPos == 0)
709      return "";
710  
711    if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ')
712      return S;
713    return S.substr(0, SuffixPos - 1);
714  }
715  
716  template <class ELFT>
getSectionNameOffset(StringRef Name)717  uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) {
718    // If a section is excluded from section headers, we do not save its name in
719    // the string table.
720    if (ExcludedSectionHeaders.count(Name))
721      return 0;
722    return ShStrtabStrings->getOffset(Name);
723  }
724  
writeContent(ContiguousBlobAccumulator & CBA,const std::optional<yaml::BinaryRef> & Content,const std::optional<llvm::yaml::Hex64> & Size)725  static uint64_t writeContent(ContiguousBlobAccumulator &CBA,
726                               const std::optional<yaml::BinaryRef> &Content,
727                               const std::optional<llvm::yaml::Hex64> &Size) {
728    size_t ContentSize = 0;
729    if (Content) {
730      CBA.writeAsBinary(*Content);
731      ContentSize = Content->binary_size();
732    }
733  
734    if (!Size)
735      return ContentSize;
736  
737    CBA.writeZeros(*Size - ContentSize);
738    return *Size;
739  }
740  
getDefaultLinkSec(unsigned SecType)741  static StringRef getDefaultLinkSec(unsigned SecType) {
742    switch (SecType) {
743    case ELF::SHT_REL:
744    case ELF::SHT_RELA:
745    case ELF::SHT_GROUP:
746    case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
747    case ELF::SHT_LLVM_ADDRSIG:
748      return ".symtab";
749    case ELF::SHT_GNU_versym:
750    case ELF::SHT_HASH:
751    case ELF::SHT_GNU_HASH:
752      return ".dynsym";
753    case ELF::SHT_DYNSYM:
754    case ELF::SHT_GNU_verdef:
755    case ELF::SHT_GNU_verneed:
756      return ".dynstr";
757    case ELF::SHT_SYMTAB:
758      return ".strtab";
759    default:
760      return "";
761    }
762  }
763  
764  template <class ELFT>
initSectionHeaders(std::vector<Elf_Shdr> & SHeaders,ContiguousBlobAccumulator & CBA)765  void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
766                                          ContiguousBlobAccumulator &CBA) {
767    // Ensure SHN_UNDEF entry is present. An all-zero section header is a
768    // valid SHN_UNDEF entry since SHT_NULL == 0.
769    SHeaders.resize(Doc.getSections().size());
770  
771    for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) {
772      if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) {
773        S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);
774        writeFill(*S, CBA);
775        LocationCounter += S->Size;
776        continue;
777      }
778  
779      if (ELFYAML::SectionHeaderTable *S =
780              dyn_cast<ELFYAML::SectionHeaderTable>(D.get())) {
781        if (S->NoHeaders.value_or(false))
782          continue;
783  
784        if (!S->Offset)
785          S->Offset = alignToOffset(CBA, sizeof(typename ELFT::uint),
786                                    /*Offset=*/std::nullopt);
787        else
788          S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);
789  
790        uint64_t Size = S->getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr);
791        // The full section header information might be not available here, so
792        // fill the space with zeroes as a placeholder.
793        CBA.writeZeros(Size);
794        LocationCounter += Size;
795        continue;
796      }
797  
798      ELFYAML::Section *Sec = cast<ELFYAML::Section>(D.get());
799      bool IsFirstUndefSection = Sec == Doc.getSections().front();
800      if (IsFirstUndefSection && Sec->IsImplicit)
801        continue;
802  
803      Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)];
804      if (Sec->Link) {
805        SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name);
806      } else {
807        StringRef LinkSec = getDefaultLinkSec(Sec->Type);
808        unsigned Link = 0;
809        if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) &&
810            SN2I.lookup(LinkSec, Link))
811          SHeader.sh_link = Link;
812      }
813  
814      if (Sec->EntSize)
815        SHeader.sh_entsize = *Sec->EntSize;
816      else
817        SHeader.sh_entsize = ELFYAML::getDefaultShEntSize<ELFT>(
818            Doc.Header.Machine.value_or(ELF::EM_NONE), Sec->Type, Sec->Name);
819  
820      // We have a few sections like string or symbol tables that are usually
821      // added implicitly to the end. However, if they are explicitly specified
822      // in the YAML, we need to write them here. This ensures the file offset
823      // remains correct.
824      if (initImplicitHeader(CBA, SHeader, Sec->Name,
825                             Sec->IsImplicit ? nullptr : Sec))
826        continue;
827  
828      assert(Sec && "It can't be null unless it is an implicit section. But all "
829                    "implicit sections should already have been handled above.");
830  
831      SHeader.sh_name =
832          getSectionNameOffset(ELFYAML::dropUniqueSuffix(Sec->Name));
833      SHeader.sh_type = Sec->Type;
834      if (Sec->Flags)
835        SHeader.sh_flags = *Sec->Flags;
836      SHeader.sh_addralign = Sec->AddressAlign;
837  
838      // Set the offset for all sections, except the SHN_UNDEF section with index
839      // 0 when not explicitly requested.
840      if (!IsFirstUndefSection || Sec->Offset)
841        SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->Offset);
842  
843      assignSectionAddress(SHeader, Sec);
844  
845      if (IsFirstUndefSection) {
846        if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
847          // We do not write any content for special SHN_UNDEF section.
848          if (RawSec->Size)
849            SHeader.sh_size = *RawSec->Size;
850          if (RawSec->Info)
851            SHeader.sh_info = *RawSec->Info;
852        }
853  
854        LocationCounter += SHeader.sh_size;
855        overrideFields<ELFT>(Sec, SHeader);
856        continue;
857      }
858  
859      if (!isa<ELFYAML::NoBitsSection>(Sec) && (Sec->Content || Sec->Size))
860        SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size);
861  
862      if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
863        writeSectionContent(SHeader, *S, CBA);
864      } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) {
865        writeSectionContent(SHeader, *S, CBA);
866      } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) {
867        writeSectionContent(SHeader, *S, CBA);
868      } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) {
869        writeSectionContent(SHeader, *S, CBA);
870      } else if (auto S = dyn_cast<ELFYAML::GroupSection>(Sec)) {
871        writeSectionContent(SHeader, *S, CBA);
872      } else if (auto S = dyn_cast<ELFYAML::ARMIndexTableSection>(Sec)) {
873        writeSectionContent(SHeader, *S, CBA);
874      } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) {
875        writeSectionContent(SHeader, *S, CBA);
876      } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) {
877        writeSectionContent(SHeader, *S, CBA);
878      } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) {
879        writeSectionContent(SHeader, *S, CBA);
880      } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) {
881        writeSectionContent(SHeader, *S, CBA);
882      } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) {
883        writeSectionContent(SHeader, *S, CBA);
884      } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) {
885        writeSectionContent(SHeader, *S, CBA);
886      } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) {
887        writeSectionContent(SHeader, *S, CBA);
888      } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) {
889        writeSectionContent(SHeader, *S, CBA);
890      } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) {
891        writeSectionContent(SHeader, *S, CBA);
892      } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) {
893        writeSectionContent(SHeader, *S, CBA);
894      } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) {
895        writeSectionContent(SHeader, *S, CBA);
896      } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) {
897        writeSectionContent(SHeader, *S, CBA);
898      } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Sec)) {
899        writeSectionContent(SHeader, *S, CBA);
900      } else if (auto S = dyn_cast<ELFYAML::CallGraphProfileSection>(Sec)) {
901        writeSectionContent(SHeader, *S, CBA);
902      } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Sec)) {
903        writeSectionContent(SHeader, *S, CBA);
904      } else {
905        llvm_unreachable("Unknown section type");
906      }
907  
908      LocationCounter += SHeader.sh_size;
909  
910      // Override section fields if requested.
911      overrideFields<ELFT>(Sec, SHeader);
912    }
913  }
914  
915  template <class ELFT>
assignSectionAddress(Elf_Shdr & SHeader,ELFYAML::Section * YAMLSec)916  void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader,
917                                            ELFYAML::Section *YAMLSec) {
918    if (YAMLSec && YAMLSec->Address) {
919      SHeader.sh_addr = *YAMLSec->Address;
920      LocationCounter = *YAMLSec->Address;
921      return;
922    }
923  
924    // sh_addr represents the address in the memory image of a process. Sections
925    // in a relocatable object file or non-allocatable sections do not need
926    // sh_addr assignment.
927    if (Doc.Header.Type.value == ELF::ET_REL ||
928        !(SHeader.sh_flags & ELF::SHF_ALLOC))
929      return;
930  
931    LocationCounter =
932        alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1);
933    SHeader.sh_addr = LocationCounter;
934  }
935  
findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols)936  static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) {
937    for (size_t I = 0; I < Symbols.size(); ++I)
938      if (Symbols[I].Binding.value != ELF::STB_LOCAL)
939        return I;
940    return Symbols.size();
941  }
942  
943  template <class ELFT>
944  std::vector<typename ELFT::Sym>
toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,const StringTableBuilder & Strtab)945  ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
946                               const StringTableBuilder &Strtab) {
947    std::vector<Elf_Sym> Ret;
948    Ret.resize(Symbols.size() + 1);
949  
950    size_t I = 0;
951    for (const ELFYAML::Symbol &Sym : Symbols) {
952      Elf_Sym &Symbol = Ret[++I];
953  
954      // If NameIndex, which contains the name offset, is explicitly specified, we
955      // use it. This is useful for preparing broken objects. Otherwise, we add
956      // the specified Name to the string table builder to get its offset.
957      if (Sym.StName)
958        Symbol.st_name = *Sym.StName;
959      else if (!Sym.Name.empty())
960        Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name));
961  
962      Symbol.setBindingAndType(Sym.Binding, Sym.Type);
963      if (Sym.Section)
964        Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name);
965      else if (Sym.Index)
966        Symbol.st_shndx = *Sym.Index;
967  
968      Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0));
969      Symbol.st_other = Sym.Other ? *Sym.Other : 0;
970      Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0));
971    }
972  
973    return Ret;
974  }
975  
976  template <class ELFT>
initSymtabSectionHeader(Elf_Shdr & SHeader,SymtabType STType,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)977  void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
978                                               SymtabType STType,
979                                               ContiguousBlobAccumulator &CBA,
980                                               ELFYAML::Section *YAMLSec) {
981  
982    bool IsStatic = STType == SymtabType::Static;
983    ArrayRef<ELFYAML::Symbol> Symbols;
984    if (IsStatic && Doc.Symbols)
985      Symbols = *Doc.Symbols;
986    else if (!IsStatic && Doc.DynamicSymbols)
987      Symbols = *Doc.DynamicSymbols;
988  
989    ELFYAML::RawContentSection *RawSec =
990        dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
991    if (RawSec && (RawSec->Content || RawSec->Size)) {
992      bool HasSymbolsDescription =
993          (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols);
994      if (HasSymbolsDescription) {
995        StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`");
996        if (RawSec->Content)
997          reportError("cannot specify both `Content` and " + Property +
998                      " for symbol table section '" + RawSec->Name + "'");
999        if (RawSec->Size)
1000          reportError("cannot specify both `Size` and " + Property +
1001                      " for symbol table section '" + RawSec->Name + "'");
1002        return;
1003      }
1004    }
1005  
1006    SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym");
1007  
1008    if (YAMLSec)
1009      SHeader.sh_type = YAMLSec->Type;
1010    else
1011      SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM;
1012  
1013    if (YAMLSec && YAMLSec->Flags)
1014      SHeader.sh_flags = *YAMLSec->Flags;
1015    else if (!IsStatic)
1016      SHeader.sh_flags = ELF::SHF_ALLOC;
1017  
1018    // If the symbol table section is explicitly described in the YAML
1019    // then we should set the fields requested.
1020    SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info)
1021                                               : findFirstNonGlobal(Symbols) + 1;
1022    SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8;
1023  
1024    assignSectionAddress(SHeader, YAMLSec);
1025  
1026    SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
1027                                      RawSec ? RawSec->Offset : std::nullopt);
1028  
1029    if (RawSec && (RawSec->Content || RawSec->Size)) {
1030      assert(Symbols.empty());
1031      SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);
1032      return;
1033    }
1034  
1035    std::vector<Elf_Sym> Syms =
1036        toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr);
1037    SHeader.sh_size = Syms.size() * sizeof(Elf_Sym);
1038    CBA.write((const char *)Syms.data(), SHeader.sh_size);
1039  }
1040  
1041  template <class ELFT>
initStrtabSectionHeader(Elf_Shdr & SHeader,StringRef Name,StringTableBuilder & STB,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)1042  void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
1043                                               StringTableBuilder &STB,
1044                                               ContiguousBlobAccumulator &CBA,
1045                                               ELFYAML::Section *YAMLSec) {
1046    SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name));
1047    SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB;
1048    SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;
1049  
1050    ELFYAML::RawContentSection *RawSec =
1051        dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
1052  
1053    SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
1054                                      YAMLSec ? YAMLSec->Offset : std::nullopt);
1055  
1056    if (RawSec && (RawSec->Content || RawSec->Size)) {
1057      SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);
1058    } else {
1059      if (raw_ostream *OS = CBA.getRawOS(STB.getSize()))
1060        STB.write(*OS);
1061      SHeader.sh_size = STB.getSize();
1062    }
1063  
1064    if (RawSec && RawSec->Info)
1065      SHeader.sh_info = *RawSec->Info;
1066  
1067    if (YAMLSec && YAMLSec->Flags)
1068      SHeader.sh_flags = *YAMLSec->Flags;
1069    else if (Name == ".dynstr")
1070      SHeader.sh_flags = ELF::SHF_ALLOC;
1071  
1072    assignSectionAddress(SHeader, YAMLSec);
1073  }
1074  
shouldEmitDWARF(DWARFYAML::Data & DWARF,StringRef Name)1075  static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) {
1076    SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames();
1077    return Name.consume_front(".") && DebugSecNames.count(Name);
1078  }
1079  
1080  template <class ELFT>
emitDWARF(typename ELFT::Shdr & SHeader,StringRef Name,const DWARFYAML::Data & DWARF,ContiguousBlobAccumulator & CBA)1081  Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name,
1082                               const DWARFYAML::Data &DWARF,
1083                               ContiguousBlobAccumulator &CBA) {
1084    // We are unable to predict the size of debug data, so we request to write 0
1085    // bytes. This should always return us an output stream unless CBA is already
1086    // in an error state.
1087    raw_ostream *OS = CBA.getRawOS(0);
1088    if (!OS)
1089      return 0;
1090  
1091    uint64_t BeginOffset = CBA.tell();
1092  
1093    auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1));
1094    if (Error Err = EmitFunc(*OS, DWARF))
1095      return std::move(Err);
1096  
1097    return CBA.tell() - BeginOffset;
1098  }
1099  
1100  template <class ELFT>
initDWARFSectionHeader(Elf_Shdr & SHeader,StringRef Name,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)1101  void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
1102                                              ContiguousBlobAccumulator &CBA,
1103                                              ELFYAML::Section *YAMLSec) {
1104    SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name));
1105    SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS;
1106    SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;
1107    SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
1108                                      YAMLSec ? YAMLSec->Offset : std::nullopt);
1109  
1110    ELFYAML::RawContentSection *RawSec =
1111        dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
1112    if (Doc.DWARF && shouldEmitDWARF(*Doc.DWARF, Name)) {
1113      if (RawSec && (RawSec->Content || RawSec->Size))
1114        reportError("cannot specify section '" + Name +
1115                    "' contents in the 'DWARF' entry and the 'Content' "
1116                    "or 'Size' in the 'Sections' entry at the same time");
1117      else {
1118        if (Expected<uint64_t> ShSizeOrErr =
1119                emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA))
1120          SHeader.sh_size = *ShSizeOrErr;
1121        else
1122          reportError(ShSizeOrErr.takeError());
1123      }
1124    } else if (RawSec)
1125      SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);
1126    else
1127      llvm_unreachable("debug sections can only be initialized via the 'DWARF' "
1128                       "entry or a RawContentSection");
1129  
1130    if (RawSec && RawSec->Info)
1131      SHeader.sh_info = *RawSec->Info;
1132  
1133    if (YAMLSec && YAMLSec->Flags)
1134      SHeader.sh_flags = *YAMLSec->Flags;
1135    else if (Name == ".debug_str")
1136      SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS;
1137  
1138    assignSectionAddress(SHeader, YAMLSec);
1139  }
1140  
reportError(const Twine & Msg)1141  template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
1142    ErrHandler(Msg);
1143    HasError = true;
1144  }
1145  
reportError(Error Err)1146  template <class ELFT> void ELFState<ELFT>::reportError(Error Err) {
1147    handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) {
1148      reportError(Err.message());
1149    });
1150  }
1151  
1152  template <class ELFT>
1153  std::vector<Fragment>
getPhdrFragments(const ELFYAML::ProgramHeader & Phdr,ArrayRef<Elf_Shdr> SHeaders)1154  ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,
1155                                   ArrayRef<Elf_Shdr> SHeaders) {
1156    std::vector<Fragment> Ret;
1157    for (const ELFYAML::Chunk *C : Phdr.Chunks) {
1158      if (const ELFYAML::Fill *F = dyn_cast<ELFYAML::Fill>(C)) {
1159        Ret.push_back({*F->Offset, F->Size, llvm::ELF::SHT_PROGBITS,
1160                       /*ShAddrAlign=*/1});
1161        continue;
1162      }
1163  
1164      const ELFYAML::Section *S = cast<ELFYAML::Section>(C);
1165      const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)];
1166      Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign});
1167    }
1168    return Ret;
1169  }
1170  
1171  template <class ELFT>
setProgramHeaderLayout(std::vector<Elf_Phdr> & PHeaders,std::vector<Elf_Shdr> & SHeaders)1172  void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
1173                                              std::vector<Elf_Shdr> &SHeaders) {
1174    uint32_t PhdrIdx = 0;
1175    for (auto &YamlPhdr : Doc.ProgramHeaders) {
1176      Elf_Phdr &PHeader = PHeaders[PhdrIdx++];
1177      std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders);
1178      if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) {
1179            return A.Offset < B.Offset;
1180          }))
1181        reportError("sections in the program header with index " +
1182                    Twine(PhdrIdx) + " are not sorted by their file offset");
1183  
1184      if (YamlPhdr.Offset) {
1185        if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset)
1186          reportError("'Offset' for segment with index " + Twine(PhdrIdx) +
1187                      " must be less than or equal to the minimum file offset of "
1188                      "all included sections (0x" +
1189                      Twine::utohexstr(Fragments.front().Offset) + ")");
1190        PHeader.p_offset = *YamlPhdr.Offset;
1191      } else if (!Fragments.empty()) {
1192        PHeader.p_offset = Fragments.front().Offset;
1193      }
1194  
1195      // Set the file size if not set explicitly.
1196      if (YamlPhdr.FileSize) {
1197        PHeader.p_filesz = *YamlPhdr.FileSize;
1198      } else if (!Fragments.empty()) {
1199        uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset;
1200        // SHT_NOBITS sections occupy no physical space in a file, we should not
1201        // take their sizes into account when calculating the file size of a
1202        // segment.
1203        if (Fragments.back().Type != llvm::ELF::SHT_NOBITS)
1204          FileSize += Fragments.back().Size;
1205        PHeader.p_filesz = FileSize;
1206      }
1207  
1208      // Find the maximum offset of the end of a section in order to set p_memsz.
1209      uint64_t MemOffset = PHeader.p_offset;
1210      for (const Fragment &F : Fragments)
1211        MemOffset = std::max(MemOffset, F.Offset + F.Size);
1212      // Set the memory size if not set explicitly.
1213      PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize)
1214                                         : MemOffset - PHeader.p_offset;
1215  
1216      if (YamlPhdr.Align) {
1217        PHeader.p_align = *YamlPhdr.Align;
1218      } else {
1219        // Set the alignment of the segment to be the maximum alignment of the
1220        // sections so that by default the segment has a valid and sensible
1221        // alignment.
1222        PHeader.p_align = 1;
1223        for (const Fragment &F : Fragments)
1224          PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign);
1225      }
1226    }
1227  }
1228  
shouldAllocateFileSpace(ArrayRef<ELFYAML::ProgramHeader> Phdrs,const ELFYAML::NoBitsSection & S)1229  bool llvm::ELFYAML::shouldAllocateFileSpace(
1230      ArrayRef<ELFYAML::ProgramHeader> Phdrs, const ELFYAML::NoBitsSection &S) {
1231    for (const ELFYAML::ProgramHeader &PH : Phdrs) {
1232      auto It = llvm::find_if(
1233          PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; });
1234      if (std::any_of(It, PH.Chunks.end(), [](ELFYAML::Chunk *C) {
1235            return (isa<ELFYAML::Fill>(C) ||
1236                    cast<ELFYAML::Section>(C)->Type != ELF::SHT_NOBITS);
1237          }))
1238        return true;
1239    }
1240    return false;
1241  }
1242  
1243  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::NoBitsSection & S,ContiguousBlobAccumulator & CBA)1244  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1245                                           const ELFYAML::NoBitsSection &S,
1246                                           ContiguousBlobAccumulator &CBA) {
1247    if (!S.Size)
1248      return;
1249  
1250    SHeader.sh_size = *S.Size;
1251  
1252    // When a nobits section is followed by a non-nobits section or fill
1253    // in the same segment, we allocate the file space for it. This behavior
1254    // matches linkers.
1255    if (shouldAllocateFileSpace(Doc.ProgramHeaders, S))
1256      CBA.writeZeros(*S.Size);
1257  }
1258  
1259  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RawContentSection & Section,ContiguousBlobAccumulator & CBA)1260  void ELFState<ELFT>::writeSectionContent(
1261      Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section,
1262      ContiguousBlobAccumulator &CBA) {
1263    if (Section.Info)
1264      SHeader.sh_info = *Section.Info;
1265  }
1266  
isMips64EL(const ELFYAML::Object & Obj)1267  static bool isMips64EL(const ELFYAML::Object &Obj) {
1268    return Obj.getMachine() == llvm::ELF::EM_MIPS &&
1269           Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) &&
1270           Obj.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
1271  }
1272  
1273  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RelocationSection & Section,ContiguousBlobAccumulator & CBA)1274  void ELFState<ELFT>::writeSectionContent(
1275      Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section,
1276      ContiguousBlobAccumulator &CBA) {
1277    assert((Section.Type == llvm::ELF::SHT_REL ||
1278            Section.Type == llvm::ELF::SHT_RELA ||
1279            Section.Type == llvm::ELF::SHT_CREL) &&
1280           "Section type is not SHT_REL nor SHT_RELA");
1281  
1282    if (!Section.RelocatableSec.empty())
1283      SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name);
1284  
1285    if (!Section.Relocations)
1286      return;
1287  
1288    const bool IsCrel = Section.Type == llvm::ELF::SHT_CREL;
1289    const bool IsRela = Section.Type == llvm::ELF::SHT_RELA;
1290    typename ELFT::uint OffsetMask = 8, Offset = 0, Addend = 0;
1291    uint32_t SymIdx = 0, Type = 0;
1292    uint64_t CurrentOffset = CBA.getOffset();
1293    if (IsCrel)
1294      for (const ELFYAML::Relocation &Rel : *Section.Relocations)
1295        OffsetMask |= Rel.Offset;
1296    const int Shift = llvm::countr_zero(OffsetMask);
1297    if (IsCrel)
1298      CBA.writeULEB128(Section.Relocations->size() * 8 + ELF::CREL_HDR_ADDEND +
1299                       Shift);
1300    for (const ELFYAML::Relocation &Rel : *Section.Relocations) {
1301      const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym");
1302      uint32_t CurSymIdx =
1303          Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, IsDynamic) : 0;
1304      if (IsCrel) {
1305        // The delta offset and flags member may be larger than uint64_t. Special
1306        // case the first byte (3 flag bits and 4 offset bits). Other ULEB128
1307        // bytes encode the remaining delta offset bits.
1308        auto DeltaOffset =
1309            (static_cast<typename ELFT::uint>(Rel.Offset) - Offset) >> Shift;
1310        Offset = Rel.Offset;
1311        uint8_t B =
1312            DeltaOffset * 8 + (SymIdx != CurSymIdx) + (Type != Rel.Type ? 2 : 0) +
1313            (Addend != static_cast<typename ELFT::uint>(Rel.Addend) ? 4 : 0);
1314        if (DeltaOffset < 0x10) {
1315          CBA.write(B);
1316        } else {
1317          CBA.write(B | 0x80);
1318          CBA.writeULEB128(DeltaOffset >> 4);
1319        }
1320        // Delta symidx/type/addend members (SLEB128).
1321        if (B & 1) {
1322          CBA.writeSLEB128(
1323              std::make_signed_t<typename ELFT::uint>(CurSymIdx - SymIdx));
1324          SymIdx = CurSymIdx;
1325        }
1326        if (B & 2) {
1327          CBA.writeSLEB128(static_cast<int32_t>(Rel.Type - Type));
1328          Type = Rel.Type;
1329        }
1330        if (B & 4) {
1331          CBA.writeSLEB128(
1332              std::make_signed_t<typename ELFT::uint>(Rel.Addend - Addend));
1333          Addend = Rel.Addend;
1334        }
1335      } else if (IsRela) {
1336        Elf_Rela REntry;
1337        zero(REntry);
1338        REntry.r_offset = Rel.Offset;
1339        REntry.r_addend = Rel.Addend;
1340        REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc));
1341        CBA.write((const char *)&REntry, sizeof(REntry));
1342      } else {
1343        Elf_Rel REntry;
1344        zero(REntry);
1345        REntry.r_offset = Rel.Offset;
1346        REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc));
1347        CBA.write((const char *)&REntry, sizeof(REntry));
1348      }
1349    }
1350  
1351    SHeader.sh_size = CBA.getOffset() - CurrentOffset;
1352  }
1353  
1354  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RelrSection & Section,ContiguousBlobAccumulator & CBA)1355  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1356                                           const ELFYAML::RelrSection &Section,
1357                                           ContiguousBlobAccumulator &CBA) {
1358    if (!Section.Entries)
1359      return;
1360  
1361    for (llvm::yaml::Hex64 E : *Section.Entries) {
1362      if (!ELFT::Is64Bits && E > UINT32_MAX)
1363        reportError(Section.Name + ": the value is too large for 32-bits: 0x" +
1364                    Twine::utohexstr(E));
1365      CBA.write<uintX_t>(E, ELFT::Endianness);
1366    }
1367  
1368    SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size();
1369  }
1370  
1371  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::SymtabShndxSection & Shndx,ContiguousBlobAccumulator & CBA)1372  void ELFState<ELFT>::writeSectionContent(
1373      Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,
1374      ContiguousBlobAccumulator &CBA) {
1375    if (Shndx.Content || Shndx.Size) {
1376      SHeader.sh_size = writeContent(CBA, Shndx.Content, Shndx.Size);
1377      return;
1378    }
1379  
1380    if (!Shndx.Entries)
1381      return;
1382  
1383    for (uint32_t E : *Shndx.Entries)
1384      CBA.write<uint32_t>(E, ELFT::Endianness);
1385    SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize;
1386  }
1387  
1388  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::GroupSection & Section,ContiguousBlobAccumulator & CBA)1389  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1390                                           const ELFYAML::GroupSection &Section,
1391                                           ContiguousBlobAccumulator &CBA) {
1392    assert(Section.Type == llvm::ELF::SHT_GROUP &&
1393           "Section type is not SHT_GROUP");
1394  
1395    if (Section.Signature)
1396      SHeader.sh_info =
1397          toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false);
1398  
1399    if (!Section.Members)
1400      return;
1401  
1402    for (const ELFYAML::SectionOrType &Member : *Section.Members) {
1403      unsigned int SectionIndex = 0;
1404      if (Member.sectionNameOrType == "GRP_COMDAT")
1405        SectionIndex = llvm::ELF::GRP_COMDAT;
1406      else
1407        SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name);
1408      CBA.write<uint32_t>(SectionIndex, ELFT::Endianness);
1409    }
1410    SHeader.sh_size = SHeader.sh_entsize * Section.Members->size();
1411  }
1412  
1413  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::SymverSection & Section,ContiguousBlobAccumulator & CBA)1414  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1415                                           const ELFYAML::SymverSection &Section,
1416                                           ContiguousBlobAccumulator &CBA) {
1417    if (!Section.Entries)
1418      return;
1419  
1420    for (uint16_t Version : *Section.Entries)
1421      CBA.write<uint16_t>(Version, ELFT::Endianness);
1422    SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize;
1423  }
1424  
1425  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::StackSizesSection & Section,ContiguousBlobAccumulator & CBA)1426  void ELFState<ELFT>::writeSectionContent(
1427      Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section,
1428      ContiguousBlobAccumulator &CBA) {
1429    if (!Section.Entries)
1430      return;
1431  
1432    for (const ELFYAML::StackSizeEntry &E : *Section.Entries) {
1433      CBA.write<uintX_t>(E.Address, ELFT::Endianness);
1434      SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size);
1435    }
1436  }
1437  
1438  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::BBAddrMapSection & Section,ContiguousBlobAccumulator & CBA)1439  void ELFState<ELFT>::writeSectionContent(
1440      Elf_Shdr &SHeader, const ELFYAML::BBAddrMapSection &Section,
1441      ContiguousBlobAccumulator &CBA) {
1442    if (!Section.Entries) {
1443      if (Section.PGOAnalyses)
1444        WithColor::warning()
1445            << "PGOAnalyses should not exist in SHT_LLVM_BB_ADDR_MAP when "
1446               "Entries does not exist";
1447      return;
1448    }
1449  
1450    const std::vector<ELFYAML::PGOAnalysisMapEntry> *PGOAnalyses = nullptr;
1451    if (Section.PGOAnalyses) {
1452      if (Section.Entries->size() != Section.PGOAnalyses->size())
1453        WithColor::warning() << "PGOAnalyses must be the same length as Entries "
1454                                "in SHT_LLVM_BB_ADDR_MAP";
1455      else
1456        PGOAnalyses = &Section.PGOAnalyses.value();
1457    }
1458  
1459    for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) {
1460      // Write version and feature values.
1461      if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) {
1462        if (E.Version > 2)
1463          WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "
1464                               << static_cast<int>(E.Version)
1465                               << "; encoding using the most recent version";
1466        CBA.write(E.Version);
1467        CBA.write(E.Feature);
1468        SHeader.sh_size += 2;
1469      }
1470      auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);
1471      bool MultiBBRangeFeatureEnabled = false;
1472      if (!FeatureOrErr)
1473        WithColor::warning() << toString(FeatureOrErr.takeError());
1474      else
1475        MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
1476      bool MultiBBRange =
1477          MultiBBRangeFeatureEnabled ||
1478          (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) ||
1479          (E.BBRanges && E.BBRanges->size() != 1);
1480      if (MultiBBRange && !MultiBBRangeFeatureEnabled)
1481        WithColor::warning() << "feature value(" << E.Feature
1482                             << ") does not support multiple BB ranges.";
1483      if (MultiBBRange) {
1484        // Write the number of basic block ranges, which is overridden by the
1485        // 'NumBBRanges' field when specified.
1486        uint64_t NumBBRanges =
1487            E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0);
1488        SHeader.sh_size += CBA.writeULEB128(NumBBRanges);
1489      }
1490      if (!E.BBRanges)
1491        continue;
1492      uint64_t TotalNumBlocks = 0;
1493      for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {
1494        // Write the base address of the range.
1495        CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness);
1496        // Write number of BBEntries (number of basic blocks in this basic block
1497        // range). This is overridden by the 'NumBlocks' YAML field when
1498        // specified.
1499        uint64_t NumBlocks =
1500            BBR.NumBlocks.value_or(BBR.BBEntries ? BBR.BBEntries->size() : 0);
1501        SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);
1502        // Write all BBEntries in this BBRange.
1503        if (!BBR.BBEntries)
1504          continue;
1505        for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries) {
1506          ++TotalNumBlocks;
1507          if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1)
1508            SHeader.sh_size += CBA.writeULEB128(BBE.ID);
1509          SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset);
1510          SHeader.sh_size += CBA.writeULEB128(BBE.Size);
1511          SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);
1512        }
1513      }
1514      if (!PGOAnalyses)
1515        continue;
1516      const ELFYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
1517  
1518      if (PGOEntry.FuncEntryCount)
1519        SHeader.sh_size += CBA.writeULEB128(*PGOEntry.FuncEntryCount);
1520  
1521      if (!PGOEntry.PGOBBEntries)
1522        continue;
1523  
1524      const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value();
1525      if (TotalNumBlocks != PGOBBEntries.size()) {
1526        WithColor::warning() << "PBOBBEntries must be the same length as "
1527                                "BBEntries in SHT_LLVM_BB_ADDR_MAP.\n"
1528                             << "Mismatch on function with address: "
1529                             << E.getFunctionAddress();
1530        continue;
1531      }
1532  
1533      for (const auto &PGOBBE : PGOBBEntries) {
1534        if (PGOBBE.BBFreq)
1535          SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq);
1536        if (PGOBBE.Successors) {
1537          SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size());
1538          for (const auto &[ID, BrProb] : *PGOBBE.Successors) {
1539            SHeader.sh_size += CBA.writeULEB128(ID);
1540            SHeader.sh_size += CBA.writeULEB128(BrProb);
1541          }
1542        }
1543      }
1544    }
1545  }
1546  
1547  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::LinkerOptionsSection & Section,ContiguousBlobAccumulator & CBA)1548  void ELFState<ELFT>::writeSectionContent(
1549      Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section,
1550      ContiguousBlobAccumulator &CBA) {
1551    if (!Section.Options)
1552      return;
1553  
1554    for (const ELFYAML::LinkerOption &LO : *Section.Options) {
1555      CBA.write(LO.Key.data(), LO.Key.size());
1556      CBA.write('\0');
1557      CBA.write(LO.Value.data(), LO.Value.size());
1558      CBA.write('\0');
1559      SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2);
1560    }
1561  }
1562  
1563  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::DependentLibrariesSection & Section,ContiguousBlobAccumulator & CBA)1564  void ELFState<ELFT>::writeSectionContent(
1565      Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section,
1566      ContiguousBlobAccumulator &CBA) {
1567    if (!Section.Libs)
1568      return;
1569  
1570    for (StringRef Lib : *Section.Libs) {
1571      CBA.write(Lib.data(), Lib.size());
1572      CBA.write('\0');
1573      SHeader.sh_size += Lib.size() + 1;
1574    }
1575  }
1576  
1577  template <class ELFT>
1578  uint64_t
alignToOffset(ContiguousBlobAccumulator & CBA,uint64_t Align,std::optional<llvm::yaml::Hex64> Offset)1579  ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
1580                                std::optional<llvm::yaml::Hex64> Offset) {
1581    uint64_t CurrentOffset = CBA.getOffset();
1582    uint64_t AlignedOffset;
1583  
1584    if (Offset) {
1585      if ((uint64_t)*Offset < CurrentOffset) {
1586        reportError("the 'Offset' value (0x" +
1587                    Twine::utohexstr((uint64_t)*Offset) + ") goes backward");
1588        return CurrentOffset;
1589      }
1590  
1591      // We ignore an alignment when an explicit offset has been requested.
1592      AlignedOffset = *Offset;
1593    } else {
1594      AlignedOffset = alignTo(CurrentOffset, std::max(Align, (uint64_t)1));
1595    }
1596  
1597    CBA.writeZeros(AlignedOffset - CurrentOffset);
1598    return AlignedOffset;
1599  }
1600  
1601  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::CallGraphProfileSection & Section,ContiguousBlobAccumulator & CBA)1602  void ELFState<ELFT>::writeSectionContent(
1603      Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section,
1604      ContiguousBlobAccumulator &CBA) {
1605    if (!Section.Entries)
1606      return;
1607  
1608    for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) {
1609      CBA.write<uint64_t>(E.Weight, ELFT::Endianness);
1610      SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>);
1611    }
1612  }
1613  
1614  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::HashSection & Section,ContiguousBlobAccumulator & CBA)1615  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1616                                           const ELFYAML::HashSection &Section,
1617                                           ContiguousBlobAccumulator &CBA) {
1618    if (!Section.Bucket)
1619      return;
1620  
1621    CBA.write<uint32_t>(
1622        Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())),
1623        ELFT::Endianness);
1624    CBA.write<uint32_t>(
1625        Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())),
1626        ELFT::Endianness);
1627  
1628    for (uint32_t Val : *Section.Bucket)
1629      CBA.write<uint32_t>(Val, ELFT::Endianness);
1630    for (uint32_t Val : *Section.Chain)
1631      CBA.write<uint32_t>(Val, ELFT::Endianness);
1632  
1633    SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4;
1634  }
1635  
1636  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::VerdefSection & Section,ContiguousBlobAccumulator & CBA)1637  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1638                                           const ELFYAML::VerdefSection &Section,
1639                                           ContiguousBlobAccumulator &CBA) {
1640  
1641    if (Section.Info)
1642      SHeader.sh_info = *Section.Info;
1643    else if (Section.Entries)
1644      SHeader.sh_info = Section.Entries->size();
1645  
1646    if (!Section.Entries)
1647      return;
1648  
1649    uint64_t AuxCnt = 0;
1650    for (size_t I = 0; I < Section.Entries->size(); ++I) {
1651      const ELFYAML::VerdefEntry &E = (*Section.Entries)[I];
1652  
1653      Elf_Verdef VerDef;
1654      VerDef.vd_version = E.Version.value_or(1);
1655      VerDef.vd_flags = E.Flags.value_or(0);
1656      VerDef.vd_ndx = E.VersionNdx.value_or(0);
1657      VerDef.vd_hash = E.Hash.value_or(0);
1658      VerDef.vd_aux = sizeof(Elf_Verdef);
1659      VerDef.vd_cnt = E.VerNames.size();
1660      if (I == Section.Entries->size() - 1)
1661        VerDef.vd_next = 0;
1662      else
1663        VerDef.vd_next =
1664            sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux);
1665      CBA.write((const char *)&VerDef, sizeof(Elf_Verdef));
1666  
1667      for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) {
1668        Elf_Verdaux VernAux;
1669        VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]);
1670        if (J == E.VerNames.size() - 1)
1671          VernAux.vda_next = 0;
1672        else
1673          VernAux.vda_next = sizeof(Elf_Verdaux);
1674        CBA.write((const char *)&VernAux, sizeof(Elf_Verdaux));
1675      }
1676    }
1677  
1678    SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) +
1679                      AuxCnt * sizeof(Elf_Verdaux);
1680  }
1681  
1682  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::VerneedSection & Section,ContiguousBlobAccumulator & CBA)1683  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1684                                           const ELFYAML::VerneedSection &Section,
1685                                           ContiguousBlobAccumulator &CBA) {
1686    if (Section.Info)
1687      SHeader.sh_info = *Section.Info;
1688    else if (Section.VerneedV)
1689      SHeader.sh_info = Section.VerneedV->size();
1690  
1691    if (!Section.VerneedV)
1692      return;
1693  
1694    uint64_t AuxCnt = 0;
1695    for (size_t I = 0; I < Section.VerneedV->size(); ++I) {
1696      const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I];
1697  
1698      Elf_Verneed VerNeed;
1699      VerNeed.vn_version = VE.Version;
1700      VerNeed.vn_file = DotDynstr.getOffset(VE.File);
1701      if (I == Section.VerneedV->size() - 1)
1702        VerNeed.vn_next = 0;
1703      else
1704        VerNeed.vn_next =
1705            sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux);
1706      VerNeed.vn_cnt = VE.AuxV.size();
1707      VerNeed.vn_aux = sizeof(Elf_Verneed);
1708      CBA.write((const char *)&VerNeed, sizeof(Elf_Verneed));
1709  
1710      for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) {
1711        const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J];
1712  
1713        Elf_Vernaux VernAux;
1714        VernAux.vna_hash = VAuxE.Hash;
1715        VernAux.vna_flags = VAuxE.Flags;
1716        VernAux.vna_other = VAuxE.Other;
1717        VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name);
1718        if (J == VE.AuxV.size() - 1)
1719          VernAux.vna_next = 0;
1720        else
1721          VernAux.vna_next = sizeof(Elf_Vernaux);
1722        CBA.write((const char *)&VernAux, sizeof(Elf_Vernaux));
1723      }
1724    }
1725  
1726    SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) +
1727                      AuxCnt * sizeof(Elf_Vernaux);
1728  }
1729  
1730  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::ARMIndexTableSection & Section,ContiguousBlobAccumulator & CBA)1731  void ELFState<ELFT>::writeSectionContent(
1732      Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section,
1733      ContiguousBlobAccumulator &CBA) {
1734    if (!Section.Entries)
1735      return;
1736  
1737    for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) {
1738      CBA.write<uint32_t>(E.Offset, ELFT::Endianness);
1739      CBA.write<uint32_t>(E.Value, ELFT::Endianness);
1740    }
1741    SHeader.sh_size = Section.Entries->size() * 8;
1742  }
1743  
1744  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::MipsABIFlags & Section,ContiguousBlobAccumulator & CBA)1745  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1746                                           const ELFYAML::MipsABIFlags &Section,
1747                                           ContiguousBlobAccumulator &CBA) {
1748    assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS &&
1749           "Section type is not SHT_MIPS_ABIFLAGS");
1750  
1751    object::Elf_Mips_ABIFlags<ELFT> Flags;
1752    zero(Flags);
1753    SHeader.sh_size = SHeader.sh_entsize;
1754  
1755    Flags.version = Section.Version;
1756    Flags.isa_level = Section.ISALevel;
1757    Flags.isa_rev = Section.ISARevision;
1758    Flags.gpr_size = Section.GPRSize;
1759    Flags.cpr1_size = Section.CPR1Size;
1760    Flags.cpr2_size = Section.CPR2Size;
1761    Flags.fp_abi = Section.FpABI;
1762    Flags.isa_ext = Section.ISAExtension;
1763    Flags.ases = Section.ASEs;
1764    Flags.flags1 = Section.Flags1;
1765    Flags.flags2 = Section.Flags2;
1766    CBA.write((const char *)&Flags, sizeof(Flags));
1767  }
1768  
1769  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::DynamicSection & Section,ContiguousBlobAccumulator & CBA)1770  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1771                                           const ELFYAML::DynamicSection &Section,
1772                                           ContiguousBlobAccumulator &CBA) {
1773    assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
1774           "Section type is not SHT_DYNAMIC");
1775  
1776    if (!Section.Entries)
1777      return;
1778  
1779    for (const ELFYAML::DynamicEntry &DE : *Section.Entries) {
1780      CBA.write<uintX_t>(DE.Tag, ELFT::Endianness);
1781      CBA.write<uintX_t>(DE.Val, ELFT::Endianness);
1782    }
1783    SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size();
1784  }
1785  
1786  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::AddrsigSection & Section,ContiguousBlobAccumulator & CBA)1787  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1788                                           const ELFYAML::AddrsigSection &Section,
1789                                           ContiguousBlobAccumulator &CBA) {
1790    if (!Section.Symbols)
1791      return;
1792  
1793    for (StringRef Sym : *Section.Symbols)
1794      SHeader.sh_size +=
1795          CBA.writeULEB128(toSymbolIndex(Sym, Section.Name, /*IsDynamic=*/false));
1796  }
1797  
1798  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::NoteSection & Section,ContiguousBlobAccumulator & CBA)1799  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1800                                           const ELFYAML::NoteSection &Section,
1801                                           ContiguousBlobAccumulator &CBA) {
1802    if (!Section.Notes)
1803      return;
1804  
1805    uint64_t Offset = CBA.tell();
1806    for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
1807      // Write name size.
1808      if (NE.Name.empty())
1809        CBA.write<uint32_t>(0, ELFT::Endianness);
1810      else
1811        CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::Endianness);
1812  
1813      // Write description size.
1814      if (NE.Desc.binary_size() == 0)
1815        CBA.write<uint32_t>(0, ELFT::Endianness);
1816      else
1817        CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::Endianness);
1818  
1819      // Write type.
1820      CBA.write<uint32_t>(NE.Type, ELFT::Endianness);
1821  
1822      // Write name, null terminator and padding.
1823      if (!NE.Name.empty()) {
1824        CBA.write(NE.Name.data(), NE.Name.size());
1825        CBA.write('\0');
1826        CBA.padToAlignment(4);
1827      }
1828  
1829      // Write description and padding.
1830      if (NE.Desc.binary_size() != 0) {
1831        CBA.writeAsBinary(NE.Desc);
1832        CBA.padToAlignment(4);
1833      }
1834    }
1835  
1836    SHeader.sh_size = CBA.tell() - Offset;
1837  }
1838  
1839  template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::GnuHashSection & Section,ContiguousBlobAccumulator & CBA)1840  void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1841                                           const ELFYAML::GnuHashSection &Section,
1842                                           ContiguousBlobAccumulator &CBA) {
1843    if (!Section.HashBuckets)
1844      return;
1845  
1846    if (!Section.Header)
1847      return;
1848  
1849    // We write the header first, starting with the hash buckets count. Normally
1850    // it is the number of entries in HashBuckets, but the "NBuckets" property can
1851    // be used to override this field, which is useful for producing broken
1852    // objects.
1853    if (Section.Header->NBuckets)
1854      CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::Endianness);
1855    else
1856      CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::Endianness);
1857  
1858    // Write the index of the first symbol in the dynamic symbol table accessible
1859    // via the hash table.
1860    CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::Endianness);
1861  
1862    // Write the number of words in the Bloom filter. As above, the "MaskWords"
1863    // property can be used to set this field to any value.
1864    if (Section.Header->MaskWords)
1865      CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::Endianness);
1866    else
1867      CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::Endianness);
1868  
1869    // Write the shift constant used by the Bloom filter.
1870    CBA.write<uint32_t>(Section.Header->Shift2, ELFT::Endianness);
1871  
1872    // We've finished writing the header. Now write the Bloom filter.
1873    for (llvm::yaml::Hex64 Val : *Section.BloomFilter)
1874      CBA.write<uintX_t>(Val, ELFT::Endianness);
1875  
1876    // Write an array of hash buckets.
1877    for (llvm::yaml::Hex32 Val : *Section.HashBuckets)
1878      CBA.write<uint32_t>(Val, ELFT::Endianness);
1879  
1880    // Write an array of hash values.
1881    for (llvm::yaml::Hex32 Val : *Section.HashValues)
1882      CBA.write<uint32_t>(Val, ELFT::Endianness);
1883  
1884    SHeader.sh_size = 16 /*Header size*/ +
1885                      Section.BloomFilter->size() * sizeof(typename ELFT::uint) +
1886                      Section.HashBuckets->size() * 4 +
1887                      Section.HashValues->size() * 4;
1888  }
1889  
1890  template <class ELFT>
writeFill(ELFYAML::Fill & Fill,ContiguousBlobAccumulator & CBA)1891  void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill,
1892                                 ContiguousBlobAccumulator &CBA) {
1893    size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0;
1894    if (!PatternSize) {
1895      CBA.writeZeros(Fill.Size);
1896      return;
1897    }
1898  
1899    // Fill the content with the specified pattern.
1900    uint64_t Written = 0;
1901    for (; Written + PatternSize <= Fill.Size; Written += PatternSize)
1902      CBA.writeAsBinary(*Fill.Pattern);
1903    CBA.writeAsBinary(*Fill.Pattern, Fill.Size - Written);
1904  }
1905  
1906  template <class ELFT>
buildSectionHeaderReorderMap()1907  DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {
1908    const ELFYAML::SectionHeaderTable &SectionHeaders =
1909        Doc.getSectionHeaderTable();
1910    if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders ||
1911        SectionHeaders.isDefault())
1912      return DenseMap<StringRef, size_t>();
1913  
1914    DenseMap<StringRef, size_t> Ret;
1915    size_t SecNdx = 0;
1916    StringSet<> Seen;
1917  
1918    auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) {
1919      if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second)
1920        reportError("repeated section name: '" + Hdr.Name +
1921                    "' in the section header description");
1922      Seen.insert(Hdr.Name);
1923    };
1924  
1925    if (SectionHeaders.Sections)
1926      for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections)
1927        AddSection(Hdr);
1928  
1929    if (SectionHeaders.Excluded)
1930      for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
1931        AddSection(Hdr);
1932  
1933    for (const ELFYAML::Section *S : Doc.getSections()) {
1934      // Ignore special first SHT_NULL section.
1935      if (S == Doc.getSections().front())
1936        continue;
1937      if (!Seen.count(S->Name))
1938        reportError("section '" + S->Name +
1939                    "' should be present in the 'Sections' or 'Excluded' lists");
1940      Seen.erase(S->Name);
1941    }
1942  
1943    for (const auto &It : Seen)
1944      reportError("section header contains undefined section '" + It.getKey() +
1945                  "'");
1946    return Ret;
1947  }
1948  
buildSectionIndex()1949  template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
1950    // A YAML description can have an explicit section header declaration that
1951    // allows to change the order of section headers.
1952    DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap();
1953  
1954    if (HasError)
1955      return;
1956  
1957    // Build excluded section headers map.
1958    std::vector<ELFYAML::Section *> Sections = Doc.getSections();
1959    const ELFYAML::SectionHeaderTable &SectionHeaders =
1960        Doc.getSectionHeaderTable();
1961    if (SectionHeaders.Excluded)
1962      for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
1963        if (!ExcludedSectionHeaders.insert(Hdr.Name).second)
1964          llvm_unreachable("buildSectionIndex() failed");
1965  
1966    if (SectionHeaders.NoHeaders.value_or(false))
1967      for (const ELFYAML::Section *S : Sections)
1968        if (!ExcludedSectionHeaders.insert(S->Name).second)
1969          llvm_unreachable("buildSectionIndex() failed");
1970  
1971    size_t SecNdx = -1;
1972    for (const ELFYAML::Section *S : Sections) {
1973      ++SecNdx;
1974  
1975      size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name);
1976      if (!SN2I.addName(S->Name, Index))
1977        llvm_unreachable("buildSectionIndex() failed");
1978  
1979      if (!ExcludedSectionHeaders.count(S->Name))
1980        ShStrtabStrings->add(ELFYAML::dropUniqueSuffix(S->Name));
1981    }
1982  }
1983  
buildSymbolIndexes()1984  template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() {
1985    auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) {
1986      for (size_t I = 0, S = V.size(); I < S; ++I) {
1987        const ELFYAML::Symbol &Sym = V[I];
1988        if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1))
1989          reportError("repeated symbol name: '" + Sym.Name + "'");
1990      }
1991    };
1992  
1993    if (Doc.Symbols)
1994      Build(*Doc.Symbols, SymN2I);
1995    if (Doc.DynamicSymbols)
1996      Build(*Doc.DynamicSymbols, DynSymN2I);
1997  }
1998  
finalizeStrings()1999  template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
2000    // Add the regular symbol names to .strtab section.
2001    if (Doc.Symbols)
2002      for (const ELFYAML::Symbol &Sym : *Doc.Symbols)
2003        DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name));
2004    DotStrtab.finalize();
2005  
2006    // Add the dynamic symbol names to .dynstr section.
2007    if (Doc.DynamicSymbols)
2008      for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols)
2009        DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name));
2010  
2011    // SHT_GNU_verdef and SHT_GNU_verneed sections might also
2012    // add strings to .dynstr section.
2013    for (const ELFYAML::Chunk *Sec : Doc.getSections()) {
2014      if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec)) {
2015        if (VerNeed->VerneedV) {
2016          for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) {
2017            DotDynstr.add(VE.File);
2018            for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
2019              DotDynstr.add(Aux.Name);
2020          }
2021        }
2022      } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec)) {
2023        if (VerDef->Entries)
2024          for (const ELFYAML::VerdefEntry &E : *VerDef->Entries)
2025            for (StringRef Name : E.VerNames)
2026              DotDynstr.add(Name);
2027      }
2028    }
2029  
2030    DotDynstr.finalize();
2031  
2032    // Don't finalize the section header string table a second time if it has
2033    // already been finalized due to being one of the symbol string tables.
2034    if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
2035      ShStrtabStrings->finalize();
2036  }
2037  
2038  template <class ELFT>
writeELF(raw_ostream & OS,ELFYAML::Object & Doc,yaml::ErrorHandler EH,uint64_t MaxSize)2039  bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
2040                                yaml::ErrorHandler EH, uint64_t MaxSize) {
2041    ELFState<ELFT> State(Doc, EH);
2042    if (State.HasError)
2043      return false;
2044  
2045    // Build the section index, which adds sections to the section header string
2046    // table first, so that we can finalize the section header string table.
2047    State.buildSectionIndex();
2048    State.buildSymbolIndexes();
2049  
2050    // Finalize section header string table and the .strtab and .dynstr sections.
2051    // We do this early because we want to finalize the string table builders
2052    // before writing the content of the sections that might want to use them.
2053    State.finalizeStrings();
2054  
2055    if (State.HasError)
2056      return false;
2057  
2058    std::vector<Elf_Phdr> PHeaders;
2059    State.initProgramHeaders(PHeaders);
2060  
2061    // XXX: This offset is tightly coupled with the order that we write
2062    // things to `OS`.
2063    const size_t SectionContentBeginOffset =
2064        sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
2065    // It is quite easy to accidentally create output with yaml2obj that is larger
2066    // than intended, for example, due to an issue in the YAML description.
2067    // We limit the maximum allowed output size, but also provide a command line
2068    // option to change this limitation.
2069    ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);
2070  
2071    std::vector<Elf_Shdr> SHeaders;
2072    State.initSectionHeaders(SHeaders, CBA);
2073  
2074    // Now we can decide segment offsets.
2075    State.setProgramHeaderLayout(PHeaders, SHeaders);
2076  
2077    bool ReachedLimit = CBA.getOffset() > MaxSize;
2078    if (Error E = CBA.takeLimitError()) {
2079      // We report a custom error message instead below.
2080      consumeError(std::move(E));
2081      ReachedLimit = true;
2082    }
2083  
2084    if (ReachedLimit)
2085      State.reportError(
2086          "the desired output size is greater than permitted. Use the "
2087          "--max-size option to change the limit");
2088  
2089    if (State.HasError)
2090      return false;
2091  
2092    State.writeELFHeader(OS);
2093    writeArrayData(OS, ArrayRef(PHeaders));
2094  
2095    const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable();
2096    if (!SHT.NoHeaders.value_or(false))
2097      CBA.updateDataAt(*SHT.Offset, SHeaders.data(),
2098                       SHT.getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr));
2099  
2100    CBA.writeBlobToStream(OS);
2101    return true;
2102  }
2103  
2104  namespace llvm {
2105  namespace yaml {
2106  
yaml2elf(llvm::ELFYAML::Object & Doc,raw_ostream & Out,ErrorHandler EH,uint64_t MaxSize)2107  bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH,
2108                uint64_t MaxSize) {
2109    bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
2110    bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
2111    if (Is64Bit) {
2112      if (IsLE)
2113        return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize);
2114      return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize);
2115    }
2116    if (IsLE)
2117      return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize);
2118    return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH, MaxSize);
2119  }
2120  
2121  } // namespace yaml
2122  } // namespace llvm
2123