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.
LLVM_YAML_STRONG_TYPEDEF(uint16_t,ELF_ET)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   llvm::yaml::Hex64 Address;
169   std::optional<uint64_t> NumBlocks;
170   std::optional<std::vector<BBEntry>> BBEntries;
171 };
172 
173 struct PGOAnalysisMapEntry {
174   struct PGOBBEntry {
175     struct SuccessorEntry {
176       uint32_t ID;
177       llvm::yaml::Hex32 BrProb;
178     };
179     std::optional<uint64_t> BBFreq;
180     std::optional<std::vector<SuccessorEntry>> Successors;
181   };
182   std::optional<uint64_t> FuncEntryCount;
183   std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
184 };
185 
186 struct StackSizeEntry {
187   llvm::yaml::Hex64 Address;
188   llvm::yaml::Hex64 Size;
189 };
190 
191 struct NoteEntry {
192   StringRef Name;
193   yaml::BinaryRef Desc;
194   ELF_NT Type;
195 };
196 
197 struct Chunk {
198   enum class ChunkKind {
199     Dynamic,
200     Group,
201     RawContent,
202     Relocation,
203     Relr,
204     NoBits,
205     Note,
206     Hash,
207     GnuHash,
208     Verdef,
209     Verneed,
210     StackSizes,
211     SymtabShndxSection,
212     Symver,
213     ARMIndexTable,
214     MipsABIFlags,
215     Addrsig,
216     LinkerOptions,
217     DependentLibraries,
218     CallGraphProfile,
219     BBAddrMap,
220 
221     // Special chunks.
222     SpecialChunksStart,
223     Fill = SpecialChunksStart,
224     SectionHeaderTable,
225   };
226 
227   ChunkKind Kind;
228   StringRef Name;
229   std::optional<llvm::yaml::Hex64> Offset;
230 
231   // Usually chunks are not created implicitly, but rather loaded from YAML.
232   // This flag is used to signal whether this is the case or not.
233   bool IsImplicit;
234 
ChunkChunk235   Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
236   virtual ~Chunk();
237 };
238 
239 struct Section : public Chunk {
240   ELF_SHT Type;
241   std::optional<ELF_SHF> Flags;
242   std::optional<llvm::yaml::Hex64> Address;
243   std::optional<StringRef> Link;
244   llvm::yaml::Hex64 AddressAlign;
245   std::optional<llvm::yaml::Hex64> EntSize;
246 
247   std::optional<yaml::BinaryRef> Content;
248   std::optional<llvm::yaml::Hex64> Size;
249 
250   // Holds the original section index.
251   unsigned OriginalSecNdx;
252 
ChunkSection253   Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
254 
classofSection255   static bool classof(const Chunk *S) {
256     return S->Kind < ChunkKind::SpecialChunksStart;
257   }
258 
259   // Some derived sections might have their own special entries. This method
260   // returns a vector of <entry name, is used> pairs. It is used for section
261   // validation.
getEntriesSection262   virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
263     return {};
264   };
265 
266   // The following members are used to override section fields which is
267   // useful for creating invalid objects.
268 
269   // This can be used to override the sh_addralign field.
270   std::optional<llvm::yaml::Hex64> ShAddrAlign;
271 
272   // This can be used to override the offset stored in the sh_name field.
273   // It does not affect the name stored in the string table.
274   std::optional<llvm::yaml::Hex64> ShName;
275 
276   // This can be used to override the sh_offset field. It does not place the
277   // section data at the offset specified.
278   std::optional<llvm::yaml::Hex64> ShOffset;
279 
280   // This can be used to override the sh_size field. It does not affect the
281   // content written.
282   std::optional<llvm::yaml::Hex64> ShSize;
283 
284   // This can be used to override the sh_flags field.
285   std::optional<llvm::yaml::Hex64> ShFlags;
286 
287   // This can be used to override the sh_type field. It is useful when we
288   // want to use specific YAML keys for a section of a particular type to
289   // describe the content, but still want to have a different final type
290   // for the section.
291   std::optional<ELF_SHT> ShType;
292 };
293 
294 // Fill is a block of data which is placed outside of sections. It is
295 // not present in the sections header table, but it might affect the output file
296 // size and program headers produced.
297 struct Fill : Chunk {
298   std::optional<yaml::BinaryRef> Pattern;
299   llvm::yaml::Hex64 Size;
300 
FillFill301   Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
302 
classofFill303   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
304 };
305 
306 struct SectionHeaderTable : Chunk {
SectionHeaderTableSectionHeaderTable307   SectionHeaderTable(bool IsImplicit)
308       : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
309 
classofSectionHeaderTable310   static bool classof(const Chunk *S) {
311     return S->Kind == ChunkKind::SectionHeaderTable;
312   }
313 
314   std::optional<std::vector<SectionHeader>> Sections;
315   std::optional<std::vector<SectionHeader>> Excluded;
316   std::optional<bool> NoHeaders;
317 
getNumHeadersSectionHeaderTable318   size_t getNumHeaders(size_t SectionsNum) const {
319     if (IsImplicit || isDefault())
320       return SectionsNum;
321     if (NoHeaders)
322       return (*NoHeaders) ? 0 : SectionsNum;
323     return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
324   }
325 
isDefaultSectionHeaderTable326   bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
327 
328   static constexpr StringRef TypeStr = "SectionHeaderTable";
329 };
330 
331 struct BBAddrMapSection : Section {
332   std::optional<std::vector<BBAddrMapEntry>> Entries;
333   std::optional<std::vector<PGOAnalysisMapEntry>> PGOAnalyses;
334 
BBAddrMapSectionBBAddrMapSection335   BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
336 
getEntriesBBAddrMapSection337   std::vector<std::pair<StringRef, bool>> getEntries() const override {
338     return {{"Entries", Entries.has_value()}};
339   };
340 
classofBBAddrMapSection341   static bool classof(const Chunk *S) {
342     return S->Kind == ChunkKind::BBAddrMap;
343   }
344 };
345 
346 struct StackSizesSection : Section {
347   std::optional<std::vector<StackSizeEntry>> Entries;
348 
StackSizesSectionStackSizesSection349   StackSizesSection() : Section(ChunkKind::StackSizes) {}
350 
getEntriesStackSizesSection351   std::vector<std::pair<StringRef, bool>> getEntries() const override {
352     return {{"Entries", Entries.has_value()}};
353   };
354 
classofStackSizesSection355   static bool classof(const Chunk *S) {
356     return S->Kind == ChunkKind::StackSizes;
357   }
358 
nameMatchesStackSizesSection359   static bool nameMatches(StringRef Name) {
360     return Name == ".stack_sizes";
361   }
362 };
363 
364 struct DynamicSection : Section {
365   std::optional<std::vector<DynamicEntry>> Entries;
366 
DynamicSectionDynamicSection367   DynamicSection() : Section(ChunkKind::Dynamic) {}
368 
getEntriesDynamicSection369   std::vector<std::pair<StringRef, bool>> getEntries() const override {
370     return {{"Entries", Entries.has_value()}};
371   };
372 
classofDynamicSection373   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
374 };
375 
376 struct RawContentSection : Section {
377   std::optional<llvm::yaml::Hex64> Info;
378 
RawContentSectionRawContentSection379   RawContentSection() : Section(ChunkKind::RawContent) {}
380 
classofRawContentSection381   static bool classof(const Chunk *S) {
382     return S->Kind == ChunkKind::RawContent;
383   }
384 
385   // Is used when a content is read as an array of bytes.
386   std::optional<std::vector<uint8_t>> ContentBuf;
387 };
388 
389 struct NoBitsSection : Section {
NoBitsSectionNoBitsSection390   NoBitsSection() : Section(ChunkKind::NoBits) {}
391 
classofNoBitsSection392   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
393 };
394 
395 struct NoteSection : Section {
396   std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
397 
NoteSectionNoteSection398   NoteSection() : Section(ChunkKind::Note) {}
399 
getEntriesNoteSection400   std::vector<std::pair<StringRef, bool>> getEntries() const override {
401     return {{"Notes", Notes.has_value()}};
402   };
403 
classofNoteSection404   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
405 };
406 
407 struct HashSection : Section {
408   std::optional<std::vector<uint32_t>> Bucket;
409   std::optional<std::vector<uint32_t>> Chain;
410 
getEntriesHashSection411   std::vector<std::pair<StringRef, bool>> getEntries() const override {
412     return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
413   };
414 
415   // The following members are used to override section fields.
416   // This is useful for creating invalid objects.
417   std::optional<llvm::yaml::Hex64> NBucket;
418   std::optional<llvm::yaml::Hex64> NChain;
419 
HashSectionHashSection420   HashSection() : Section(ChunkKind::Hash) {}
421 
classofHashSection422   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
423 };
424 
425 struct GnuHashHeader {
426   // The number of hash buckets.
427   // Not used when dumping the object, but can be used to override
428   // the real number of buckets when emiting an object from a YAML document.
429   std::optional<llvm::yaml::Hex32> NBuckets;
430 
431   // Index of the first symbol in the dynamic symbol table
432   // included in the hash table.
433   llvm::yaml::Hex32 SymNdx;
434 
435   // The number of words in the Bloom filter.
436   // Not used when dumping the object, but can be used to override the real
437   // number of words in the Bloom filter when emiting an object from a YAML
438   // document.
439   std::optional<llvm::yaml::Hex32> MaskWords;
440 
441   // A shift constant used by the Bloom filter.
442   llvm::yaml::Hex32 Shift2;
443 };
444 
445 struct GnuHashSection : Section {
446   std::optional<GnuHashHeader> Header;
447   std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
448   std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
449   std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
450 
GnuHashSectionGnuHashSection451   GnuHashSection() : Section(ChunkKind::GnuHash) {}
452 
getEntriesGnuHashSection453   std::vector<std::pair<StringRef, bool>> getEntries() const override {
454     return {{"Header", Header.has_value()},
455             {"BloomFilter", BloomFilter.has_value()},
456             {"HashBuckets", HashBuckets.has_value()},
457             {"HashValues", HashValues.has_value()}};
458   };
459 
classofGnuHashSection460   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
461 };
462 
463 struct VernauxEntry {
464   uint32_t Hash;
465   uint16_t Flags;
466   uint16_t Other;
467   StringRef Name;
468 };
469 
470 struct VerneedEntry {
471   uint16_t Version;
472   StringRef File;
473   std::vector<VernauxEntry> AuxV;
474 };
475 
476 struct VerneedSection : Section {
477   std::optional<std::vector<VerneedEntry>> VerneedV;
478   std::optional<llvm::yaml::Hex64> Info;
479 
VerneedSectionVerneedSection480   VerneedSection() : Section(ChunkKind::Verneed) {}
481 
getEntriesVerneedSection482   std::vector<std::pair<StringRef, bool>> getEntries() const override {
483     return {{"Dependencies", VerneedV.has_value()}};
484   };
485 
classofVerneedSection486   static bool classof(const Chunk *S) {
487     return S->Kind == ChunkKind::Verneed;
488   }
489 };
490 
491 struct AddrsigSection : Section {
492   std::optional<std::vector<YAMLFlowString>> Symbols;
493 
AddrsigSectionAddrsigSection494   AddrsigSection() : Section(ChunkKind::Addrsig) {}
495 
getEntriesAddrsigSection496   std::vector<std::pair<StringRef, bool>> getEntries() const override {
497     return {{"Symbols", Symbols.has_value()}};
498   };
499 
classofAddrsigSection500   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
501 };
502 
503 struct LinkerOption {
504   StringRef Key;
505   StringRef Value;
506 };
507 
508 struct LinkerOptionsSection : Section {
509   std::optional<std::vector<LinkerOption>> Options;
510 
LinkerOptionsSectionLinkerOptionsSection511   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
512 
getEntriesLinkerOptionsSection513   std::vector<std::pair<StringRef, bool>> getEntries() const override {
514     return {{"Options", Options.has_value()}};
515   };
516 
classofLinkerOptionsSection517   static bool classof(const Chunk *S) {
518     return S->Kind == ChunkKind::LinkerOptions;
519   }
520 };
521 
522 struct DependentLibrariesSection : Section {
523   std::optional<std::vector<YAMLFlowString>> Libs;
524 
DependentLibrariesSectionDependentLibrariesSection525   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
526 
getEntriesDependentLibrariesSection527   std::vector<std::pair<StringRef, bool>> getEntries() const override {
528     return {{"Libraries", Libs.has_value()}};
529   };
530 
classofDependentLibrariesSection531   static bool classof(const Chunk *S) {
532     return S->Kind == ChunkKind::DependentLibraries;
533   }
534 };
535 
536 // Represents the call graph profile section entry.
537 struct CallGraphEntryWeight {
538   // The weight of the edge.
539   uint64_t Weight;
540 };
541 
542 struct CallGraphProfileSection : Section {
543   std::optional<std::vector<CallGraphEntryWeight>> Entries;
544 
CallGraphProfileSectionCallGraphProfileSection545   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
546 
getEntriesCallGraphProfileSection547   std::vector<std::pair<StringRef, bool>> getEntries() const override {
548     return {{"Entries", Entries.has_value()}};
549   };
550 
classofCallGraphProfileSection551   static bool classof(const Chunk *S) {
552     return S->Kind == ChunkKind::CallGraphProfile;
553   }
554 };
555 
556 struct SymverSection : Section {
557   std::optional<std::vector<uint16_t>> Entries;
558 
SymverSectionSymverSection559   SymverSection() : Section(ChunkKind::Symver) {}
560 
getEntriesSymverSection561   std::vector<std::pair<StringRef, bool>> getEntries() const override {
562     return {{"Entries", Entries.has_value()}};
563   };
564 
classofSymverSection565   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
566 };
567 
568 struct VerdefEntry {
569   std::optional<uint16_t> Version;
570   std::optional<uint16_t> Flags;
571   std::optional<uint16_t> VersionNdx;
572   std::optional<uint32_t> Hash;
573   std::vector<StringRef> VerNames;
574 };
575 
576 struct VerdefSection : Section {
577   std::optional<std::vector<VerdefEntry>> Entries;
578   std::optional<llvm::yaml::Hex64> Info;
579 
VerdefSectionVerdefSection580   VerdefSection() : Section(ChunkKind::Verdef) {}
581 
getEntriesVerdefSection582   std::vector<std::pair<StringRef, bool>> getEntries() const override {
583     return {{"Entries", Entries.has_value()}};
584   };
585 
classofVerdefSection586   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
587 };
588 
589 struct GroupSection : Section {
590   // Members of a group contain a flag and a list of section indices
591   // that are part of the group.
592   std::optional<std::vector<SectionOrType>> Members;
593   std::optional<StringRef> Signature; /* Info */
594 
GroupSectionGroupSection595   GroupSection() : Section(ChunkKind::Group) {}
596 
getEntriesGroupSection597   std::vector<std::pair<StringRef, bool>> getEntries() const override {
598     return {{"Members", Members.has_value()}};
599   };
600 
classofGroupSection601   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
602 };
603 
604 struct Relocation {
605   llvm::yaml::Hex64 Offset;
606   YAMLIntUInt Addend;
607   ELF_REL Type;
608   std::optional<StringRef> Symbol;
609 };
610 
611 struct RelocationSection : Section {
612   std::optional<std::vector<Relocation>> Relocations;
613   StringRef RelocatableSec; /* Info */
614 
RelocationSectionRelocationSection615   RelocationSection() : Section(ChunkKind::Relocation) {}
616 
getEntriesRelocationSection617   std::vector<std::pair<StringRef, bool>> getEntries() const override {
618     return {{"Relocations", Relocations.has_value()}};
619   };
620 
classofRelocationSection621   static bool classof(const Chunk *S) {
622     return S->Kind == ChunkKind::Relocation;
623   }
624 };
625 
626 struct RelrSection : Section {
627   std::optional<std::vector<llvm::yaml::Hex64>> Entries;
628 
RelrSectionRelrSection629   RelrSection() : Section(ChunkKind::Relr) {}
630 
getEntriesRelrSection631   std::vector<std::pair<StringRef, bool>> getEntries() const override {
632     return {{"Entries", Entries.has_value()}};
633   };
634 
classofRelrSection635   static bool classof(const Chunk *S) {
636     return S->Kind == ChunkKind::Relr;
637   }
638 };
639 
640 struct SymtabShndxSection : Section {
641   std::optional<std::vector<uint32_t>> Entries;
642 
SymtabShndxSectionSymtabShndxSection643   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
644 
getEntriesSymtabShndxSection645   std::vector<std::pair<StringRef, bool>> getEntries() const override {
646     return {{"Entries", Entries.has_value()}};
647   };
648 
classofSymtabShndxSection649   static bool classof(const Chunk *S) {
650     return S->Kind == ChunkKind::SymtabShndxSection;
651   }
652 };
653 
654 struct ARMIndexTableEntry {
655   llvm::yaml::Hex32 Offset;
656   llvm::yaml::Hex32 Value;
657 };
658 
659 struct ARMIndexTableSection : Section {
660   std::optional<std::vector<ARMIndexTableEntry>> Entries;
661 
ARMIndexTableSectionARMIndexTableSection662   ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
663 
getEntriesARMIndexTableSection664   std::vector<std::pair<StringRef, bool>> getEntries() const override {
665     return {{"Entries", Entries.has_value()}};
666   };
667 
classofARMIndexTableSection668   static bool classof(const Chunk *S) {
669     return S->Kind == ChunkKind::ARMIndexTable;
670   }
671 };
672 
673 // Represents .MIPS.abiflags section
674 struct MipsABIFlags : Section {
675   llvm::yaml::Hex16 Version;
676   MIPS_ISA ISALevel;
677   llvm::yaml::Hex8 ISARevision;
678   MIPS_AFL_REG GPRSize;
679   MIPS_AFL_REG CPR1Size;
680   MIPS_AFL_REG CPR2Size;
681   MIPS_ABI_FP FpABI;
682   MIPS_AFL_EXT ISAExtension;
683   MIPS_AFL_ASE ASEs;
684   MIPS_AFL_FLAGS1 Flags1;
685   llvm::yaml::Hex32 Flags2;
686 
MipsABIFlagsMipsABIFlags687   MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
688 
classofMipsABIFlags689   static bool classof(const Chunk *S) {
690     return S->Kind == ChunkKind::MipsABIFlags;
691   }
692 };
693 
694 struct ProgramHeader {
695   ELF_PT Type;
696   ELF_PF Flags;
697   llvm::yaml::Hex64 VAddr;
698   llvm::yaml::Hex64 PAddr;
699   std::optional<llvm::yaml::Hex64> Align;
700   std::optional<llvm::yaml::Hex64> FileSize;
701   std::optional<llvm::yaml::Hex64> MemSize;
702   std::optional<llvm::yaml::Hex64> Offset;
703   std::optional<StringRef> FirstSec;
704   std::optional<StringRef> LastSec;
705 
706   // This vector contains all chunks from [FirstSec, LastSec].
707   std::vector<Chunk *> Chunks;
708 };
709 
710 struct Object {
711   FileHeader Header;
712   std::vector<ProgramHeader> ProgramHeaders;
713 
714   // An object might contain output section descriptions as well as
715   // custom data that does not belong to any section.
716   std::vector<std::unique_ptr<Chunk>> Chunks;
717 
718   // Although in reality the symbols reside in a section, it is a lot
719   // cleaner and nicer if we read them from the YAML as a separate
720   // top-level key, which automatically ensures that invariants like there
721   // being a single SHT_SYMTAB section are upheld.
722   std::optional<std::vector<Symbol>> Symbols;
723   std::optional<std::vector<Symbol>> DynamicSymbols;
724   std::optional<DWARFYAML::Data> DWARF;
725 
getSectionsObject726   std::vector<Section *> getSections() {
727     std::vector<Section *> Ret;
728     for (const std::unique_ptr<Chunk> &Sec : Chunks)
729       if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
730         Ret.push_back(S);
731     return Ret;
732   }
733 
getSectionHeaderTableObject734   const SectionHeaderTable &getSectionHeaderTable() const {
735     for (const std::unique_ptr<Chunk> &C : Chunks)
736       if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
737         return *S;
738     llvm_unreachable("the section header table chunk must always be present");
739   }
740 
741   ELF_ELFOSABI getOSAbi() const;
742   unsigned getMachine() const;
743 };
744 
745 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
746                              const NoBitsSection &S);
747 
748 } // end namespace ELFYAML
749 } // end namespace llvm
750 
751 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)752 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
753 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
754 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
755 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
756 LLVM_YAML_IS_SEQUENCE_VECTOR(
757     llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry)
758 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
759 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
760 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
761 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
762 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
763 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
764 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
765 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
766 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
767 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
768 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
769 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
770 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
771 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
772 
773 namespace llvm {
774 namespace yaml {
775 
776 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
777   static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
778                      raw_ostream &Out);
779   static StringRef input(StringRef Scalar, void *Ctx,
780                          ELFYAML::YAMLIntUInt &Val);
781   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
782 };
783 
784 template <>
785 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
786   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
787 };
788 
789 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
790   static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
791 };
792 
793 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
794   static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
795 };
796 
797 template <>
798 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
799   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
800 };
801 
802 template <>
803 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
804   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
805 };
806 
807 template <>
808 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
809   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
810 };
811 
812 template <>
813 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
814   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
815 };
816 
817 template <>
818 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
819   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
820 };
821 
822 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
823   static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
824 };
825 
826 template <>
827 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
828   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
829 };
830 
831 template <>
832 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
833   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
834 };
835 
836 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
837   static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
838 };
839 
840 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
841   static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
842 };
843 
844 template <>
845 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
846   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
847 };
848 
849 template <>
850 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
851   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
852 };
853 
854 template <>
855 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
856   static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
857 };
858 
859 template <>
860 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
861   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
862 };
863 
864 template <>
865 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
866   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
867 };
868 
869 template <>
870 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
871   static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
872 };
873 
874 template <>
875 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
876   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
877 };
878 
879 template <>
880 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
881   static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
882 };
883 
884 template <>
885 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
886   static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
887 };
888 
889 template <>
890 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
891   static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
892 };
893 
894 template <>
895 struct MappingTraits<ELFYAML::FileHeader> {
896   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
897 };
898 
899 template <> struct MappingTraits<ELFYAML::SectionHeader> {
900   static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
901 };
902 
903 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
904   static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
905   static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
906 };
907 
908 template <>
909 struct MappingTraits<ELFYAML::Symbol> {
910   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
911   static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
912 };
913 
914 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
915   static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
916 };
917 
918 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
919   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
920 };
921 
922 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
923   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
924 };
925 
926 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
927   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel);
928 };
929 
930 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> {
931   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel);
932 };
933 
934 template <>
935 struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> {
936   static void
937   mapping(IO &IO,
938           ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel);
939 };
940 
941 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
942   static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
943 };
944 
945 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
946   static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
947 };
948 
949 template <> struct MappingTraits<ELFYAML::NoteEntry> {
950   static void mapping(IO &IO, ELFYAML::NoteEntry &N);
951 };
952 
953 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
954   static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
955 };
956 
957 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
958   static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
959 };
960 
961 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
962   static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
963 };
964 
965 template <> struct MappingTraits<ELFYAML::LinkerOption> {
966   static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
967 };
968 
969 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
970   static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
971 };
972 
973 template <> struct MappingTraits<ELFYAML::Relocation> {
974   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
975 };
976 
977 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
978   static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
979 };
980 
981 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
982   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
983   static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
984 };
985 
986 template <>
987 struct MappingTraits<ELFYAML::Object> {
988   static void mapping(IO &IO, ELFYAML::Object &Object);
989 };
990 
991 template <> struct MappingTraits<ELFYAML::SectionOrType> {
992   static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
993 };
994 
995 } // end namespace yaml
996 } // end namespace llvm
997 
998 #endif // LLVM_OBJECTYAML_ELFYAML_H
999