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