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 §ionOrType);
958 };
959
960 } // end namespace yaml
961 } // end namespace llvm
962
963 #endif // LLVM_OBJECTYAML_ELFYAML_H
964