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