xref: /llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h (revision 60972a893e2bf915f6ff043c9396dea9619456fb)
1 //===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
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 /// This file declares classes for handling the YAML representation
11 /// of ELF.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_OBJECTYAML_ELFYAML_H
16 #define LLVM_OBJECTYAML_ELFYAML_H
17 
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/Object/ELFTypes.h"
21 #include "llvm/ObjectYAML/DWARFYAML.h"
22 #include "llvm/ObjectYAML/YAML.h"
23 #include "llvm/Support/YAMLTraits.h"
24 #include <cstdint>
25 #include <memory>
26 #include <optional>
27 #include <vector>
28 
29 namespace llvm {
30 namespace ELFYAML {
31 
32 StringRef dropUniqueSuffix(StringRef S);
33 std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
34 
35 // These types are invariant across 32/64-bit ELF, so for simplicity just
36 // directly give them their exact sizes. We don't need to worry about
37 // endianness because these are just the types in the YAMLIO structures,
38 // and are appropriately converted to the necessary endianness when
39 // reading/generating binary object files.
40 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
41 // the common prefix of the respective constants. E.g. ELF_EM corresponds
42 // to the `e_machine` constants, like `EM_X86_64`.
43 // In the future, these would probably be better suited by C++11 enum
44 // class's with appropriate fixed underlying type.
45 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
46 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
47 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
48 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
49 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
50 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
51 // Just use 64, since it can hold 32-bit values too.
52 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
53 // Just use 64, since it can hold 32-bit values too.
54 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
55 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
56 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
57 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
59 // Just use 64, since it can hold 32-bit values too.
60 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
61 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
62 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
63 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
64 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)
65 
66 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
67 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
68 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
69 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
70 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
71 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
72 
73 LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
74 LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
75 
76 template <class ELFT>
77 unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
78                              StringRef SecName) {
79   if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
80     return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
81 
82   switch (SecType) {
83   case ELF::SHT_SYMTAB:
84   case ELF::SHT_DYNSYM:
85     return sizeof(typename ELFT::Sym);
86   case ELF::SHT_GROUP:
87     return sizeof(typename ELFT::Word);
88   case ELF::SHT_REL:
89     return sizeof(typename ELFT::Rel);
90   case ELF::SHT_RELA:
91     return sizeof(typename ELFT::Rela);
92   case ELF::SHT_RELR:
93     return sizeof(typename ELFT::Relr);
94   case ELF::SHT_DYNAMIC:
95     return sizeof(typename ELFT::Dyn);
96   case ELF::SHT_HASH:
97     return sizeof(typename ELFT::Word);
98   case ELF::SHT_SYMTAB_SHNDX:
99     return sizeof(typename ELFT::Word);
100   case ELF::SHT_GNU_versym:
101     return sizeof(typename ELFT::Half);
102   case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
103     return sizeof(object::Elf_CGProfile_Impl<ELFT>);
104   default:
105     if (SecName == ".debug_str")
106       return 1;
107     return 0;
108   }
109 }
110 
111 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
112 // since 64-bit can hold 32-bit values too.
113 struct FileHeader {
114   ELF_ELFCLASS Class;
115   ELF_ELFDATA Data;
116   ELF_ELFOSABI OSABI;
117   llvm::yaml::Hex8 ABIVersion;
118   ELF_ET Type;
119   std::optional<ELF_EM> Machine;
120   ELF_EF Flags;
121   llvm::yaml::Hex64 Entry;
122   std::optional<StringRef> SectionHeaderStringTable;
123 
124   std::optional<llvm::yaml::Hex64> EPhOff;
125   std::optional<llvm::yaml::Hex16> EPhEntSize;
126   std::optional<llvm::yaml::Hex16> EPhNum;
127   std::optional<llvm::yaml::Hex16> EShEntSize;
128   std::optional<llvm::yaml::Hex64> EShOff;
129   std::optional<llvm::yaml::Hex16> EShNum;
130   std::optional<llvm::yaml::Hex16> EShStrNdx;
131 };
132 
133 struct SectionHeader {
134   StringRef Name;
135 };
136 
137 struct Symbol {
138   StringRef Name;
139   ELF_STT Type;
140   std::optional<StringRef> Section;
141   std::optional<ELF_SHN> Index;
142   ELF_STB Binding;
143   std::optional<llvm::yaml::Hex64> Value;
144   std::optional<llvm::yaml::Hex64> Size;
145   std::optional<uint8_t> Other;
146 
147   std::optional<uint32_t> StName;
148 };
149 
150 struct SectionOrType {
151   StringRef sectionNameOrType;
152 };
153 
154 struct DynamicEntry {
155   ELF_DYNTAG Tag;
156   llvm::yaml::Hex64 Val;
157 };
158 
159 struct BBAddrMapEntry {
160   struct BBEntry {
161     uint32_t ID;
162     llvm::yaml::Hex64 AddressOffset;
163     llvm::yaml::Hex64 Size;
164     llvm::yaml::Hex64 Metadata;
165   };
166   uint8_t Version;
167   llvm::yaml::Hex8 Feature;
168 
169   struct BBRangeEntry {
170     llvm::yaml::Hex64 BaseAddress;
171     std::optional<uint64_t> NumBlocks;
172     std::optional<std::vector<BBEntry>> BBEntries;
173   };
174 
175   std::optional<uint64_t> NumBBRanges;
176   std::optional<std::vector<BBRangeEntry>> BBRanges;
177 
178   llvm::yaml::Hex64 getFunctionAddress() const {
179     if (!BBRanges || BBRanges->empty())
180       return 0;
181     return BBRanges->front().BaseAddress;
182   }
183 };
184 
185 struct PGOAnalysisMapEntry {
186   struct PGOBBEntry {
187     struct SuccessorEntry {
188       uint32_t ID;
189       llvm::yaml::Hex32 BrProb;
190     };
191     std::optional<uint64_t> BBFreq;
192     std::optional<std::vector<SuccessorEntry>> Successors;
193   };
194   std::optional<uint64_t> FuncEntryCount;
195   std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
196 };
197 
198 struct StackSizeEntry {
199   llvm::yaml::Hex64 Address;
200   llvm::yaml::Hex64 Size;
201 };
202 
203 struct NoteEntry {
204   StringRef Name;
205   yaml::BinaryRef Desc;
206   ELF_NT Type;
207 };
208 
209 struct Chunk {
210   enum class ChunkKind {
211     Dynamic,
212     Group,
213     RawContent,
214     Relocation,
215     Relr,
216     NoBits,
217     Note,
218     Hash,
219     GnuHash,
220     Verdef,
221     Verneed,
222     StackSizes,
223     SymtabShndxSection,
224     Symver,
225     ARMIndexTable,
226     MipsABIFlags,
227     Addrsig,
228     LinkerOptions,
229     DependentLibraries,
230     CallGraphProfile,
231     BBAddrMap,
232 
233     // Special chunks.
234     SpecialChunksStart,
235     Fill = SpecialChunksStart,
236     SectionHeaderTable,
237   };
238 
239   ChunkKind Kind;
240   StringRef Name;
241   std::optional<llvm::yaml::Hex64> Offset;
242 
243   // Usually chunks are not created implicitly, but rather loaded from YAML.
244   // This flag is used to signal whether this is the case or not.
245   bool IsImplicit;
246 
247   Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
248   virtual ~Chunk();
249 };
250 
251 struct Section : public Chunk {
252   ELF_SHT Type;
253   std::optional<ELF_SHF> Flags;
254   std::optional<llvm::yaml::Hex64> Address;
255   std::optional<StringRef> Link;
256   llvm::yaml::Hex64 AddressAlign;
257   std::optional<llvm::yaml::Hex64> EntSize;
258 
259   std::optional<yaml::BinaryRef> Content;
260   std::optional<llvm::yaml::Hex64> Size;
261 
262   // Holds the original section index.
263   unsigned OriginalSecNdx;
264 
265   Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
266 
267   static bool classof(const Chunk *S) {
268     return S->Kind < ChunkKind::SpecialChunksStart;
269   }
270 
271   // Some derived sections might have their own special entries. This method
272   // returns a vector of <entry name, is used> pairs. It is used for section
273   // validation.
274   virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
275     return {};
276   };
277 
278   // The following members are used to override section fields which is
279   // useful for creating invalid objects.
280 
281   // This can be used to override the sh_addralign field.
282   std::optional<llvm::yaml::Hex64> ShAddrAlign;
283 
284   // This can be used to override the offset stored in the sh_name field.
285   // It does not affect the name stored in the string table.
286   std::optional<llvm::yaml::Hex64> ShName;
287 
288   // This can be used to override the sh_offset field. It does not place the
289   // section data at the offset specified.
290   std::optional<llvm::yaml::Hex64> ShOffset;
291 
292   // This can be used to override the sh_size field. It does not affect the
293   // content written.
294   std::optional<llvm::yaml::Hex64> ShSize;
295 
296   // This can be used to override the sh_flags field.
297   std::optional<llvm::yaml::Hex64> ShFlags;
298 
299   // This can be used to override the sh_type field. It is useful when we
300   // want to use specific YAML keys for a section of a particular type to
301   // describe the content, but still want to have a different final type
302   // for the section.
303   std::optional<ELF_SHT> ShType;
304 };
305 
306 // Fill is a block of data which is placed outside of sections. It is
307 // not present in the sections header table, but it might affect the output file
308 // size and program headers produced.
309 struct Fill : Chunk {
310   std::optional<yaml::BinaryRef> Pattern;
311   llvm::yaml::Hex64 Size;
312 
313   Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
314 
315   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
316 };
317 
318 struct SectionHeaderTable : Chunk {
319   SectionHeaderTable(bool IsImplicit)
320       : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
321 
322   static bool classof(const Chunk *S) {
323     return S->Kind == ChunkKind::SectionHeaderTable;
324   }
325 
326   std::optional<std::vector<SectionHeader>> Sections;
327   std::optional<std::vector<SectionHeader>> Excluded;
328   std::optional<bool> NoHeaders;
329 
330   size_t getNumHeaders(size_t SectionsNum) const {
331     if (IsImplicit || isDefault())
332       return SectionsNum;
333     if (NoHeaders)
334       return (*NoHeaders) ? 0 : SectionsNum;
335     return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
336   }
337 
338   bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
339 
340   static constexpr StringRef TypeStr = "SectionHeaderTable";
341 };
342 
343 struct BBAddrMapSection : Section {
344   std::optional<std::vector<BBAddrMapEntry>> Entries;
345   std::optional<std::vector<PGOAnalysisMapEntry>> PGOAnalyses;
346 
347   BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
348 
349   std::vector<std::pair<StringRef, bool>> getEntries() const override {
350     return {{"Entries", Entries.has_value()}};
351   };
352 
353   static bool classof(const Chunk *S) {
354     return S->Kind == ChunkKind::BBAddrMap;
355   }
356 };
357 
358 struct StackSizesSection : Section {
359   std::optional<std::vector<StackSizeEntry>> Entries;
360 
361   StackSizesSection() : Section(ChunkKind::StackSizes) {}
362 
363   std::vector<std::pair<StringRef, bool>> getEntries() const override {
364     return {{"Entries", Entries.has_value()}};
365   };
366 
367   static bool classof(const Chunk *S) {
368     return S->Kind == ChunkKind::StackSizes;
369   }
370 
371   static bool nameMatches(StringRef Name) {
372     return Name == ".stack_sizes";
373   }
374 };
375 
376 struct DynamicSection : Section {
377   std::optional<std::vector<DynamicEntry>> Entries;
378 
379   DynamicSection() : Section(ChunkKind::Dynamic) {}
380 
381   std::vector<std::pair<StringRef, bool>> getEntries() const override {
382     return {{"Entries", Entries.has_value()}};
383   };
384 
385   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
386 };
387 
388 struct RawContentSection : Section {
389   std::optional<llvm::yaml::Hex64> Info;
390 
391   RawContentSection() : Section(ChunkKind::RawContent) {}
392 
393   static bool classof(const Chunk *S) {
394     return S->Kind == ChunkKind::RawContent;
395   }
396 
397   // Is used when a content is read as an array of bytes.
398   std::optional<std::vector<uint8_t>> ContentBuf;
399 };
400 
401 struct NoBitsSection : Section {
402   NoBitsSection() : Section(ChunkKind::NoBits) {}
403 
404   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
405 };
406 
407 struct NoteSection : Section {
408   std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
409 
410   NoteSection() : Section(ChunkKind::Note) {}
411 
412   std::vector<std::pair<StringRef, bool>> getEntries() const override {
413     return {{"Notes", Notes.has_value()}};
414   };
415 
416   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
417 };
418 
419 struct HashSection : Section {
420   std::optional<std::vector<uint32_t>> Bucket;
421   std::optional<std::vector<uint32_t>> Chain;
422 
423   std::vector<std::pair<StringRef, bool>> getEntries() const override {
424     return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
425   };
426 
427   // The following members are used to override section fields.
428   // This is useful for creating invalid objects.
429   std::optional<llvm::yaml::Hex64> NBucket;
430   std::optional<llvm::yaml::Hex64> NChain;
431 
432   HashSection() : Section(ChunkKind::Hash) {}
433 
434   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
435 };
436 
437 struct GnuHashHeader {
438   // The number of hash buckets.
439   // Not used when dumping the object, but can be used to override
440   // the real number of buckets when emiting an object from a YAML document.
441   std::optional<llvm::yaml::Hex32> NBuckets;
442 
443   // Index of the first symbol in the dynamic symbol table
444   // included in the hash table.
445   llvm::yaml::Hex32 SymNdx;
446 
447   // The number of words in the Bloom filter.
448   // Not used when dumping the object, but can be used to override the real
449   // number of words in the Bloom filter when emiting an object from a YAML
450   // document.
451   std::optional<llvm::yaml::Hex32> MaskWords;
452 
453   // A shift constant used by the Bloom filter.
454   llvm::yaml::Hex32 Shift2;
455 };
456 
457 struct GnuHashSection : Section {
458   std::optional<GnuHashHeader> Header;
459   std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
460   std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
461   std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
462 
463   GnuHashSection() : Section(ChunkKind::GnuHash) {}
464 
465   std::vector<std::pair<StringRef, bool>> getEntries() const override {
466     return {{"Header", Header.has_value()},
467             {"BloomFilter", BloomFilter.has_value()},
468             {"HashBuckets", HashBuckets.has_value()},
469             {"HashValues", HashValues.has_value()}};
470   };
471 
472   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
473 };
474 
475 struct VernauxEntry {
476   uint32_t Hash;
477   uint16_t Flags;
478   uint16_t Other;
479   StringRef Name;
480 };
481 
482 struct VerneedEntry {
483   uint16_t Version;
484   StringRef File;
485   std::vector<VernauxEntry> AuxV;
486 };
487 
488 struct VerneedSection : Section {
489   std::optional<std::vector<VerneedEntry>> VerneedV;
490   std::optional<llvm::yaml::Hex64> Info;
491 
492   VerneedSection() : Section(ChunkKind::Verneed) {}
493 
494   std::vector<std::pair<StringRef, bool>> getEntries() const override {
495     return {{"Dependencies", VerneedV.has_value()}};
496   };
497 
498   static bool classof(const Chunk *S) {
499     return S->Kind == ChunkKind::Verneed;
500   }
501 };
502 
503 struct AddrsigSection : Section {
504   std::optional<std::vector<YAMLFlowString>> Symbols;
505 
506   AddrsigSection() : Section(ChunkKind::Addrsig) {}
507 
508   std::vector<std::pair<StringRef, bool>> getEntries() const override {
509     return {{"Symbols", Symbols.has_value()}};
510   };
511 
512   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
513 };
514 
515 struct LinkerOption {
516   StringRef Key;
517   StringRef Value;
518 };
519 
520 struct LinkerOptionsSection : Section {
521   std::optional<std::vector<LinkerOption>> Options;
522 
523   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
524 
525   std::vector<std::pair<StringRef, bool>> getEntries() const override {
526     return {{"Options", Options.has_value()}};
527   };
528 
529   static bool classof(const Chunk *S) {
530     return S->Kind == ChunkKind::LinkerOptions;
531   }
532 };
533 
534 struct DependentLibrariesSection : Section {
535   std::optional<std::vector<YAMLFlowString>> Libs;
536 
537   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
538 
539   std::vector<std::pair<StringRef, bool>> getEntries() const override {
540     return {{"Libraries", Libs.has_value()}};
541   };
542 
543   static bool classof(const Chunk *S) {
544     return S->Kind == ChunkKind::DependentLibraries;
545   }
546 };
547 
548 // Represents the call graph profile section entry.
549 struct CallGraphEntryWeight {
550   // The weight of the edge.
551   uint64_t Weight;
552 };
553 
554 struct CallGraphProfileSection : Section {
555   std::optional<std::vector<CallGraphEntryWeight>> Entries;
556 
557   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
558 
559   std::vector<std::pair<StringRef, bool>> getEntries() const override {
560     return {{"Entries", Entries.has_value()}};
561   };
562 
563   static bool classof(const Chunk *S) {
564     return S->Kind == ChunkKind::CallGraphProfile;
565   }
566 };
567 
568 struct SymverSection : Section {
569   std::optional<std::vector<uint16_t>> Entries;
570 
571   SymverSection() : Section(ChunkKind::Symver) {}
572 
573   std::vector<std::pair<StringRef, bool>> getEntries() const override {
574     return {{"Entries", Entries.has_value()}};
575   };
576 
577   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
578 };
579 
580 struct VerdefEntry {
581   std::optional<uint16_t> Version;
582   std::optional<uint16_t> Flags;
583   std::optional<uint16_t> VersionNdx;
584   std::optional<uint32_t> Hash;
585   std::optional<uint16_t> VDAux;
586   std::vector<StringRef> VerNames;
587 };
588 
589 struct VerdefSection : Section {
590   std::optional<std::vector<VerdefEntry>> Entries;
591   std::optional<llvm::yaml::Hex64> Info;
592 
593   VerdefSection() : Section(ChunkKind::Verdef) {}
594 
595   std::vector<std::pair<StringRef, bool>> getEntries() const override {
596     return {{"Entries", Entries.has_value()}};
597   };
598 
599   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
600 };
601 
602 struct GroupSection : Section {
603   // Members of a group contain a flag and a list of section indices
604   // that are part of the group.
605   std::optional<std::vector<SectionOrType>> Members;
606   std::optional<StringRef> Signature; /* Info */
607 
608   GroupSection() : Section(ChunkKind::Group) {}
609 
610   std::vector<std::pair<StringRef, bool>> getEntries() const override {
611     return {{"Members", Members.has_value()}};
612   };
613 
614   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
615 };
616 
617 struct Relocation {
618   llvm::yaml::Hex64 Offset;
619   YAMLIntUInt Addend;
620   ELF_REL Type;
621   std::optional<StringRef> Symbol;
622 };
623 
624 struct RelocationSection : Section {
625   std::optional<std::vector<Relocation>> Relocations;
626   StringRef RelocatableSec; /* Info */
627 
628   RelocationSection() : Section(ChunkKind::Relocation) {}
629 
630   std::vector<std::pair<StringRef, bool>> getEntries() const override {
631     return {{"Relocations", Relocations.has_value()}};
632   };
633 
634   static bool classof(const Chunk *S) {
635     return S->Kind == ChunkKind::Relocation;
636   }
637 };
638 
639 struct RelrSection : Section {
640   std::optional<std::vector<llvm::yaml::Hex64>> Entries;
641 
642   RelrSection() : Section(ChunkKind::Relr) {}
643 
644   std::vector<std::pair<StringRef, bool>> getEntries() const override {
645     return {{"Entries", Entries.has_value()}};
646   };
647 
648   static bool classof(const Chunk *S) {
649     return S->Kind == ChunkKind::Relr;
650   }
651 };
652 
653 struct SymtabShndxSection : Section {
654   std::optional<std::vector<uint32_t>> Entries;
655 
656   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
657 
658   std::vector<std::pair<StringRef, bool>> getEntries() const override {
659     return {{"Entries", Entries.has_value()}};
660   };
661 
662   static bool classof(const Chunk *S) {
663     return S->Kind == ChunkKind::SymtabShndxSection;
664   }
665 };
666 
667 struct ARMIndexTableEntry {
668   llvm::yaml::Hex32 Offset;
669   llvm::yaml::Hex32 Value;
670 };
671 
672 struct ARMIndexTableSection : Section {
673   std::optional<std::vector<ARMIndexTableEntry>> Entries;
674 
675   ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
676 
677   std::vector<std::pair<StringRef, bool>> getEntries() const override {
678     return {{"Entries", Entries.has_value()}};
679   };
680 
681   static bool classof(const Chunk *S) {
682     return S->Kind == ChunkKind::ARMIndexTable;
683   }
684 };
685 
686 // Represents .MIPS.abiflags section
687 struct MipsABIFlags : Section {
688   llvm::yaml::Hex16 Version;
689   MIPS_ISA ISALevel;
690   llvm::yaml::Hex8 ISARevision;
691   MIPS_AFL_REG GPRSize;
692   MIPS_AFL_REG CPR1Size;
693   MIPS_AFL_REG CPR2Size;
694   MIPS_ABI_FP FpABI;
695   MIPS_AFL_EXT ISAExtension;
696   MIPS_AFL_ASE ASEs;
697   MIPS_AFL_FLAGS1 Flags1;
698   llvm::yaml::Hex32 Flags2;
699 
700   MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
701 
702   static bool classof(const Chunk *S) {
703     return S->Kind == ChunkKind::MipsABIFlags;
704   }
705 };
706 
707 struct ProgramHeader {
708   ELF_PT Type;
709   ELF_PF Flags;
710   llvm::yaml::Hex64 VAddr;
711   llvm::yaml::Hex64 PAddr;
712   std::optional<llvm::yaml::Hex64> Align;
713   std::optional<llvm::yaml::Hex64> FileSize;
714   std::optional<llvm::yaml::Hex64> MemSize;
715   std::optional<llvm::yaml::Hex64> Offset;
716   std::optional<StringRef> FirstSec;
717   std::optional<StringRef> LastSec;
718 
719   // This vector contains all chunks from [FirstSec, LastSec].
720   std::vector<Chunk *> Chunks;
721 };
722 
723 struct Object {
724   FileHeader Header;
725   std::vector<ProgramHeader> ProgramHeaders;
726 
727   // An object might contain output section descriptions as well as
728   // custom data that does not belong to any section.
729   std::vector<std::unique_ptr<Chunk>> Chunks;
730 
731   // Although in reality the symbols reside in a section, it is a lot
732   // cleaner and nicer if we read them from the YAML as a separate
733   // top-level key, which automatically ensures that invariants like there
734   // being a single SHT_SYMTAB section are upheld.
735   std::optional<std::vector<Symbol>> Symbols;
736   std::optional<std::vector<Symbol>> DynamicSymbols;
737   std::optional<DWARFYAML::Data> DWARF;
738 
739   std::vector<Section *> getSections() {
740     std::vector<Section *> Ret;
741     for (const std::unique_ptr<Chunk> &Sec : Chunks)
742       if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
743         Ret.push_back(S);
744     return Ret;
745   }
746 
747   const SectionHeaderTable &getSectionHeaderTable() const {
748     for (const std::unique_ptr<Chunk> &C : Chunks)
749       if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
750         return *S;
751     llvm_unreachable("the section header table chunk must always be present");
752   }
753 
754   ELF_ELFOSABI getOSAbi() const;
755   unsigned getMachine() const;
756 };
757 
758 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
759                              const NoBitsSection &S);
760 
761 } // end namespace ELFYAML
762 } // end namespace llvm
763 
764 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
765 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
766 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
767 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry)
768 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
769 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
770 LLVM_YAML_IS_SEQUENCE_VECTOR(
771     llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry)
772 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
773 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
774 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
775 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
776 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
777 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
778 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
779 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
780 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
781 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
782 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
783 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
784 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
785 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
786 
787 namespace llvm {
788 namespace yaml {
789 
790 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
791   static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
792                      raw_ostream &Out);
793   static StringRef input(StringRef Scalar, void *Ctx,
794                          ELFYAML::YAMLIntUInt &Val);
795   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
796 };
797 
798 template <>
799 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
800   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
801 };
802 
803 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
804   static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
805 };
806 
807 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
808   static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
809 };
810 
811 template <>
812 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
813   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
814 };
815 
816 template <>
817 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
818   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
819 };
820 
821 template <>
822 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
823   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
824 };
825 
826 template <>
827 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
828   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
829 };
830 
831 template <>
832 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
833   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
834 };
835 
836 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
837   static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
838 };
839 
840 template <>
841 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
842   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
843 };
844 
845 template <>
846 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
847   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
848 };
849 
850 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
851   static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
852 };
853 
854 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
855   static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
856 };
857 
858 template <>
859 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
860   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
861 };
862 
863 template <>
864 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
865   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
866 };
867 
868 template <>
869 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
870   static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
871 };
872 
873 template <>
874 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
875   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
876 };
877 
878 template <>
879 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
880   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
881 };
882 
883 template <>
884 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
885   static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
886 };
887 
888 template <>
889 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
890   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
891 };
892 
893 template <>
894 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
895   static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
896 };
897 
898 template <>
899 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
900   static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
901 };
902 
903 template <>
904 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
905   static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
906 };
907 
908 template <>
909 struct MappingTraits<ELFYAML::FileHeader> {
910   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
911 };
912 
913 template <> struct MappingTraits<ELFYAML::SectionHeader> {
914   static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
915 };
916 
917 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
918   static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
919   static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
920 };
921 
922 template <>
923 struct MappingTraits<ELFYAML::Symbol> {
924   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
925   static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
926 };
927 
928 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
929   static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
930 };
931 
932 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
933   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E);
934 };
935 
936 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> {
937   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E);
938 };
939 
940 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
941   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E);
942 };
943 
944 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
945   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel);
946 };
947 
948 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> {
949   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel);
950 };
951 
952 template <>
953 struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> {
954   static void
955   mapping(IO &IO,
956           ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel);
957 };
958 
959 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
960   static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
961 };
962 
963 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
964   static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
965 };
966 
967 template <> struct MappingTraits<ELFYAML::NoteEntry> {
968   static void mapping(IO &IO, ELFYAML::NoteEntry &N);
969 };
970 
971 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
972   static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
973 };
974 
975 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
976   static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
977 };
978 
979 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
980   static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
981 };
982 
983 template <> struct MappingTraits<ELFYAML::LinkerOption> {
984   static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
985 };
986 
987 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
988   static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
989 };
990 
991 template <> struct MappingTraits<ELFYAML::Relocation> {
992   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
993 };
994 
995 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
996   static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
997 };
998 
999 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
1000   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
1001   static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
1002 };
1003 
1004 template <>
1005 struct MappingTraits<ELFYAML::Object> {
1006   static void mapping(IO &IO, ELFYAML::Object &Object);
1007 };
1008 
1009 template <> struct MappingTraits<ELFYAML::SectionOrType> {
1010   static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
1011 };
1012 
1013 } // end namespace yaml
1014 } // end namespace llvm
1015 
1016 #endif // LLVM_OBJECTYAML_ELFYAML_H
1017