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