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 Optional<StringRef> SectionHeaderStringTable;
122
123 Optional<llvm::yaml::Hex64> EPhOff;
124 Optional<llvm::yaml::Hex16> EPhEntSize;
125 Optional<llvm::yaml::Hex16> EPhNum;
126 Optional<llvm::yaml::Hex16> EShEntSize;
127 Optional<llvm::yaml::Hex64> EShOff;
128 Optional<llvm::yaml::Hex16> EShNum;
129 Optional<llvm::yaml::Hex16> EShStrNdx;
130 };
131
132 struct SectionHeader {
133 StringRef Name;
134 };
135
136 struct Symbol {
137 StringRef Name;
138 ELF_STT Type;
139 Optional<StringRef> Section;
140 Optional<ELF_SHN> Index;
141 ELF_STB Binding;
142 Optional<llvm::yaml::Hex64> Value;
143 Optional<llvm::yaml::Hex64> Size;
144 Optional<uint8_t> Other;
145
146 Optional<uint32_t> StName;
147 };
148
149 struct SectionOrType {
150 StringRef sectionNameOrType;
151 };
152
153 struct DynamicEntry {
154 ELF_DYNTAG Tag;
155 llvm::yaml::Hex64 Val;
156 };
157
158 struct BBAddrMapEntry {
159 struct BBEntry {
160 llvm::yaml::Hex64 AddressOffset;
161 llvm::yaml::Hex64 Size;
162 llvm::yaml::Hex64 Metadata;
163 };
164 uint8_t Version;
165 llvm::yaml::Hex8 Feature;
166 llvm::yaml::Hex64 Address;
167 Optional<uint64_t> NumBlocks;
168 Optional<std::vector<BBEntry>> BBEntries;
169 };
170
171 struct StackSizeEntry {
172 llvm::yaml::Hex64 Address;
173 llvm::yaml::Hex64 Size;
174 };
175
176 struct NoteEntry {
177 StringRef Name;
178 yaml::BinaryRef Desc;
179 ELF_NT Type;
180 };
181
182 struct Chunk {
183 enum class ChunkKind {
184 Dynamic,
185 Group,
186 RawContent,
187 Relocation,
188 Relr,
189 NoBits,
190 Note,
191 Hash,
192 GnuHash,
193 Verdef,
194 Verneed,
195 StackSizes,
196 SymtabShndxSection,
197 Symver,
198 ARMIndexTable,
199 MipsABIFlags,
200 Addrsig,
201 LinkerOptions,
202 DependentLibraries,
203 CallGraphProfile,
204 BBAddrMap,
205
206 // Special chunks.
207 SpecialChunksStart,
208 Fill = SpecialChunksStart,
209 SectionHeaderTable,
210 };
211
212 ChunkKind Kind;
213 StringRef Name;
214 Optional<llvm::yaml::Hex64> Offset;
215
216 // Usually chunks are not created implicitly, but rather loaded from YAML.
217 // This flag is used to signal whether this is the case or not.
218 bool IsImplicit;
219
ChunkChunk220 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
221 virtual ~Chunk();
222 };
223
224 struct Section : public Chunk {
225 ELF_SHT Type;
226 Optional<ELF_SHF> Flags;
227 Optional<llvm::yaml::Hex64> Address;
228 Optional<StringRef> Link;
229 llvm::yaml::Hex64 AddressAlign;
230 Optional<llvm::yaml::Hex64> EntSize;
231
232 Optional<yaml::BinaryRef> Content;
233 Optional<llvm::yaml::Hex64> Size;
234
235 // Holds the original section index.
236 unsigned OriginalSecNdx;
237
ChunkSection238 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
239
classofSection240 static bool classof(const Chunk *S) {
241 return S->Kind < ChunkKind::SpecialChunksStart;
242 }
243
244 // Some derived sections might have their own special entries. This method
245 // returns a vector of <entry name, is used> pairs. It is used for section
246 // validation.
getEntriesSection247 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
248 return {};
249 };
250
251 // The following members are used to override section fields which is
252 // useful for creating invalid objects.
253
254 // This can be used to override the sh_addralign field.
255 Optional<llvm::yaml::Hex64> ShAddrAlign;
256
257 // This can be used to override the offset stored in the sh_name field.
258 // It does not affect the name stored in the string table.
259 Optional<llvm::yaml::Hex64> ShName;
260
261 // This can be used to override the sh_offset field. It does not place the
262 // section data at the offset specified.
263 Optional<llvm::yaml::Hex64> ShOffset;
264
265 // This can be used to override the sh_size field. It does not affect the
266 // content written.
267 Optional<llvm::yaml::Hex64> ShSize;
268
269 // This can be used to override the sh_flags field.
270 Optional<llvm::yaml::Hex64> ShFlags;
271
272 // This can be used to override the sh_type field. It is useful when we
273 // want to use specific YAML keys for a section of a particular type to
274 // describe the content, but still want to have a different final type
275 // for the section.
276 Optional<ELF_SHT> ShType;
277 };
278
279 // Fill is a block of data which is placed outside of sections. It is
280 // not present in the sections header table, but it might affect the output file
281 // size and program headers produced.
282 struct Fill : Chunk {
283 Optional<yaml::BinaryRef> Pattern;
284 llvm::yaml::Hex64 Size;
285
FillFill286 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
287
classofFill288 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
289 };
290
291 struct SectionHeaderTable : Chunk {
SectionHeaderTableSectionHeaderTable292 SectionHeaderTable(bool IsImplicit)
293 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
294
classofSectionHeaderTable295 static bool classof(const Chunk *S) {
296 return S->Kind == ChunkKind::SectionHeaderTable;
297 }
298
299 Optional<std::vector<SectionHeader>> Sections;
300 Optional<std::vector<SectionHeader>> Excluded;
301 Optional<bool> NoHeaders;
302
getNumHeadersSectionHeaderTable303 size_t getNumHeaders(size_t SectionsNum) const {
304 if (IsImplicit || isDefault())
305 return SectionsNum;
306 if (NoHeaders)
307 return (*NoHeaders) ? 0 : SectionsNum;
308 return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
309 }
310
isDefaultSectionHeaderTable311 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
312
313 static constexpr StringRef TypeStr = "SectionHeaderTable";
314 };
315
316 struct BBAddrMapSection : Section {
317 Optional<std::vector<BBAddrMapEntry>> Entries;
318
BBAddrMapSectionBBAddrMapSection319 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
320
getEntriesBBAddrMapSection321 std::vector<std::pair<StringRef, bool>> getEntries() const override {
322 return {{"Entries", Entries.has_value()}};
323 };
324
classofBBAddrMapSection325 static bool classof(const Chunk *S) {
326 return S->Kind == ChunkKind::BBAddrMap;
327 }
328 };
329
330 struct StackSizesSection : Section {
331 Optional<std::vector<StackSizeEntry>> Entries;
332
StackSizesSectionStackSizesSection333 StackSizesSection() : Section(ChunkKind::StackSizes) {}
334
getEntriesStackSizesSection335 std::vector<std::pair<StringRef, bool>> getEntries() const override {
336 return {{"Entries", Entries.has_value()}};
337 };
338
classofStackSizesSection339 static bool classof(const Chunk *S) {
340 return S->Kind == ChunkKind::StackSizes;
341 }
342
nameMatchesStackSizesSection343 static bool nameMatches(StringRef Name) {
344 return Name == ".stack_sizes";
345 }
346 };
347
348 struct DynamicSection : Section {
349 Optional<std::vector<DynamicEntry>> Entries;
350
DynamicSectionDynamicSection351 DynamicSection() : Section(ChunkKind::Dynamic) {}
352
getEntriesDynamicSection353 std::vector<std::pair<StringRef, bool>> getEntries() const override {
354 return {{"Entries", Entries.has_value()}};
355 };
356
classofDynamicSection357 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
358 };
359
360 struct RawContentSection : Section {
361 Optional<llvm::yaml::Hex64> Info;
362
RawContentSectionRawContentSection363 RawContentSection() : Section(ChunkKind::RawContent) {}
364
classofRawContentSection365 static bool classof(const Chunk *S) {
366 return S->Kind == ChunkKind::RawContent;
367 }
368
369 // Is used when a content is read as an array of bytes.
370 Optional<std::vector<uint8_t>> ContentBuf;
371 };
372
373 struct NoBitsSection : Section {
NoBitsSectionNoBitsSection374 NoBitsSection() : Section(ChunkKind::NoBits) {}
375
classofNoBitsSection376 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
377 };
378
379 struct NoteSection : Section {
380 Optional<std::vector<ELFYAML::NoteEntry>> Notes;
381
NoteSectionNoteSection382 NoteSection() : Section(ChunkKind::Note) {}
383
getEntriesNoteSection384 std::vector<std::pair<StringRef, bool>> getEntries() const override {
385 return {{"Notes", Notes.has_value()}};
386 };
387
classofNoteSection388 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
389 };
390
391 struct HashSection : Section {
392 Optional<std::vector<uint32_t>> Bucket;
393 Optional<std::vector<uint32_t>> Chain;
394
getEntriesHashSection395 std::vector<std::pair<StringRef, bool>> getEntries() const override {
396 return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
397 };
398
399 // The following members are used to override section fields.
400 // This is useful for creating invalid objects.
401 Optional<llvm::yaml::Hex64> NBucket;
402 Optional<llvm::yaml::Hex64> NChain;
403
HashSectionHashSection404 HashSection() : Section(ChunkKind::Hash) {}
405
classofHashSection406 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
407 };
408
409 struct GnuHashHeader {
410 // The number of hash buckets.
411 // Not used when dumping the object, but can be used to override
412 // the real number of buckets when emiting an object from a YAML document.
413 Optional<llvm::yaml::Hex32> NBuckets;
414
415 // Index of the first symbol in the dynamic symbol table
416 // included in the hash table.
417 llvm::yaml::Hex32 SymNdx;
418
419 // The number of words in the Bloom filter.
420 // Not used when dumping the object, but can be used to override the real
421 // number of words in the Bloom filter when emiting an object from a YAML
422 // document.
423 Optional<llvm::yaml::Hex32> MaskWords;
424
425 // A shift constant used by the Bloom filter.
426 llvm::yaml::Hex32 Shift2;
427 };
428
429 struct GnuHashSection : Section {
430 Optional<GnuHashHeader> Header;
431 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
432 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
433 Optional<std::vector<llvm::yaml::Hex32>> HashValues;
434
GnuHashSectionGnuHashSection435 GnuHashSection() : Section(ChunkKind::GnuHash) {}
436
getEntriesGnuHashSection437 std::vector<std::pair<StringRef, bool>> getEntries() const override {
438 return {{"Header", Header.has_value()},
439 {"BloomFilter", BloomFilter.has_value()},
440 {"HashBuckets", HashBuckets.has_value()},
441 {"HashValues", HashValues.has_value()}};
442 };
443
classofGnuHashSection444 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
445 };
446
447 struct VernauxEntry {
448 uint32_t Hash;
449 uint16_t Flags;
450 uint16_t Other;
451 StringRef Name;
452 };
453
454 struct VerneedEntry {
455 uint16_t Version;
456 StringRef File;
457 std::vector<VernauxEntry> AuxV;
458 };
459
460 struct VerneedSection : Section {
461 Optional<std::vector<VerneedEntry>> VerneedV;
462 Optional<llvm::yaml::Hex64> Info;
463
VerneedSectionVerneedSection464 VerneedSection() : Section(ChunkKind::Verneed) {}
465
getEntriesVerneedSection466 std::vector<std::pair<StringRef, bool>> getEntries() const override {
467 return {{"Dependencies", VerneedV.has_value()}};
468 };
469
classofVerneedSection470 static bool classof(const Chunk *S) {
471 return S->Kind == ChunkKind::Verneed;
472 }
473 };
474
475 struct AddrsigSection : Section {
476 Optional<std::vector<YAMLFlowString>> Symbols;
477
AddrsigSectionAddrsigSection478 AddrsigSection() : Section(ChunkKind::Addrsig) {}
479
getEntriesAddrsigSection480 std::vector<std::pair<StringRef, bool>> getEntries() const override {
481 return {{"Symbols", Symbols.has_value()}};
482 };
483
classofAddrsigSection484 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
485 };
486
487 struct LinkerOption {
488 StringRef Key;
489 StringRef Value;
490 };
491
492 struct LinkerOptionsSection : Section {
493 Optional<std::vector<LinkerOption>> Options;
494
LinkerOptionsSectionLinkerOptionsSection495 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
496
getEntriesLinkerOptionsSection497 std::vector<std::pair<StringRef, bool>> getEntries() const override {
498 return {{"Options", Options.has_value()}};
499 };
500
classofLinkerOptionsSection501 static bool classof(const Chunk *S) {
502 return S->Kind == ChunkKind::LinkerOptions;
503 }
504 };
505
506 struct DependentLibrariesSection : Section {
507 Optional<std::vector<YAMLFlowString>> Libs;
508
DependentLibrariesSectionDependentLibrariesSection509 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
510
getEntriesDependentLibrariesSection511 std::vector<std::pair<StringRef, bool>> getEntries() const override {
512 return {{"Libraries", Libs.has_value()}};
513 };
514
classofDependentLibrariesSection515 static bool classof(const Chunk *S) {
516 return S->Kind == ChunkKind::DependentLibraries;
517 }
518 };
519
520 // Represents the call graph profile section entry.
521 struct CallGraphEntryWeight {
522 // The weight of the edge.
523 uint64_t Weight;
524 };
525
526 struct CallGraphProfileSection : Section {
527 Optional<std::vector<CallGraphEntryWeight>> Entries;
528
CallGraphProfileSectionCallGraphProfileSection529 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
530
getEntriesCallGraphProfileSection531 std::vector<std::pair<StringRef, bool>> getEntries() const override {
532 return {{"Entries", Entries.has_value()}};
533 };
534
classofCallGraphProfileSection535 static bool classof(const Chunk *S) {
536 return S->Kind == ChunkKind::CallGraphProfile;
537 }
538 };
539
540 struct SymverSection : Section {
541 Optional<std::vector<uint16_t>> Entries;
542
SymverSectionSymverSection543 SymverSection() : Section(ChunkKind::Symver) {}
544
getEntriesSymverSection545 std::vector<std::pair<StringRef, bool>> getEntries() const override {
546 return {{"Entries", Entries.has_value()}};
547 };
548
classofSymverSection549 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
550 };
551
552 struct VerdefEntry {
553 Optional<uint16_t> Version;
554 Optional<uint16_t> Flags;
555 Optional<uint16_t> VersionNdx;
556 Optional<uint32_t> Hash;
557 std::vector<StringRef> VerNames;
558 };
559
560 struct VerdefSection : Section {
561 Optional<std::vector<VerdefEntry>> Entries;
562 Optional<llvm::yaml::Hex64> Info;
563
VerdefSectionVerdefSection564 VerdefSection() : Section(ChunkKind::Verdef) {}
565
getEntriesVerdefSection566 std::vector<std::pair<StringRef, bool>> getEntries() const override {
567 return {{"Entries", Entries.has_value()}};
568 };
569
classofVerdefSection570 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
571 };
572
573 struct GroupSection : Section {
574 // Members of a group contain a flag and a list of section indices
575 // that are part of the group.
576 Optional<std::vector<SectionOrType>> Members;
577 Optional<StringRef> Signature; /* Info */
578
GroupSectionGroupSection579 GroupSection() : Section(ChunkKind::Group) {}
580
getEntriesGroupSection581 std::vector<std::pair<StringRef, bool>> getEntries() const override {
582 return {{"Members", Members.has_value()}};
583 };
584
classofGroupSection585 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
586 };
587
588 struct Relocation {
589 llvm::yaml::Hex64 Offset;
590 YAMLIntUInt Addend;
591 ELF_REL Type;
592 Optional<StringRef> Symbol;
593 };
594
595 struct RelocationSection : Section {
596 Optional<std::vector<Relocation>> Relocations;
597 StringRef RelocatableSec; /* Info */
598
RelocationSectionRelocationSection599 RelocationSection() : Section(ChunkKind::Relocation) {}
600
getEntriesRelocationSection601 std::vector<std::pair<StringRef, bool>> getEntries() const override {
602 return {{"Relocations", Relocations.has_value()}};
603 };
604
classofRelocationSection605 static bool classof(const Chunk *S) {
606 return S->Kind == ChunkKind::Relocation;
607 }
608 };
609
610 struct RelrSection : Section {
611 Optional<std::vector<llvm::yaml::Hex64>> Entries;
612
RelrSectionRelrSection613 RelrSection() : Section(ChunkKind::Relr) {}
614
getEntriesRelrSection615 std::vector<std::pair<StringRef, bool>> getEntries() const override {
616 return {{"Entries", Entries.has_value()}};
617 };
618
classofRelrSection619 static bool classof(const Chunk *S) {
620 return S->Kind == ChunkKind::Relr;
621 }
622 };
623
624 struct SymtabShndxSection : Section {
625 Optional<std::vector<uint32_t>> Entries;
626
SymtabShndxSectionSymtabShndxSection627 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
628
getEntriesSymtabShndxSection629 std::vector<std::pair<StringRef, bool>> getEntries() const override {
630 return {{"Entries", Entries.has_value()}};
631 };
632
classofSymtabShndxSection633 static bool classof(const Chunk *S) {
634 return S->Kind == ChunkKind::SymtabShndxSection;
635 }
636 };
637
638 struct ARMIndexTableEntry {
639 llvm::yaml::Hex32 Offset;
640 llvm::yaml::Hex32 Value;
641 };
642
643 struct ARMIndexTableSection : Section {
644 Optional<std::vector<ARMIndexTableEntry>> Entries;
645
ARMIndexTableSectionARMIndexTableSection646 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
647
getEntriesARMIndexTableSection648 std::vector<std::pair<StringRef, bool>> getEntries() const override {
649 return {{"Entries", Entries.has_value()}};
650 };
651
classofARMIndexTableSection652 static bool classof(const Chunk *S) {
653 return S->Kind == ChunkKind::ARMIndexTable;
654 }
655 };
656
657 // Represents .MIPS.abiflags section
658 struct MipsABIFlags : Section {
659 llvm::yaml::Hex16 Version;
660 MIPS_ISA ISALevel;
661 llvm::yaml::Hex8 ISARevision;
662 MIPS_AFL_REG GPRSize;
663 MIPS_AFL_REG CPR1Size;
664 MIPS_AFL_REG CPR2Size;
665 MIPS_ABI_FP FpABI;
666 MIPS_AFL_EXT ISAExtension;
667 MIPS_AFL_ASE ASEs;
668 MIPS_AFL_FLAGS1 Flags1;
669 llvm::yaml::Hex32 Flags2;
670
MipsABIFlagsMipsABIFlags671 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
672
classofMipsABIFlags673 static bool classof(const Chunk *S) {
674 return S->Kind == ChunkKind::MipsABIFlags;
675 }
676 };
677
678 struct ProgramHeader {
679 ELF_PT Type;
680 ELF_PF Flags;
681 llvm::yaml::Hex64 VAddr;
682 llvm::yaml::Hex64 PAddr;
683 Optional<llvm::yaml::Hex64> Align;
684 Optional<llvm::yaml::Hex64> FileSize;
685 Optional<llvm::yaml::Hex64> MemSize;
686 Optional<llvm::yaml::Hex64> Offset;
687 Optional<StringRef> FirstSec;
688 Optional<StringRef> LastSec;
689
690 // This vector contains all chunks from [FirstSec, LastSec].
691 std::vector<Chunk *> Chunks;
692 };
693
694 struct Object {
695 FileHeader Header;
696 std::vector<ProgramHeader> ProgramHeaders;
697
698 // An object might contain output section descriptions as well as
699 // custom data that does not belong to any section.
700 std::vector<std::unique_ptr<Chunk>> Chunks;
701
702 // Although in reality the symbols reside in a section, it is a lot
703 // cleaner and nicer if we read them from the YAML as a separate
704 // top-level key, which automatically ensures that invariants like there
705 // being a single SHT_SYMTAB section are upheld.
706 Optional<std::vector<Symbol>> Symbols;
707 Optional<std::vector<Symbol>> DynamicSymbols;
708 Optional<DWARFYAML::Data> DWARF;
709
getSectionsObject710 std::vector<Section *> getSections() {
711 std::vector<Section *> Ret;
712 for (const std::unique_ptr<Chunk> &Sec : Chunks)
713 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
714 Ret.push_back(S);
715 return Ret;
716 }
717
getSectionHeaderTableObject718 const SectionHeaderTable &getSectionHeaderTable() const {
719 for (const std::unique_ptr<Chunk> &C : Chunks)
720 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
721 return *S;
722 llvm_unreachable("the section header table chunk must always be present");
723 }
724
725 ELF_ELFOSABI getOSAbi() const;
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::CallGraphEntryWeight)
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::CallGraphEntryWeight> {
935 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &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