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