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 llvm::yaml::Hex64 Address;
165 Optional<uint64_t> NumBlocks;
166 Optional<std::vector<BBEntry>> BBEntries;
167 };
168
169 struct StackSizeEntry {
170 llvm::yaml::Hex64 Address;
171 llvm::yaml::Hex64 Size;
172 };
173
174 struct NoteEntry {
175 StringRef Name;
176 yaml::BinaryRef Desc;
177 ELF_NT Type;
178 };
179
180 struct Chunk {
181 enum class ChunkKind {
182 Dynamic,
183 Group,
184 RawContent,
185 Relocation,
186 Relr,
187 NoBits,
188 Note,
189 Hash,
190 GnuHash,
191 Verdef,
192 Verneed,
193 StackSizes,
194 SymtabShndxSection,
195 Symver,
196 ARMIndexTable,
197 MipsABIFlags,
198 Addrsig,
199 LinkerOptions,
200 DependentLibraries,
201 CallGraphProfile,
202 BBAddrMap,
203
204 // Special chunks.
205 SpecialChunksStart,
206 Fill = SpecialChunksStart,
207 SectionHeaderTable,
208 };
209
210 ChunkKind Kind;
211 StringRef Name;
212 Optional<llvm::yaml::Hex64> Offset;
213
214 // Usually chunks are not created implicitly, but rather loaded from YAML.
215 // This flag is used to signal whether this is the case or not.
216 bool IsImplicit;
217
ChunkChunk218 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
219 virtual ~Chunk();
220 };
221
222 struct Section : public Chunk {
223 ELF_SHT Type;
224 Optional<ELF_SHF> Flags;
225 Optional<llvm::yaml::Hex64> Address;
226 Optional<StringRef> Link;
227 llvm::yaml::Hex64 AddressAlign;
228 Optional<llvm::yaml::Hex64> EntSize;
229
230 Optional<yaml::BinaryRef> Content;
231 Optional<llvm::yaml::Hex64> Size;
232
233 // Holds the original section index.
234 unsigned OriginalSecNdx;
235
ChunkSection236 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
237
classofSection238 static bool classof(const Chunk *S) {
239 return S->Kind < ChunkKind::SpecialChunksStart;
240 }
241
242 // Some derived sections might have their own special entries. This method
243 // returns a vector of <entry name, is used> pairs. It is used for section
244 // validation.
getEntriesSection245 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
246 return {};
247 };
248
249 // The following members are used to override section fields which is
250 // useful for creating invalid objects.
251
252 // This can be used to override the sh_addralign field.
253 Optional<llvm::yaml::Hex64> ShAddrAlign;
254
255 // This can be used to override the offset stored in the sh_name field.
256 // It does not affect the name stored in the string table.
257 Optional<llvm::yaml::Hex64> ShName;
258
259 // This can be used to override the sh_offset field. It does not place the
260 // section data at the offset specified.
261 Optional<llvm::yaml::Hex64> ShOffset;
262
263 // This can be used to override the sh_size field. It does not affect the
264 // content written.
265 Optional<llvm::yaml::Hex64> ShSize;
266
267 // This can be used to override the sh_flags field.
268 Optional<llvm::yaml::Hex64> ShFlags;
269
270 // This can be used to override the sh_type field. It is useful when we
271 // want to use specific YAML keys for a section of a particular type to
272 // describe the content, but still want to have a different final type
273 // for the section.
274 Optional<ELF_SHT> ShType;
275 };
276
277 // Fill is a block of data which is placed outside of sections. It is
278 // not present in the sections header table, but it might affect the output file
279 // size and program headers produced.
280 struct Fill : Chunk {
281 Optional<yaml::BinaryRef> Pattern;
282 llvm::yaml::Hex64 Size;
283
FillFill284 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
285
classofFill286 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
287 };
288
289 struct SectionHeaderTable : Chunk {
SectionHeaderTableSectionHeaderTable290 SectionHeaderTable(bool IsImplicit)
291 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
292
classofSectionHeaderTable293 static bool classof(const Chunk *S) {
294 return S->Kind == ChunkKind::SectionHeaderTable;
295 }
296
297 Optional<std::vector<SectionHeader>> Sections;
298 Optional<std::vector<SectionHeader>> Excluded;
299 Optional<bool> NoHeaders;
300
getNumHeadersSectionHeaderTable301 size_t getNumHeaders(size_t SectionsNum) const {
302 if (IsImplicit || isDefault())
303 return SectionsNum;
304 if (NoHeaders)
305 return (*NoHeaders) ? 0 : SectionsNum;
306 return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
307 }
308
isDefaultSectionHeaderTable309 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
310
311 static constexpr StringRef TypeStr = "SectionHeaderTable";
312 };
313
314 struct BBAddrMapSection : Section {
315 Optional<std::vector<BBAddrMapEntry>> Entries;
316
BBAddrMapSectionBBAddrMapSection317 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
318
getEntriesBBAddrMapSection319 std::vector<std::pair<StringRef, bool>> getEntries() const override {
320 return {{"Entries", Entries.hasValue()}};
321 };
322
classofBBAddrMapSection323 static bool classof(const Chunk *S) {
324 return S->Kind == ChunkKind::BBAddrMap;
325 }
326 };
327
328 struct StackSizesSection : Section {
329 Optional<std::vector<StackSizeEntry>> Entries;
330
StackSizesSectionStackSizesSection331 StackSizesSection() : Section(ChunkKind::StackSizes) {}
332
getEntriesStackSizesSection333 std::vector<std::pair<StringRef, bool>> getEntries() const override {
334 return {{"Entries", Entries.hasValue()}};
335 };
336
classofStackSizesSection337 static bool classof(const Chunk *S) {
338 return S->Kind == ChunkKind::StackSizes;
339 }
340
nameMatchesStackSizesSection341 static bool nameMatches(StringRef Name) {
342 return Name == ".stack_sizes";
343 }
344 };
345
346 struct DynamicSection : Section {
347 Optional<std::vector<DynamicEntry>> Entries;
348
DynamicSectionDynamicSection349 DynamicSection() : Section(ChunkKind::Dynamic) {}
350
getEntriesDynamicSection351 std::vector<std::pair<StringRef, bool>> getEntries() const override {
352 return {{"Entries", Entries.hasValue()}};
353 };
354
classofDynamicSection355 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
356 };
357
358 struct RawContentSection : Section {
359 Optional<llvm::yaml::Hex64> Info;
360
RawContentSectionRawContentSection361 RawContentSection() : Section(ChunkKind::RawContent) {}
362
classofRawContentSection363 static bool classof(const Chunk *S) {
364 return S->Kind == ChunkKind::RawContent;
365 }
366
367 // Is used when a content is read as an array of bytes.
368 Optional<std::vector<uint8_t>> ContentBuf;
369 };
370
371 struct NoBitsSection : Section {
NoBitsSectionNoBitsSection372 NoBitsSection() : Section(ChunkKind::NoBits) {}
373
classofNoBitsSection374 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
375 };
376
377 struct NoteSection : Section {
378 Optional<std::vector<ELFYAML::NoteEntry>> Notes;
379
NoteSectionNoteSection380 NoteSection() : Section(ChunkKind::Note) {}
381
getEntriesNoteSection382 std::vector<std::pair<StringRef, bool>> getEntries() const override {
383 return {{"Notes", Notes.hasValue()}};
384 };
385
classofNoteSection386 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
387 };
388
389 struct HashSection : Section {
390 Optional<std::vector<uint32_t>> Bucket;
391 Optional<std::vector<uint32_t>> Chain;
392
getEntriesHashSection393 std::vector<std::pair<StringRef, bool>> getEntries() const override {
394 return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
395 };
396
397 // The following members are used to override section fields.
398 // This is useful for creating invalid objects.
399 Optional<llvm::yaml::Hex64> NBucket;
400 Optional<llvm::yaml::Hex64> NChain;
401
HashSectionHashSection402 HashSection() : Section(ChunkKind::Hash) {}
403
classofHashSection404 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
405 };
406
407 struct GnuHashHeader {
408 // The number of hash buckets.
409 // Not used when dumping the object, but can be used to override
410 // the real number of buckets when emiting an object from a YAML document.
411 Optional<llvm::yaml::Hex32> NBuckets;
412
413 // Index of the first symbol in the dynamic symbol table
414 // included in the hash table.
415 llvm::yaml::Hex32 SymNdx;
416
417 // The number of words in the Bloom filter.
418 // Not used when dumping the object, but can be used to override the real
419 // number of words in the Bloom filter when emiting an object from a YAML
420 // document.
421 Optional<llvm::yaml::Hex32> MaskWords;
422
423 // A shift constant used by the Bloom filter.
424 llvm::yaml::Hex32 Shift2;
425 };
426
427 struct GnuHashSection : Section {
428 Optional<GnuHashHeader> Header;
429 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
430 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
431 Optional<std::vector<llvm::yaml::Hex32>> HashValues;
432
GnuHashSectionGnuHashSection433 GnuHashSection() : Section(ChunkKind::GnuHash) {}
434
getEntriesGnuHashSection435 std::vector<std::pair<StringRef, bool>> getEntries() const override {
436 return {{"Header", Header.hasValue()},
437 {"BloomFilter", BloomFilter.hasValue()},
438 {"HashBuckets", HashBuckets.hasValue()},
439 {"HashValues", HashValues.hasValue()}};
440 };
441
classofGnuHashSection442 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
443 };
444
445 struct VernauxEntry {
446 uint32_t Hash;
447 uint16_t Flags;
448 uint16_t Other;
449 StringRef Name;
450 };
451
452 struct VerneedEntry {
453 uint16_t Version;
454 StringRef File;
455 std::vector<VernauxEntry> AuxV;
456 };
457
458 struct VerneedSection : Section {
459 Optional<std::vector<VerneedEntry>> VerneedV;
460 Optional<llvm::yaml::Hex64> Info;
461
VerneedSectionVerneedSection462 VerneedSection() : Section(ChunkKind::Verneed) {}
463
getEntriesVerneedSection464 std::vector<std::pair<StringRef, bool>> getEntries() const override {
465 return {{"Dependencies", VerneedV.hasValue()}};
466 };
467
classofVerneedSection468 static bool classof(const Chunk *S) {
469 return S->Kind == ChunkKind::Verneed;
470 }
471 };
472
473 struct AddrsigSection : Section {
474 Optional<std::vector<YAMLFlowString>> Symbols;
475
AddrsigSectionAddrsigSection476 AddrsigSection() : Section(ChunkKind::Addrsig) {}
477
getEntriesAddrsigSection478 std::vector<std::pair<StringRef, bool>> getEntries() const override {
479 return {{"Symbols", Symbols.hasValue()}};
480 };
481
classofAddrsigSection482 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
483 };
484
485 struct LinkerOption {
486 StringRef Key;
487 StringRef Value;
488 };
489
490 struct LinkerOptionsSection : Section {
491 Optional<std::vector<LinkerOption>> Options;
492
LinkerOptionsSectionLinkerOptionsSection493 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
494
getEntriesLinkerOptionsSection495 std::vector<std::pair<StringRef, bool>> getEntries() const override {
496 return {{"Options", Options.hasValue()}};
497 };
498
classofLinkerOptionsSection499 static bool classof(const Chunk *S) {
500 return S->Kind == ChunkKind::LinkerOptions;
501 }
502 };
503
504 struct DependentLibrariesSection : Section {
505 Optional<std::vector<YAMLFlowString>> Libs;
506
DependentLibrariesSectionDependentLibrariesSection507 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
508
getEntriesDependentLibrariesSection509 std::vector<std::pair<StringRef, bool>> getEntries() const override {
510 return {{"Libraries", Libs.hasValue()}};
511 };
512
classofDependentLibrariesSection513 static bool classof(const Chunk *S) {
514 return S->Kind == ChunkKind::DependentLibraries;
515 }
516 };
517
518 // Represents the call graph profile section entry.
519 struct CallGraphEntryWeight {
520 // The weight of the edge.
521 uint64_t Weight;
522 };
523
524 struct CallGraphProfileSection : Section {
525 Optional<std::vector<CallGraphEntryWeight>> Entries;
526
CallGraphProfileSectionCallGraphProfileSection527 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
528
getEntriesCallGraphProfileSection529 std::vector<std::pair<StringRef, bool>> getEntries() const override {
530 return {{"Entries", Entries.hasValue()}};
531 };
532
classofCallGraphProfileSection533 static bool classof(const Chunk *S) {
534 return S->Kind == ChunkKind::CallGraphProfile;
535 }
536 };
537
538 struct SymverSection : Section {
539 Optional<std::vector<uint16_t>> Entries;
540
SymverSectionSymverSection541 SymverSection() : Section(ChunkKind::Symver) {}
542
getEntriesSymverSection543 std::vector<std::pair<StringRef, bool>> getEntries() const override {
544 return {{"Entries", Entries.hasValue()}};
545 };
546
classofSymverSection547 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
548 };
549
550 struct VerdefEntry {
551 Optional<uint16_t> Version;
552 Optional<uint16_t> Flags;
553 Optional<uint16_t> VersionNdx;
554 Optional<uint32_t> Hash;
555 std::vector<StringRef> VerNames;
556 };
557
558 struct VerdefSection : Section {
559 Optional<std::vector<VerdefEntry>> Entries;
560 Optional<llvm::yaml::Hex64> Info;
561
VerdefSectionVerdefSection562 VerdefSection() : Section(ChunkKind::Verdef) {}
563
getEntriesVerdefSection564 std::vector<std::pair<StringRef, bool>> getEntries() const override {
565 return {{"Entries", Entries.hasValue()}};
566 };
567
classofVerdefSection568 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
569 };
570
571 struct GroupSection : Section {
572 // Members of a group contain a flag and a list of section indices
573 // that are part of the group.
574 Optional<std::vector<SectionOrType>> Members;
575 Optional<StringRef> Signature; /* Info */
576
GroupSectionGroupSection577 GroupSection() : Section(ChunkKind::Group) {}
578
getEntriesGroupSection579 std::vector<std::pair<StringRef, bool>> getEntries() const override {
580 return {{"Members", Members.hasValue()}};
581 };
582
classofGroupSection583 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
584 };
585
586 struct Relocation {
587 llvm::yaml::Hex64 Offset;
588 YAMLIntUInt Addend;
589 ELF_REL Type;
590 Optional<StringRef> Symbol;
591 };
592
593 struct RelocationSection : Section {
594 Optional<std::vector<Relocation>> Relocations;
595 StringRef RelocatableSec; /* Info */
596
RelocationSectionRelocationSection597 RelocationSection() : Section(ChunkKind::Relocation) {}
598
getEntriesRelocationSection599 std::vector<std::pair<StringRef, bool>> getEntries() const override {
600 return {{"Relocations", Relocations.hasValue()}};
601 };
602
classofRelocationSection603 static bool classof(const Chunk *S) {
604 return S->Kind == ChunkKind::Relocation;
605 }
606 };
607
608 struct RelrSection : Section {
609 Optional<std::vector<llvm::yaml::Hex64>> Entries;
610
RelrSectionRelrSection611 RelrSection() : Section(ChunkKind::Relr) {}
612
getEntriesRelrSection613 std::vector<std::pair<StringRef, bool>> getEntries() const override {
614 return {{"Entries", Entries.hasValue()}};
615 };
616
classofRelrSection617 static bool classof(const Chunk *S) {
618 return S->Kind == ChunkKind::Relr;
619 }
620 };
621
622 struct SymtabShndxSection : Section {
623 Optional<std::vector<uint32_t>> Entries;
624
SymtabShndxSectionSymtabShndxSection625 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
626
getEntriesSymtabShndxSection627 std::vector<std::pair<StringRef, bool>> getEntries() const override {
628 return {{"Entries", Entries.hasValue()}};
629 };
630
classofSymtabShndxSection631 static bool classof(const Chunk *S) {
632 return S->Kind == ChunkKind::SymtabShndxSection;
633 }
634 };
635
636 struct ARMIndexTableEntry {
637 llvm::yaml::Hex32 Offset;
638 llvm::yaml::Hex32 Value;
639 };
640
641 struct ARMIndexTableSection : Section {
642 Optional<std::vector<ARMIndexTableEntry>> Entries;
643
ARMIndexTableSectionARMIndexTableSection644 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
645
getEntriesARMIndexTableSection646 std::vector<std::pair<StringRef, bool>> getEntries() const override {
647 return {{"Entries", Entries.hasValue()}};
648 };
649
classofARMIndexTableSection650 static bool classof(const Chunk *S) {
651 return S->Kind == ChunkKind::ARMIndexTable;
652 }
653 };
654
655 // Represents .MIPS.abiflags section
656 struct MipsABIFlags : Section {
657 llvm::yaml::Hex16 Version;
658 MIPS_ISA ISALevel;
659 llvm::yaml::Hex8 ISARevision;
660 MIPS_AFL_REG GPRSize;
661 MIPS_AFL_REG CPR1Size;
662 MIPS_AFL_REG CPR2Size;
663 MIPS_ABI_FP FpABI;
664 MIPS_AFL_EXT ISAExtension;
665 MIPS_AFL_ASE ASEs;
666 MIPS_AFL_FLAGS1 Flags1;
667 llvm::yaml::Hex32 Flags2;
668
MipsABIFlagsMipsABIFlags669 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
670
classofMipsABIFlags671 static bool classof(const Chunk *S) {
672 return S->Kind == ChunkKind::MipsABIFlags;
673 }
674 };
675
676 struct ProgramHeader {
677 ELF_PT Type;
678 ELF_PF Flags;
679 llvm::yaml::Hex64 VAddr;
680 llvm::yaml::Hex64 PAddr;
681 Optional<llvm::yaml::Hex64> Align;
682 Optional<llvm::yaml::Hex64> FileSize;
683 Optional<llvm::yaml::Hex64> MemSize;
684 Optional<llvm::yaml::Hex64> Offset;
685 Optional<StringRef> FirstSec;
686 Optional<StringRef> LastSec;
687
688 // This vector contains all chunks from [FirstSec, LastSec].
689 std::vector<Chunk *> Chunks;
690 };
691
692 struct Object {
693 FileHeader Header;
694 std::vector<ProgramHeader> ProgramHeaders;
695
696 // An object might contain output section descriptions as well as
697 // custom data that does not belong to any section.
698 std::vector<std::unique_ptr<Chunk>> Chunks;
699
700 // Although in reality the symbols reside in a section, it is a lot
701 // cleaner and nicer if we read them from the YAML as a separate
702 // top-level key, which automatically ensures that invariants like there
703 // being a single SHT_SYMTAB section are upheld.
704 Optional<std::vector<Symbol>> Symbols;
705 Optional<std::vector<Symbol>> DynamicSymbols;
706 Optional<DWARFYAML::Data> DWARF;
707
getSectionsObject708 std::vector<Section *> getSections() {
709 std::vector<Section *> Ret;
710 for (const std::unique_ptr<Chunk> &Sec : Chunks)
711 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
712 Ret.push_back(S);
713 return Ret;
714 }
715
getSectionHeaderTableObject716 const SectionHeaderTable &getSectionHeaderTable() const {
717 for (const std::unique_ptr<Chunk> &C : Chunks)
718 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
719 return *S;
720 llvm_unreachable("the section header table chunk must always be present");
721 }
722
723 unsigned getMachine() const;
724 };
725
726 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
727 const NoBitsSection &S);
728
729 } // end namespace ELFYAML
730 } // end namespace llvm
731
732 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)733 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
734 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
735 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
736 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
737 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
738 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
739 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
740 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
741 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
742 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
743 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
744 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
745 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
746 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
747 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
748 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
749
750 namespace llvm {
751 namespace yaml {
752
753 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
754 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
755 raw_ostream &Out);
756 static StringRef input(StringRef Scalar, void *Ctx,
757 ELFYAML::YAMLIntUInt &Val);
758 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
759 };
760
761 template <>
762 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
763 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
764 };
765
766 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
767 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
768 };
769
770 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
771 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
772 };
773
774 template <>
775 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
776 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
777 };
778
779 template <>
780 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
781 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
782 };
783
784 template <>
785 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
786 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
787 };
788
789 template <>
790 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
791 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
792 };
793
794 template <>
795 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
796 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
797 };
798
799 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
800 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
801 };
802
803 template <>
804 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
805 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
806 };
807
808 template <>
809 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
810 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
811 };
812
813 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
814 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
815 };
816
817 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
818 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
819 };
820
821 template <>
822 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
823 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
824 };
825
826 template <>
827 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
828 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
829 };
830
831 template <>
832 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
833 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
834 };
835
836 template <>
837 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
838 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
839 };
840
841 template <>
842 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
843 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
844 };
845
846 template <>
847 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
848 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
849 };
850
851 template <>
852 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
853 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
854 };
855
856 template <>
857 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
858 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
859 };
860
861 template <>
862 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
863 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
864 };
865
866 template <>
867 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
868 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
869 };
870
871 template <>
872 struct MappingTraits<ELFYAML::FileHeader> {
873 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
874 };
875
876 template <> struct MappingTraits<ELFYAML::SectionHeader> {
877 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
878 };
879
880 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
881 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
882 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
883 };
884
885 template <>
886 struct MappingTraits<ELFYAML::Symbol> {
887 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
888 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
889 };
890
891 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
892 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
893 };
894
895 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
896 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
897 };
898
899 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
900 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
901 };
902
903 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
904 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
905 };
906
907 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
908 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
909 };
910
911 template <> struct MappingTraits<ELFYAML::NoteEntry> {
912 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
913 };
914
915 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
916 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
917 };
918
919 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
920 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
921 };
922
923 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
924 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
925 };
926
927 template <> struct MappingTraits<ELFYAML::LinkerOption> {
928 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
929 };
930
931 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
932 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
933 };
934
935 template <> struct MappingTraits<ELFYAML::Relocation> {
936 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
937 };
938
939 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
940 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
941 };
942
943 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
944 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
945 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
946 };
947
948 template <>
949 struct MappingTraits<ELFYAML::Object> {
950 static void mapping(IO &IO, ELFYAML::Object &Object);
951 };
952
953 template <> struct MappingTraits<ELFYAML::SectionOrType> {
954 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType);
955 };
956
957 } // end namespace yaml
958 } // end namespace llvm
959
960 #endif // LLVM_OBJECTYAML_ELFYAML_H
961