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 Optional<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 Symbol {
104 StringRef Name;
105 ELF_STT Type;
106 Optional<StringRef> Section;
107 Optional<ELF_SHN> Index;
108 ELF_STB Binding;
109 llvm::yaml::Hex64 Value;
110 llvm::yaml::Hex64 Size;
111 Optional<uint8_t> Other;
112
113 Optional<uint32_t> StName;
114 };
115
116 struct SectionOrType {
117 StringRef sectionNameOrType;
118 };
119
120 struct DynamicEntry {
121 ELF_DYNTAG Tag;
122 llvm::yaml::Hex64 Val;
123 };
124
125 struct BBAddrMapEntry {
126 struct BBEntry {
127 llvm::yaml::Hex32 AddressOffset;
128 llvm::yaml::Hex32 Size;
129 llvm::yaml::Hex32 Metadata;
130 };
131 llvm::yaml::Hex64 Address;
132 Optional<std::vector<BBEntry>> BBEntries;
133 };
134
135 struct StackSizeEntry {
136 llvm::yaml::Hex64 Address;
137 llvm::yaml::Hex64 Size;
138 };
139
140 struct NoteEntry {
141 StringRef Name;
142 yaml::BinaryRef Desc;
143 llvm::yaml::Hex32 Type;
144 };
145
146 struct Chunk {
147 enum class ChunkKind {
148 Dynamic,
149 Group,
150 RawContent,
151 Relocation,
152 Relr,
153 NoBits,
154 Note,
155 Hash,
156 GnuHash,
157 Verdef,
158 Verneed,
159 StackSizes,
160 SymtabShndxSection,
161 Symver,
162 ARMIndexTable,
163 MipsABIFlags,
164 Addrsig,
165 Fill,
166 LinkerOptions,
167 DependentLibraries,
168 CallGraphProfile,
169 BBAddrMap
170 };
171
172 ChunkKind Kind;
173 StringRef Name;
174 Optional<llvm::yaml::Hex64> Offset;
175
ChunkChunk176 Chunk(ChunkKind K) : Kind(K) {}
177 virtual ~Chunk();
178 };
179
180 struct Section : public Chunk {
181 ELF_SHT Type;
182 Optional<ELF_SHF> Flags;
183 Optional<llvm::yaml::Hex64> Address;
184 Optional<StringRef> Link;
185 llvm::yaml::Hex64 AddressAlign;
186 Optional<llvm::yaml::Hex64> EntSize;
187
188 Optional<yaml::BinaryRef> Content;
189 Optional<llvm::yaml::Hex64> Size;
190
191 // Usually sections are not created implicitly, but loaded from YAML.
192 // When they are, this flag is used to signal about that.
193 bool IsImplicit;
194
195 // Holds the original section index.
196 unsigned OriginalSecNdx;
197
198 Section(ChunkKind Kind, bool IsImplicit = false)
ChunkSection199 : Chunk(Kind), IsImplicit(IsImplicit) {}
200
classofSection201 static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; }
202
203 // Some derived sections might have their own special entries. This method
204 // returns a vector of <entry name, is used> pairs. It is used for section
205 // validation.
getEntriesSection206 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
207 return {};
208 };
209
210 // The following members are used to override section fields which is
211 // useful for creating invalid objects.
212
213 // This can be used to override the sh_addralign field.
214 Optional<llvm::yaml::Hex64> ShAddrAlign;
215
216 // This can be used to override the offset stored in the sh_name field.
217 // It does not affect the name stored in the string table.
218 Optional<llvm::yaml::Hex64> ShName;
219
220 // This can be used to override the sh_offset field. It does not place the
221 // section data at the offset specified.
222 Optional<llvm::yaml::Hex64> ShOffset;
223
224 // This can be used to override the sh_size field. It does not affect the
225 // content written.
226 Optional<llvm::yaml::Hex64> ShSize;
227
228 // This can be used to override the sh_flags field.
229 Optional<llvm::yaml::Hex64> ShFlags;
230
231 // This can be used to override the sh_type field. It is useful when we
232 // want to use specific YAML keys for a section of a particular type to
233 // describe the content, but still want to have a different final type
234 // for the section.
235 Optional<ELF_SHT> ShType;
236 };
237
238 // Fill is a block of data which is placed outside of sections. It is
239 // not present in the sections header table, but it might affect the output file
240 // size and program headers produced.
241 struct Fill : Chunk {
242 Optional<yaml::BinaryRef> Pattern;
243 llvm::yaml::Hex64 Size;
244
FillFill245 Fill() : Chunk(ChunkKind::Fill) {}
246
classofFill247 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
248 };
249
250 struct BBAddrMapSection : Section {
251 Optional<std::vector<BBAddrMapEntry>> Entries;
252
BBAddrMapSectionBBAddrMapSection253 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
254
getEntriesBBAddrMapSection255 std::vector<std::pair<StringRef, bool>> getEntries() const override {
256 return {{"Entries", Entries.hasValue()}};
257 };
258
classofBBAddrMapSection259 static bool classof(const Chunk *S) {
260 return S->Kind == ChunkKind::BBAddrMap;
261 }
262 };
263
264 struct StackSizesSection : Section {
265 Optional<std::vector<StackSizeEntry>> Entries;
266
StackSizesSectionStackSizesSection267 StackSizesSection() : Section(ChunkKind::StackSizes) {}
268
getEntriesStackSizesSection269 std::vector<std::pair<StringRef, bool>> getEntries() const override {
270 return {{"Entries", Entries.hasValue()}};
271 };
272
classofStackSizesSection273 static bool classof(const Chunk *S) {
274 return S->Kind == ChunkKind::StackSizes;
275 }
276
nameMatchesStackSizesSection277 static bool nameMatches(StringRef Name) {
278 return Name == ".stack_sizes";
279 }
280 };
281
282 struct DynamicSection : Section {
283 Optional<std::vector<DynamicEntry>> Entries;
284
DynamicSectionDynamicSection285 DynamicSection() : Section(ChunkKind::Dynamic) {}
286
getEntriesDynamicSection287 std::vector<std::pair<StringRef, bool>> getEntries() const override {
288 return {{"Entries", Entries.hasValue()}};
289 };
290
classofDynamicSection291 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
292 };
293
294 struct RawContentSection : Section {
295 Optional<llvm::yaml::Hex64> Info;
296
RawContentSectionRawContentSection297 RawContentSection() : Section(ChunkKind::RawContent) {}
298
classofRawContentSection299 static bool classof(const Chunk *S) {
300 return S->Kind == ChunkKind::RawContent;
301 }
302
303 // Is used when a content is read as an array of bytes.
304 Optional<std::vector<uint8_t>> ContentBuf;
305 };
306
307 struct NoBitsSection : Section {
NoBitsSectionNoBitsSection308 NoBitsSection() : Section(ChunkKind::NoBits) {}
309
classofNoBitsSection310 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
311 };
312
313 struct NoteSection : Section {
314 Optional<std::vector<ELFYAML::NoteEntry>> Notes;
315
NoteSectionNoteSection316 NoteSection() : Section(ChunkKind::Note) {}
317
getEntriesNoteSection318 std::vector<std::pair<StringRef, bool>> getEntries() const override {
319 return {{"Notes", Notes.hasValue()}};
320 };
321
classofNoteSection322 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
323 };
324
325 struct HashSection : Section {
326 Optional<std::vector<uint32_t>> Bucket;
327 Optional<std::vector<uint32_t>> Chain;
328
getEntriesHashSection329 std::vector<std::pair<StringRef, bool>> getEntries() const override {
330 return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
331 };
332
333 // The following members are used to override section fields.
334 // This is useful for creating invalid objects.
335 Optional<llvm::yaml::Hex64> NBucket;
336 Optional<llvm::yaml::Hex64> NChain;
337
HashSectionHashSection338 HashSection() : Section(ChunkKind::Hash) {}
339
classofHashSection340 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
341 };
342
343 struct GnuHashHeader {
344 // The number of hash buckets.
345 // Not used when dumping the object, but can be used to override
346 // the real number of buckets when emiting an object from a YAML document.
347 Optional<llvm::yaml::Hex32> NBuckets;
348
349 // Index of the first symbol in the dynamic symbol table
350 // included in the hash table.
351 llvm::yaml::Hex32 SymNdx;
352
353 // The number of words in the Bloom filter.
354 // Not used when dumping the object, but can be used to override the real
355 // number of words in the Bloom filter when emiting an object from a YAML
356 // document.
357 Optional<llvm::yaml::Hex32> MaskWords;
358
359 // A shift constant used by the Bloom filter.
360 llvm::yaml::Hex32 Shift2;
361 };
362
363 struct GnuHashSection : Section {
364 Optional<GnuHashHeader> Header;
365 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
366 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
367 Optional<std::vector<llvm::yaml::Hex32>> HashValues;
368
GnuHashSectionGnuHashSection369 GnuHashSection() : Section(ChunkKind::GnuHash) {}
370
getEntriesGnuHashSection371 std::vector<std::pair<StringRef, bool>> getEntries() const override {
372 return {{"Header", Header.hasValue()},
373 {"BloomFilter", BloomFilter.hasValue()},
374 {"HashBuckets", HashBuckets.hasValue()},
375 {"HashValues", HashValues.hasValue()}};
376 };
377
classofGnuHashSection378 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
379 };
380
381 struct VernauxEntry {
382 uint32_t Hash;
383 uint16_t Flags;
384 uint16_t Other;
385 StringRef Name;
386 };
387
388 struct VerneedEntry {
389 uint16_t Version;
390 StringRef File;
391 std::vector<VernauxEntry> AuxV;
392 };
393
394 struct VerneedSection : Section {
395 Optional<std::vector<VerneedEntry>> VerneedV;
396 llvm::yaml::Hex64 Info;
397
VerneedSectionVerneedSection398 VerneedSection() : Section(ChunkKind::Verneed) {}
399
getEntriesVerneedSection400 std::vector<std::pair<StringRef, bool>> getEntries() const override {
401 return {{"Dependencies", VerneedV.hasValue()}};
402 };
403
classofVerneedSection404 static bool classof(const Chunk *S) {
405 return S->Kind == ChunkKind::Verneed;
406 }
407 };
408
409 struct AddrsigSection : Section {
410 Optional<std::vector<YAMLFlowString>> Symbols;
411
AddrsigSectionAddrsigSection412 AddrsigSection() : Section(ChunkKind::Addrsig) {}
413
getEntriesAddrsigSection414 std::vector<std::pair<StringRef, bool>> getEntries() const override {
415 return {{"Symbols", Symbols.hasValue()}};
416 };
417
classofAddrsigSection418 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
419 };
420
421 struct LinkerOption {
422 StringRef Key;
423 StringRef Value;
424 };
425
426 struct LinkerOptionsSection : Section {
427 Optional<std::vector<LinkerOption>> Options;
428
LinkerOptionsSectionLinkerOptionsSection429 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
430
getEntriesLinkerOptionsSection431 std::vector<std::pair<StringRef, bool>> getEntries() const override {
432 return {{"Options", Options.hasValue()}};
433 };
434
classofLinkerOptionsSection435 static bool classof(const Chunk *S) {
436 return S->Kind == ChunkKind::LinkerOptions;
437 }
438 };
439
440 struct DependentLibrariesSection : Section {
441 Optional<std::vector<YAMLFlowString>> Libs;
442
DependentLibrariesSectionDependentLibrariesSection443 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
444
getEntriesDependentLibrariesSection445 std::vector<std::pair<StringRef, bool>> getEntries() const override {
446 return {{"Libraries", Libs.hasValue()}};
447 };
448
classofDependentLibrariesSection449 static bool classof(const Chunk *S) {
450 return S->Kind == ChunkKind::DependentLibraries;
451 }
452 };
453
454 // Represents the call graph profile section entry.
455 struct CallGraphEntry {
456 // The symbol of the source of the edge.
457 StringRef From;
458 // The symbol index of the destination of the edge.
459 StringRef To;
460 // The weight of the edge.
461 uint64_t Weight;
462 };
463
464 struct CallGraphProfileSection : Section {
465 Optional<std::vector<CallGraphEntry>> Entries;
466
CallGraphProfileSectionCallGraphProfileSection467 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
468
getEntriesCallGraphProfileSection469 std::vector<std::pair<StringRef, bool>> getEntries() const override {
470 return {{"Entries", Entries.hasValue()}};
471 };
472
classofCallGraphProfileSection473 static bool classof(const Chunk *S) {
474 return S->Kind == ChunkKind::CallGraphProfile;
475 }
476 };
477
478 struct SymverSection : Section {
479 Optional<std::vector<uint16_t>> Entries;
480
SymverSectionSymverSection481 SymverSection() : Section(ChunkKind::Symver) {}
482
getEntriesSymverSection483 std::vector<std::pair<StringRef, bool>> getEntries() const override {
484 return {{"Entries", Entries.hasValue()}};
485 };
486
classofSymverSection487 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
488 };
489
490 struct VerdefEntry {
491 uint16_t Version;
492 uint16_t Flags;
493 uint16_t VersionNdx;
494 uint32_t Hash;
495 std::vector<StringRef> VerNames;
496 };
497
498 struct VerdefSection : Section {
499 Optional<std::vector<VerdefEntry>> Entries;
500
501 llvm::yaml::Hex64 Info;
502
VerdefSectionVerdefSection503 VerdefSection() : Section(ChunkKind::Verdef) {}
504
getEntriesVerdefSection505 std::vector<std::pair<StringRef, bool>> getEntries() const override {
506 return {{"Entries", Entries.hasValue()}};
507 };
508
classofVerdefSection509 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
510 };
511
512 struct GroupSection : Section {
513 // Members of a group contain a flag and a list of section indices
514 // that are part of the group.
515 Optional<std::vector<SectionOrType>> Members;
516 Optional<StringRef> Signature; /* Info */
517
GroupSectionGroupSection518 GroupSection() : Section(ChunkKind::Group) {}
519
getEntriesGroupSection520 std::vector<std::pair<StringRef, bool>> getEntries() const override {
521 return {{"Members", Members.hasValue()}};
522 };
523
classofGroupSection524 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
525 };
526
527 struct Relocation {
528 llvm::yaml::Hex64 Offset;
529 YAMLIntUInt Addend;
530 ELF_REL Type;
531 Optional<StringRef> Symbol;
532 };
533
534 struct RelocationSection : Section {
535 Optional<std::vector<Relocation>> Relocations;
536 StringRef RelocatableSec; /* Info */
537
RelocationSectionRelocationSection538 RelocationSection() : Section(ChunkKind::Relocation) {}
539
getEntriesRelocationSection540 std::vector<std::pair<StringRef, bool>> getEntries() const override {
541 return {{"Relocations", Relocations.hasValue()}};
542 };
543
classofRelocationSection544 static bool classof(const Chunk *S) {
545 return S->Kind == ChunkKind::Relocation;
546 }
547 };
548
549 struct RelrSection : Section {
550 Optional<std::vector<llvm::yaml::Hex64>> Entries;
551
RelrSectionRelrSection552 RelrSection() : Section(ChunkKind::Relr) {}
553
getEntriesRelrSection554 std::vector<std::pair<StringRef, bool>> getEntries() const override {
555 return {{"Entries", Entries.hasValue()}};
556 };
557
classofRelrSection558 static bool classof(const Chunk *S) {
559 return S->Kind == ChunkKind::Relr;
560 }
561 };
562
563 struct SymtabShndxSection : Section {
564 Optional<std::vector<uint32_t>> Entries;
565
SymtabShndxSectionSymtabShndxSection566 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
567
getEntriesSymtabShndxSection568 std::vector<std::pair<StringRef, bool>> getEntries() const override {
569 return {{"Entries", Entries.hasValue()}};
570 };
571
classofSymtabShndxSection572 static bool classof(const Chunk *S) {
573 return S->Kind == ChunkKind::SymtabShndxSection;
574 }
575 };
576
577 struct ARMIndexTableEntry {
578 llvm::yaml::Hex32 Offset;
579 llvm::yaml::Hex32 Value;
580 };
581
582 struct ARMIndexTableSection : Section {
583 Optional<std::vector<ARMIndexTableEntry>> Entries;
584
ARMIndexTableSectionARMIndexTableSection585 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
586
getEntriesARMIndexTableSection587 std::vector<std::pair<StringRef, bool>> getEntries() const override {
588 return {{"Entries", Entries.hasValue()}};
589 };
590
classofARMIndexTableSection591 static bool classof(const Chunk *S) {
592 return S->Kind == ChunkKind::ARMIndexTable;
593 }
594 };
595
596 // Represents .MIPS.abiflags section
597 struct MipsABIFlags : Section {
598 llvm::yaml::Hex16 Version;
599 MIPS_ISA ISALevel;
600 llvm::yaml::Hex8 ISARevision;
601 MIPS_AFL_REG GPRSize;
602 MIPS_AFL_REG CPR1Size;
603 MIPS_AFL_REG CPR2Size;
604 MIPS_ABI_FP FpABI;
605 MIPS_AFL_EXT ISAExtension;
606 MIPS_AFL_ASE ASEs;
607 MIPS_AFL_FLAGS1 Flags1;
608 llvm::yaml::Hex32 Flags2;
609
MipsABIFlagsMipsABIFlags610 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
611
classofMipsABIFlags612 static bool classof(const Chunk *S) {
613 return S->Kind == ChunkKind::MipsABIFlags;
614 }
615 };
616
617 struct ProgramHeader {
618 ELF_PT Type;
619 ELF_PF Flags;
620 llvm::yaml::Hex64 VAddr;
621 llvm::yaml::Hex64 PAddr;
622 Optional<llvm::yaml::Hex64> Align;
623 Optional<llvm::yaml::Hex64> FileSize;
624 Optional<llvm::yaml::Hex64> MemSize;
625 Optional<llvm::yaml::Hex64> Offset;
626 Optional<StringRef> FirstSec;
627 Optional<StringRef> LastSec;
628
629 // This vector contains all chunks from [FirstSec, LastSec].
630 std::vector<Chunk *> Chunks;
631 };
632
633 struct Object {
634 FileHeader Header;
635 Optional<SectionHeaderTable> SectionHeaders;
636 std::vector<ProgramHeader> ProgramHeaders;
637
638 // An object might contain output section descriptions as well as
639 // custom data that does not belong to any section.
640 std::vector<std::unique_ptr<Chunk>> Chunks;
641
642 // Although in reality the symbols reside in a section, it is a lot
643 // cleaner and nicer if we read them from the YAML as a separate
644 // top-level key, which automatically ensures that invariants like there
645 // being a single SHT_SYMTAB section are upheld.
646 Optional<std::vector<Symbol>> Symbols;
647 Optional<std::vector<Symbol>> DynamicSymbols;
648 Optional<DWARFYAML::Data> DWARF;
649
getSectionsObject650 std::vector<Section *> getSections() {
651 std::vector<Section *> Ret;
652 for (const std::unique_ptr<Chunk> &Sec : Chunks)
653 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
654 Ret.push_back(S);
655 return Ret;
656 }
657
658 unsigned getMachine() const;
659 };
660
661 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
662 const NoBitsSection &S);
663
664 } // end namespace ELFYAML
665 } // end namespace llvm
666
667 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)668 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
669 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
670 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
671 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
672 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntry)
673 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
674 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
675 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
676 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
677 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
678 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
679 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
680 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
681 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
682 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
683 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
684
685 namespace llvm {
686 namespace yaml {
687
688 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
689 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
690 raw_ostream &Out);
691 static StringRef input(StringRef Scalar, void *Ctx,
692 ELFYAML::YAMLIntUInt &Val);
693 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
694 };
695
696 template <>
697 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
698 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
699 };
700
701 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
702 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
703 };
704
705 template <>
706 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
707 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
708 };
709
710 template <>
711 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
712 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
713 };
714
715 template <>
716 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
717 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
718 };
719
720 template <>
721 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
722 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
723 };
724
725 template <>
726 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
727 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
728 };
729
730 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
731 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
732 };
733
734 template <>
735 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
736 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
737 };
738
739 template <>
740 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
741 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
742 };
743
744 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
745 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
746 };
747
748 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
749 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
750 };
751
752 template <>
753 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
754 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
755 };
756
757 template <>
758 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
759 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
760 };
761
762 template <>
763 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
764 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
765 };
766
767 template <>
768 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
769 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
770 };
771
772 template <>
773 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
774 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
775 };
776
777 template <>
778 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
779 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
780 };
781
782 template <>
783 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
784 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
785 };
786
787 template <>
788 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
789 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
790 };
791
792 template <>
793 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
794 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
795 };
796
797 template <>
798 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
799 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
800 };
801
802 template <>
803 struct MappingTraits<ELFYAML::FileHeader> {
804 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
805 };
806
807 template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
808 static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
809 static std::string validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
810 };
811
812 template <> struct MappingTraits<ELFYAML::SectionHeader> {
813 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
814 };
815
816 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
817 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
818 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
819 };
820
821 template <>
822 struct MappingTraits<ELFYAML::Symbol> {
823 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
824 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
825 };
826
827 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
828 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
829 };
830
831 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
832 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
833 };
834
835 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
836 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
837 };
838
839 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
840 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
841 };
842
843 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
844 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
845 };
846
847 template <> struct MappingTraits<ELFYAML::NoteEntry> {
848 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
849 };
850
851 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
852 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
853 };
854
855 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
856 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
857 };
858
859 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
860 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
861 };
862
863 template <> struct MappingTraits<ELFYAML::LinkerOption> {
864 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
865 };
866
867 template <> struct MappingTraits<ELFYAML::CallGraphEntry> {
868 static void mapping(IO &IO, ELFYAML::CallGraphEntry &E);
869 };
870
871 template <> struct MappingTraits<ELFYAML::Relocation> {
872 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
873 };
874
875 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
876 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
877 };
878
879 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
880 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
881 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
882 };
883
884 template <>
885 struct MappingTraits<ELFYAML::Object> {
886 static void mapping(IO &IO, ELFYAML::Object &Object);
887 };
888
889 template <> struct MappingTraits<ELFYAML::SectionOrType> {
890 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType);
891 };
892
893 } // end namespace yaml
894 } // end namespace llvm
895
896 #endif // LLVM_OBJECTYAML_ELFYAML_H
897