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/ObjectYAML/DWARFYAML.h"
20 #include "llvm/ObjectYAML/YAML.h"
21 #include "llvm/Support/YAMLTraits.h"
22 #include <cstdint>
23 #include <memory>
24 #include <vector>
25 
26 namespace llvm {
27 namespace ELFYAML {
28 
29 StringRef dropUniqueSuffix(StringRef S);
30 std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
31 
32 // These types are invariant across 32/64-bit ELF, so for simplicity just
33 // directly give them their exact sizes. We don't need to worry about
34 // endianness because these are just the types in the YAMLIO structures,
35 // and are appropriately converted to the necessary endianness when
36 // reading/generating binary object files.
37 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
38 // the common prefix of the respective constants. E.g. ELF_EM corresponds
39 // to the `e_machine` constants, like `EM_X86_64`.
40 // In the future, these would probably be better suited by C++11 enum
41 // class's with appropriate fixed underlying type.
42 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
43 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
44 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
45 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
46 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
47 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
48 // Just use 64, since it can hold 32-bit values too.
49 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
50 // Just use 64, since it can hold 32-bit values too.
51 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
52 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
53 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
54 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
55 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
56 // Just use 64, since it can hold 32-bit values too.
57 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
58 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
59 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
60 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
61 
62 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
63 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
64 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
65 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
66 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
67 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
68 
69 LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
70 LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
71 
72 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
73 // since 64-bit can hold 32-bit values too.
74 struct FileHeader {
75   ELF_ELFCLASS Class;
76   ELF_ELFDATA Data;
77   ELF_ELFOSABI OSABI;
78   llvm::yaml::Hex8 ABIVersion;
79   ELF_ET Type;
80   ELF_EM Machine;
81   ELF_EF Flags;
82   llvm::yaml::Hex64 Entry;
83 
84   Optional<llvm::yaml::Hex64> EPhOff;
85   Optional<llvm::yaml::Hex16> EPhEntSize;
86   Optional<llvm::yaml::Hex16> EPhNum;
87   Optional<llvm::yaml::Hex16> EShEntSize;
88   Optional<llvm::yaml::Hex64> EShOff;
89   Optional<llvm::yaml::Hex16> EShNum;
90   Optional<llvm::yaml::Hex16> EShStrNdx;
91 };
92 
93 struct SectionHeader {
94   StringRef Name;
95 };
96 
97 struct SectionHeaderTable {
98   Optional<std::vector<SectionHeader>> Sections;
99   Optional<std::vector<SectionHeader>> Excluded;
100   Optional<bool> NoHeaders;
101 };
102 
103 struct SectionName {
104   StringRef Section;
105 };
106 
107 struct Symbol {
108   StringRef Name;
109   ELF_STT Type;
110   StringRef Section;
111   Optional<ELF_SHN> Index;
112   ELF_STB Binding;
113   llvm::yaml::Hex64 Value;
114   llvm::yaml::Hex64 Size;
115   Optional<uint8_t> Other;
116 
117   Optional<uint32_t> StName;
118 };
119 
120 struct SectionOrType {
121   StringRef sectionNameOrType;
122 };
123 
124 struct DynamicEntry {
125   ELF_DYNTAG Tag;
126   llvm::yaml::Hex64 Val;
127 };
128 
129 struct StackSizeEntry {
130   llvm::yaml::Hex64 Address;
131   llvm::yaml::Hex64 Size;
132 };
133 
134 struct NoteEntry {
135   StringRef Name;
136   yaml::BinaryRef Desc;
137   llvm::yaml::Hex32 Type;
138 };
139 
140 struct Chunk {
141   enum class ChunkKind {
142     Dynamic,
143     Group,
144     RawContent,
145     Relocation,
146     Relr,
147     NoBits,
148     Note,
149     Hash,
150     GnuHash,
151     Verdef,
152     Verneed,
153     StackSizes,
154     SymtabShndxSection,
155     Symver,
156     MipsABIFlags,
157     Addrsig,
158     Fill,
159     LinkerOptions,
160     DependentLibraries,
161     CallGraphProfile
162   };
163 
164   ChunkKind Kind;
165   StringRef Name;
166   Optional<llvm::yaml::Hex64> Offset;
167 
ChunkChunk168   Chunk(ChunkKind K) : Kind(K) {}
169   virtual ~Chunk();
170 };
171 
172 struct Section : public Chunk {
173   ELF_SHT Type;
174   Optional<ELF_SHF> Flags;
175   Optional<llvm::yaml::Hex64> Address;
176   StringRef Link;
177   llvm::yaml::Hex64 AddressAlign;
178   Optional<llvm::yaml::Hex64> EntSize;
179 
180   // Usually sections are not created implicitly, but loaded from YAML.
181   // When they are, this flag is used to signal about that.
182   bool IsImplicit;
183 
184   // Holds the original section index.
185   unsigned OriginalSecNdx;
186 
187   Section(ChunkKind Kind, bool IsImplicit = false)
ChunkSection188       : Chunk(Kind), IsImplicit(IsImplicit) {}
189 
classofSection190   static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; }
191 
192   // The following members are used to override section fields which is
193   // useful for creating invalid objects.
194 
195   // This can be used to override the offset stored in the sh_name field.
196   // It does not affect the name stored in the string table.
197   Optional<llvm::yaml::Hex64> ShName;
198 
199   // This can be used to override the sh_offset field. It does not place the
200   // section data at the offset specified.
201   Optional<llvm::yaml::Hex64> ShOffset;
202 
203   // This can be used to override the sh_size field. It does not affect the
204   // content written.
205   Optional<llvm::yaml::Hex64> ShSize;
206 
207   // This can be used to override the sh_flags field.
208   Optional<llvm::yaml::Hex64> ShFlags;
209 };
210 
211 // Fill is a block of data which is placed outside of sections. It is
212 // not present in the sections header table, but it might affect the output file
213 // size and program headers produced.
214 struct Fill : Chunk {
215   Optional<yaml::BinaryRef> Pattern;
216   llvm::yaml::Hex64 Size;
217 
FillFill218   Fill() : Chunk(ChunkKind::Fill) {}
219 
classofFill220   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
221 };
222 
223 struct StackSizesSection : Section {
224   Optional<yaml::BinaryRef> Content;
225   Optional<llvm::yaml::Hex64> Size;
226   Optional<std::vector<StackSizeEntry>> Entries;
227 
StackSizesSectionStackSizesSection228   StackSizesSection() : Section(ChunkKind::StackSizes) {}
229 
classofStackSizesSection230   static bool classof(const Chunk *S) {
231     return S->Kind == ChunkKind::StackSizes;
232   }
233 
nameMatchesStackSizesSection234   static bool nameMatches(StringRef Name) {
235     return Name == ".stack_sizes";
236   }
237 };
238 
239 struct DynamicSection : Section {
240   std::vector<DynamicEntry> Entries;
241   Optional<yaml::BinaryRef> Content;
242 
DynamicSectionDynamicSection243   DynamicSection() : Section(ChunkKind::Dynamic) {}
244 
classofDynamicSection245   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
246 };
247 
248 struct RawContentSection : Section {
249   Optional<yaml::BinaryRef> Content;
250   Optional<llvm::yaml::Hex64> Size;
251   Optional<llvm::yaml::Hex64> Info;
252 
RawContentSectionRawContentSection253   RawContentSection() : Section(ChunkKind::RawContent) {}
254 
classofRawContentSection255   static bool classof(const Chunk *S) {
256     return S->Kind == ChunkKind::RawContent;
257   }
258 
259   // Is used when a content is read as an array of bytes.
260   Optional<std::vector<uint8_t>> ContentBuf;
261 };
262 
263 struct NoBitsSection : Section {
264   llvm::yaml::Hex64 Size;
265 
NoBitsSectionNoBitsSection266   NoBitsSection() : Section(ChunkKind::NoBits) {}
267 
classofNoBitsSection268   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
269 };
270 
271 struct NoteSection : Section {
272   Optional<yaml::BinaryRef> Content;
273   Optional<llvm::yaml::Hex64> Size;
274   Optional<std::vector<ELFYAML::NoteEntry>> Notes;
275 
NoteSectionNoteSection276   NoteSection() : Section(ChunkKind::Note) {}
277 
classofNoteSection278   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
279 };
280 
281 struct HashSection : Section {
282   Optional<yaml::BinaryRef> Content;
283   Optional<llvm::yaml::Hex64> Size;
284   Optional<std::vector<uint32_t>> Bucket;
285   Optional<std::vector<uint32_t>> Chain;
286 
287   // The following members are used to override section fields.
288   // This is useful for creating invalid objects.
289   Optional<llvm::yaml::Hex64> NBucket;
290   Optional<llvm::yaml::Hex64> NChain;
291 
HashSectionHashSection292   HashSection() : Section(ChunkKind::Hash) {}
293 
classofHashSection294   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
295 };
296 
297 struct GnuHashHeader {
298   // The number of hash buckets.
299   // Not used when dumping the object, but can be used to override
300   // the real number of buckets when emiting an object from a YAML document.
301   Optional<llvm::yaml::Hex32> NBuckets;
302 
303   // Index of the first symbol in the dynamic symbol table
304   // included in the hash table.
305   llvm::yaml::Hex32 SymNdx;
306 
307   // The number of words in the Bloom filter.
308   // Not used when dumping the object, but can be used to override the real
309   // number of words in the Bloom filter when emiting an object from a YAML
310   // document.
311   Optional<llvm::yaml::Hex32> MaskWords;
312 
313   // A shift constant used by the Bloom filter.
314   llvm::yaml::Hex32 Shift2;
315 };
316 
317 struct GnuHashSection : Section {
318   Optional<yaml::BinaryRef> Content;
319 
320   Optional<GnuHashHeader> Header;
321   Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
322   Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
323   Optional<std::vector<llvm::yaml::Hex32>> HashValues;
324 
GnuHashSectionGnuHashSection325   GnuHashSection() : Section(ChunkKind::GnuHash) {}
326 
classofGnuHashSection327   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
328 };
329 
330 struct VernauxEntry {
331   uint32_t Hash;
332   uint16_t Flags;
333   uint16_t Other;
334   StringRef Name;
335 };
336 
337 struct VerneedEntry {
338   uint16_t Version;
339   StringRef File;
340   std::vector<VernauxEntry> AuxV;
341 };
342 
343 struct VerneedSection : Section {
344   Optional<yaml::BinaryRef> Content;
345   Optional<std::vector<VerneedEntry>> VerneedV;
346   llvm::yaml::Hex64 Info;
347 
VerneedSectionVerneedSection348   VerneedSection() : Section(ChunkKind::Verneed) {}
349 
classofVerneedSection350   static bool classof(const Chunk *S) {
351     return S->Kind == ChunkKind::Verneed;
352   }
353 };
354 
355 struct AddrsigSection : Section {
356   Optional<yaml::BinaryRef> Content;
357   Optional<llvm::yaml::Hex64> Size;
358   Optional<std::vector<YAMLFlowString>> Symbols;
359 
AddrsigSectionAddrsigSection360   AddrsigSection() : Section(ChunkKind::Addrsig) {}
361 
classofAddrsigSection362   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
363 };
364 
365 struct LinkerOption {
366   StringRef Key;
367   StringRef Value;
368 };
369 
370 struct LinkerOptionsSection : Section {
371   Optional<std::vector<LinkerOption>> Options;
372   Optional<yaml::BinaryRef> Content;
373 
LinkerOptionsSectionLinkerOptionsSection374   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
375 
classofLinkerOptionsSection376   static bool classof(const Chunk *S) {
377     return S->Kind == ChunkKind::LinkerOptions;
378   }
379 };
380 
381 struct DependentLibrariesSection : Section {
382   Optional<std::vector<YAMLFlowString>> Libs;
383   Optional<yaml::BinaryRef> Content;
384 
DependentLibrariesSectionDependentLibrariesSection385   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
386 
classofDependentLibrariesSection387   static bool classof(const Chunk *S) {
388     return S->Kind == ChunkKind::DependentLibraries;
389   }
390 };
391 
392 // Represents the call graph profile section entry.
393 struct CallGraphEntry {
394   // The symbol of the source of the edge.
395   StringRef From;
396   // The symbol index of the destination of the edge.
397   StringRef To;
398   // The weight of the edge.
399   uint64_t Weight;
400 };
401 
402 struct CallGraphProfileSection : Section {
403   Optional<std::vector<CallGraphEntry>> Entries;
404   Optional<yaml::BinaryRef> Content;
405 
CallGraphProfileSectionCallGraphProfileSection406   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
407 
classofCallGraphProfileSection408   static bool classof(const Chunk *S) {
409     return S->Kind == ChunkKind::CallGraphProfile;
410   }
411 };
412 
413 struct SymverSection : Section {
414   std::vector<uint16_t> Entries;
415 
SymverSectionSymverSection416   SymverSection() : Section(ChunkKind::Symver) {}
417 
classofSymverSection418   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
419 };
420 
421 struct VerdefEntry {
422   uint16_t Version;
423   uint16_t Flags;
424   uint16_t VersionNdx;
425   uint32_t Hash;
426   std::vector<StringRef> VerNames;
427 };
428 
429 struct VerdefSection : Section {
430   Optional<std::vector<VerdefEntry>> Entries;
431   Optional<yaml::BinaryRef> Content;
432 
433   llvm::yaml::Hex64 Info;
434 
VerdefSectionVerdefSection435   VerdefSection() : Section(ChunkKind::Verdef) {}
436 
classofVerdefSection437   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
438 };
439 
440 struct Group : Section {
441   // Members of a group contain a flag and a list of section indices
442   // that are part of the group.
443   std::vector<SectionOrType> Members;
444   Optional<StringRef> Signature; /* Info */
445 
GroupGroup446   Group() : Section(ChunkKind::Group) {}
447 
classofGroup448   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
449 };
450 
451 struct Relocation {
452   llvm::yaml::Hex64 Offset;
453   YAMLIntUInt Addend;
454   ELF_REL Type;
455   Optional<StringRef> Symbol;
456 };
457 
458 struct RelocationSection : Section {
459   std::vector<Relocation> Relocations;
460   StringRef RelocatableSec; /* Info */
461 
RelocationSectionRelocationSection462   RelocationSection() : Section(ChunkKind::Relocation) {}
463 
classofRelocationSection464   static bool classof(const Chunk *S) {
465     return S->Kind == ChunkKind::Relocation;
466   }
467 };
468 
469 struct RelrSection : Section {
470   Optional<std::vector<llvm::yaml::Hex64>> Entries;
471   Optional<yaml::BinaryRef> Content;
472 
RelrSectionRelrSection473   RelrSection() : Section(ChunkKind::Relr) {}
474 
classofRelrSection475   static bool classof(const Chunk *S) {
476     return S->Kind == ChunkKind::Relr;
477   }
478 };
479 
480 struct SymtabShndxSection : Section {
481   std::vector<uint32_t> Entries;
482 
SymtabShndxSectionSymtabShndxSection483   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
484 
classofSymtabShndxSection485   static bool classof(const Chunk *S) {
486     return S->Kind == ChunkKind::SymtabShndxSection;
487   }
488 };
489 
490 // Represents .MIPS.abiflags section
491 struct MipsABIFlags : Section {
492   llvm::yaml::Hex16 Version;
493   MIPS_ISA ISALevel;
494   llvm::yaml::Hex8 ISARevision;
495   MIPS_AFL_REG GPRSize;
496   MIPS_AFL_REG CPR1Size;
497   MIPS_AFL_REG CPR2Size;
498   MIPS_ABI_FP FpABI;
499   MIPS_AFL_EXT ISAExtension;
500   MIPS_AFL_ASE ASEs;
501   MIPS_AFL_FLAGS1 Flags1;
502   llvm::yaml::Hex32 Flags2;
503 
MipsABIFlagsMipsABIFlags504   MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
505 
classofMipsABIFlags506   static bool classof(const Chunk *S) {
507     return S->Kind == ChunkKind::MipsABIFlags;
508   }
509 };
510 
511 struct ProgramHeader {
512   ELF_PT Type;
513   ELF_PF Flags;
514   llvm::yaml::Hex64 VAddr;
515   llvm::yaml::Hex64 PAddr;
516   Optional<llvm::yaml::Hex64> Align;
517   Optional<llvm::yaml::Hex64> FileSize;
518   Optional<llvm::yaml::Hex64> MemSize;
519   Optional<llvm::yaml::Hex64> Offset;
520 
521   std::vector<SectionName> Sections;
522   // This vector is parallel to Sections and contains corresponding chunks.
523   std::vector<Chunk *> Chunks;
524 };
525 
526 struct Object {
527   FileHeader Header;
528   Optional<SectionHeaderTable> SectionHeaders;
529   std::vector<ProgramHeader> ProgramHeaders;
530 
531   // An object might contain output section descriptions as well as
532   // custom data that does not belong to any section.
533   std::vector<std::unique_ptr<Chunk>> Chunks;
534 
535   // Although in reality the symbols reside in a section, it is a lot
536   // cleaner and nicer if we read them from the YAML as a separate
537   // top-level key, which automatically ensures that invariants like there
538   // being a single SHT_SYMTAB section are upheld.
539   Optional<std::vector<Symbol>> Symbols;
540   Optional<std::vector<Symbol>> DynamicSymbols;
541   Optional<DWARFYAML::Data> DWARF;
542 
getSectionsObject543   std::vector<Section *> getSections() {
544     std::vector<Section *> Ret;
545     for (const std::unique_ptr<Chunk> &Sec : Chunks)
546       if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
547         Ret.push_back(S);
548     return Ret;
549   }
550 };
551 
552 } // end namespace ELFYAML
553 } // end namespace llvm
554 
555 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)556 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
557 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
558 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntry)
559 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
560 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
561 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
562 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
563 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
564 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
565 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
566 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
567 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
568 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
569 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)
570 
571 namespace llvm {
572 namespace yaml {
573 
574 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
575   static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
576                      raw_ostream &Out);
577   static StringRef input(StringRef Scalar, void *Ctx,
578                          ELFYAML::YAMLIntUInt &Val);
579   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
580 };
581 
582 template <>
583 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
584   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
585 };
586 
587 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
588   static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
589 };
590 
591 template <>
592 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
593   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
594 };
595 
596 template <>
597 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
598   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
599 };
600 
601 template <>
602 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
603   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
604 };
605 
606 template <>
607 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
608   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
609 };
610 
611 template <>
612 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
613   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
614 };
615 
616 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
617   static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
618 };
619 
620 template <>
621 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
622   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
623 };
624 
625 template <>
626 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
627   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
628 };
629 
630 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
631   static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
632 };
633 
634 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
635   static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
636 };
637 
638 template <>
639 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
640   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
641 };
642 
643 template <>
644 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
645   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
646 };
647 
648 template <>
649 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
650   static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
651 };
652 
653 template <>
654 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
655   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
656 };
657 
658 template <>
659 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
660   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
661 };
662 
663 template <>
664 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
665   static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
666 };
667 
668 template <>
669 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
670   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
671 };
672 
673 template <>
674 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
675   static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
676 };
677 
678 template <>
679 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
680   static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
681 };
682 
683 template <>
684 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
685   static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
686 };
687 
688 template <>
689 struct MappingTraits<ELFYAML::FileHeader> {
690   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
691 };
692 
693 template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
694   static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
695   static StringRef validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
696 };
697 
698 template <> struct MappingTraits<ELFYAML::SectionHeader> {
699   static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
700 };
701 
702 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
703   static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
704 };
705 
706 template <>
707 struct MappingTraits<ELFYAML::Symbol> {
708   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
709   static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
710 };
711 
712 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
713   static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
714 };
715 
716 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
717   static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
718 };
719 
720 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
721   static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
722 };
723 
724 template <> struct MappingTraits<ELFYAML::NoteEntry> {
725   static void mapping(IO &IO, ELFYAML::NoteEntry &N);
726 };
727 
728 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
729   static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
730 };
731 
732 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
733   static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
734 };
735 
736 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
737   static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
738 };
739 
740 template <> struct MappingTraits<ELFYAML::LinkerOption> {
741   static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
742 };
743 
744 template <> struct MappingTraits<ELFYAML::CallGraphEntry> {
745   static void mapping(IO &IO, ELFYAML::CallGraphEntry &E);
746 };
747 
748 template <> struct MappingTraits<ELFYAML::Relocation> {
749   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
750 };
751 
752 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
753   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
754   static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
755 };
756 
757 template <>
758 struct MappingTraits<ELFYAML::Object> {
759   static void mapping(IO &IO, ELFYAML::Object &Object);
760 };
761 
762 template <> struct MappingTraits<ELFYAML::SectionOrType> {
763   static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
764 };
765 
766 template <> struct MappingTraits<ELFYAML::SectionName> {
767   static void mapping(IO &IO, ELFYAML::SectionName &sectionName);
768 };
769 
770 } // end namespace yaml
771 } // end namespace llvm
772 
773 #endif // LLVM_OBJECTYAML_ELFYAML_H
774