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
29namespace llvm {
30namespace ELFYAML {
31
32StringRef dropUniqueSuffix(StringRef S);
33std::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.
45LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
46LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
47LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
48LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
49LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
50LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
51// Just use 64, since it can hold 32-bit values too.
52LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
53// Just use 64, since it can hold 32-bit values too.
54LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
55LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
56LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
57LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
58LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
59// Just use 64, since it can hold 32-bit values too.
60LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
61LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
62LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
63LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
64LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)
65
66LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
67LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
68LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
69LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
70LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
71LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
72
73LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
74LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
75
76template <class ELFT>
77unsigned 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.
113struct 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
133struct SectionHeader {
134 StringRef Name;
135};
136
137struct 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
150struct SectionOrType {
151 StringRef sectionNameOrType;
152};
153
154struct DynamicEntry {
155 ELF_DYNTAG Tag;
156 llvm::yaml::Hex64 Val;
157};
158
159struct BBAddrMapEntry {
160 struct BBEntry {
161 uint32_t ID;
162 llvm::yaml::Hex64 AddressOffset;
163 llvm::yaml::Hex64 Size;
164 llvm::yaml::Hex64 Metadata;
165 std::optional<std::vector<llvm::yaml::Hex64>> CallsiteOffsets;
166 };
167 uint8_t Version;
168 llvm::yaml::Hex8 Feature;
169
170 struct BBRangeEntry {
171 llvm::yaml::Hex64 BaseAddress;
172 std::optional<uint64_t> NumBlocks;
173 std::optional<std::vector<BBEntry>> BBEntries;
174 };
175
176 std::optional<uint64_t> NumBBRanges;
177 std::optional<std::vector<BBRangeEntry>> BBRanges;
178
179 llvm::yaml::Hex64 getFunctionAddress() const {
180 if (!BBRanges || BBRanges->empty())
181 return 0;
182 return BBRanges->front().BaseAddress;
183 }
184
185 // Returns if any BB entries have non-empty callsite offsets.
186 bool hasAnyCallsiteOffsets() const {
187 if (!BBRanges)
188 return false;
189 for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *BBRanges) {
190 if (!BBR.BBEntries)
191 continue;
192 for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries)
193 if (BBE.CallsiteOffsets && !BBE.CallsiteOffsets->empty())
194 return true;
195 }
196 return false;
197 }
198};
199
200struct PGOAnalysisMapEntry {
201 struct PGOBBEntry {
202 struct SuccessorEntry {
203 uint32_t ID;
204 llvm::yaml::Hex32 BrProb;
205 };
206 std::optional<uint64_t> BBFreq;
207 std::optional<std::vector<SuccessorEntry>> Successors;
208 };
209 std::optional<uint64_t> FuncEntryCount;
210 std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
211};
212
213struct StackSizeEntry {
214 llvm::yaml::Hex64 Address;
215 llvm::yaml::Hex64 Size;
216};
217
218struct NoteEntry {
219 StringRef Name;
220 yaml::BinaryRef Desc;
221 ELF_NT Type;
222};
223
224struct Chunk {
225 enum class ChunkKind {
226 Dynamic,
227 Group,
228 RawContent,
229 Relocation,
230 Relr,
231 NoBits,
232 Note,
233 Hash,
234 GnuHash,
235 Verdef,
236 Verneed,
237 StackSizes,
238 SymtabShndxSection,
239 Symver,
240 ARMIndexTable,
241 MipsABIFlags,
242 Addrsig,
243 LinkerOptions,
244 DependentLibraries,
245 CallGraphProfile,
246 BBAddrMap,
247
248 // Special chunks.
249 SpecialChunksStart,
250 Fill = SpecialChunksStart,
251 SectionHeaderTable,
252 };
253
254 ChunkKind Kind;
255 StringRef Name;
256 std::optional<llvm::yaml::Hex64> Offset;
257
258 // Usually chunks are not created implicitly, but rather loaded from YAML.
259 // This flag is used to signal whether this is the case or not.
260 bool IsImplicit;
261
262 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
263 virtual ~Chunk();
264};
265
266struct Section : public Chunk {
267 ELF_SHT Type;
268 std::optional<ELF_SHF> Flags;
269 std::optional<llvm::yaml::Hex64> Address;
270 std::optional<StringRef> Link;
271 llvm::yaml::Hex64 AddressAlign;
272 std::optional<llvm::yaml::Hex64> EntSize;
273
274 std::optional<yaml::BinaryRef> Content;
275 std::optional<llvm::yaml::Hex64> Size;
276
277 // Holds the original section index.
278 unsigned OriginalSecNdx;
279
280 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
281
282 static bool classof(const Chunk *S) {
283 return S->Kind < ChunkKind::SpecialChunksStart;
284 }
285
286 // Some derived sections might have their own special entries. This method
287 // returns a vector of <entry name, is used> pairs. It is used for section
288 // validation.
289 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
290 return {};
291 };
292
293 // The following members are used to override section fields which is
294 // useful for creating invalid objects.
295
296 // This can be used to override the sh_addralign field.
297 std::optional<llvm::yaml::Hex64> ShAddrAlign;
298
299 // This can be used to override the offset stored in the sh_name field.
300 // It does not affect the name stored in the string table.
301 std::optional<llvm::yaml::Hex64> ShName;
302
303 // This can be used to override the sh_offset field. It does not place the
304 // section data at the offset specified.
305 std::optional<llvm::yaml::Hex64> ShOffset;
306
307 // This can be used to override the sh_size field. It does not affect the
308 // content written.
309 std::optional<llvm::yaml::Hex64> ShSize;
310
311 // This can be used to override the sh_flags field.
312 std::optional<llvm::yaml::Hex64> ShFlags;
313
314 // This can be used to override the sh_type field. It is useful when we
315 // want to use specific YAML keys for a section of a particular type to
316 // describe the content, but still want to have a different final type
317 // for the section.
318 std::optional<ELF_SHT> ShType;
319};
320
321// Fill is a block of data which is placed outside of sections. It is
322// not present in the sections header table, but it might affect the output file
323// size and program headers produced.
324struct Fill : Chunk {
325 std::optional<yaml::BinaryRef> Pattern;
326 llvm::yaml::Hex64 Size;
327
328 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
329
330 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
331};
332
333struct SectionHeaderTable : Chunk {
334 SectionHeaderTable(bool IsImplicit)
335 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
336
337 static bool classof(const Chunk *S) {
338 return S->Kind == ChunkKind::SectionHeaderTable;
339 }
340
341 std::optional<std::vector<SectionHeader>> Sections;
342 std::optional<std::vector<SectionHeader>> Excluded;
343 std::optional<bool> NoHeaders;
344
345 size_t getNumHeaders(size_t SectionsNum) const {
346 if (IsImplicit || isDefault())
347 return SectionsNum;
348 if (NoHeaders)
349 return (*NoHeaders) ? 0 : SectionsNum;
350 return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
351 }
352
353 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
354
355 static constexpr StringRef TypeStr = "SectionHeaderTable";
356};
357
358struct BBAddrMapSection : Section {
359 std::optional<std::vector<BBAddrMapEntry>> Entries;
360 std::optional<std::vector<PGOAnalysisMapEntry>> PGOAnalyses;
361
362 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
363
364 std::vector<std::pair<StringRef, bool>> getEntries() const override {
365 return {{"Entries", Entries.has_value()}};
366 };
367
368 static bool classof(const Chunk *S) {
369 return S->Kind == ChunkKind::BBAddrMap;
370 }
371};
372
373struct StackSizesSection : Section {
374 std::optional<std::vector<StackSizeEntry>> Entries;
375
376 StackSizesSection() : Section(ChunkKind::StackSizes) {}
377
378 std::vector<std::pair<StringRef, bool>> getEntries() const override {
379 return {{"Entries", Entries.has_value()}};
380 };
381
382 static bool classof(const Chunk *S) {
383 return S->Kind == ChunkKind::StackSizes;
384 }
385
386 static bool nameMatches(StringRef Name) {
387 return Name == ".stack_sizes";
388 }
389};
390
391struct DynamicSection : Section {
392 std::optional<std::vector<DynamicEntry>> Entries;
393
394 DynamicSection() : Section(ChunkKind::Dynamic) {}
395
396 std::vector<std::pair<StringRef, bool>> getEntries() const override {
397 return {{"Entries", Entries.has_value()}};
398 };
399
400 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
401};
402
403struct RawContentSection : Section {
404 std::optional<llvm::yaml::Hex64> Info;
405
406 RawContentSection() : Section(ChunkKind::RawContent) {}
407
408 static bool classof(const Chunk *S) {
409 return S->Kind == ChunkKind::RawContent;
410 }
411
412 // Is used when a content is read as an array of bytes.
413 std::optional<std::vector<uint8_t>> ContentBuf;
414};
415
416struct NoBitsSection : Section {
417 NoBitsSection() : Section(ChunkKind::NoBits) {}
418
419 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
420};
421
422struct NoteSection : Section {
423 std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
424
425 NoteSection() : Section(ChunkKind::Note) {}
426
427 std::vector<std::pair<StringRef, bool>> getEntries() const override {
428 return {{"Notes", Notes.has_value()}};
429 };
430
431 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
432};
433
434struct HashSection : Section {
435 std::optional<std::vector<uint32_t>> Bucket;
436 std::optional<std::vector<uint32_t>> Chain;
437
438 std::vector<std::pair<StringRef, bool>> getEntries() const override {
439 return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
440 };
441
442 // The following members are used to override section fields.
443 // This is useful for creating invalid objects.
444 std::optional<llvm::yaml::Hex64> NBucket;
445 std::optional<llvm::yaml::Hex64> NChain;
446
447 HashSection() : Section(ChunkKind::Hash) {}
448
449 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
450};
451
452struct GnuHashHeader {
453 // The number of hash buckets.
454 // Not used when dumping the object, but can be used to override
455 // the real number of buckets when emiting an object from a YAML document.
456 std::optional<llvm::yaml::Hex32> NBuckets;
457
458 // Index of the first symbol in the dynamic symbol table
459 // included in the hash table.
460 llvm::yaml::Hex32 SymNdx;
461
462 // The number of words in the Bloom filter.
463 // Not used when dumping the object, but can be used to override the real
464 // number of words in the Bloom filter when emiting an object from a YAML
465 // document.
466 std::optional<llvm::yaml::Hex32> MaskWords;
467
468 // A shift constant used by the Bloom filter.
469 llvm::yaml::Hex32 Shift2;
470};
471
472struct GnuHashSection : Section {
473 std::optional<GnuHashHeader> Header;
474 std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
475 std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
476 std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
477
478 GnuHashSection() : Section(ChunkKind::GnuHash) {}
479
480 std::vector<std::pair<StringRef, bool>> getEntries() const override {
481 return {{"Header", Header.has_value()},
482 {"BloomFilter", BloomFilter.has_value()},
483 {"HashBuckets", HashBuckets.has_value()},
484 {"HashValues", HashValues.has_value()}};
485 };
486
487 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
488};
489
490struct VernauxEntry {
491 uint32_t Hash;
492 uint16_t Flags;
493 uint16_t Other;
494 StringRef Name;
495};
496
497struct VerneedEntry {
498 uint16_t Version;
499 StringRef File;
500 std::vector<VernauxEntry> AuxV;
501};
502
503struct VerneedSection : Section {
504 std::optional<std::vector<VerneedEntry>> VerneedV;
505 std::optional<llvm::yaml::Hex64> Info;
506
507 VerneedSection() : Section(ChunkKind::Verneed) {}
508
509 std::vector<std::pair<StringRef, bool>> getEntries() const override {
510 return {{"Dependencies", VerneedV.has_value()}};
511 };
512
513 static bool classof(const Chunk *S) {
514 return S->Kind == ChunkKind::Verneed;
515 }
516};
517
518struct AddrsigSection : Section {
519 std::optional<std::vector<YAMLFlowString>> Symbols;
520
521 AddrsigSection() : Section(ChunkKind::Addrsig) {}
522
523 std::vector<std::pair<StringRef, bool>> getEntries() const override {
524 return {{"Symbols", Symbols.has_value()}};
525 };
526
527 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
528};
529
530struct LinkerOption {
531 StringRef Key;
532 StringRef Value;
533};
534
535struct LinkerOptionsSection : Section {
536 std::optional<std::vector<LinkerOption>> Options;
537
538 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
539
540 std::vector<std::pair<StringRef, bool>> getEntries() const override {
541 return {{"Options", Options.has_value()}};
542 };
543
544 static bool classof(const Chunk *S) {
545 return S->Kind == ChunkKind::LinkerOptions;
546 }
547};
548
549struct DependentLibrariesSection : Section {
550 std::optional<std::vector<YAMLFlowString>> Libs;
551
552 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
553
554 std::vector<std::pair<StringRef, bool>> getEntries() const override {
555 return {{"Libraries", Libs.has_value()}};
556 };
557
558 static bool classof(const Chunk *S) {
559 return S->Kind == ChunkKind::DependentLibraries;
560 }
561};
562
563// Represents the call graph profile section entry.
564struct CallGraphEntryWeight {
565 // The weight of the edge.
566 uint64_t Weight;
567};
568
569struct CallGraphProfileSection : Section {
570 std::optional<std::vector<CallGraphEntryWeight>> Entries;
571
572 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
573
574 std::vector<std::pair<StringRef, bool>> getEntries() const override {
575 return {{"Entries", Entries.has_value()}};
576 };
577
578 static bool classof(const Chunk *S) {
579 return S->Kind == ChunkKind::CallGraphProfile;
580 }
581};
582
583struct SymverSection : Section {
584 std::optional<std::vector<uint16_t>> Entries;
585
586 SymverSection() : Section(ChunkKind::Symver) {}
587
588 std::vector<std::pair<StringRef, bool>> getEntries() const override {
589 return {{"Entries", Entries.has_value()}};
590 };
591
592 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
593};
594
595struct VerdefEntry {
596 std::optional<uint16_t> Version;
597 std::optional<uint16_t> Flags;
598 std::optional<uint16_t> VersionNdx;
599 std::optional<uint32_t> Hash;
600 std::optional<uint16_t> VDAux;
601 std::vector<StringRef> VerNames;
602};
603
604struct VerdefSection : Section {
605 std::optional<std::vector<VerdefEntry>> Entries;
606 std::optional<llvm::yaml::Hex64> Info;
607
608 VerdefSection() : Section(ChunkKind::Verdef) {}
609
610 std::vector<std::pair<StringRef, bool>> getEntries() const override {
611 return {{"Entries", Entries.has_value()}};
612 };
613
614 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
615};
616
617struct GroupSection : Section {
618 // Members of a group contain a flag and a list of section indices
619 // that are part of the group.
620 std::optional<std::vector<SectionOrType>> Members;
621 std::optional<StringRef> Signature; /* Info */
622
623 GroupSection() : Section(ChunkKind::Group) {}
624
625 std::vector<std::pair<StringRef, bool>> getEntries() const override {
626 return {{"Members", Members.has_value()}};
627 };
628
629 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
630};
631
632struct Relocation {
633 llvm::yaml::Hex64 Offset;
634 YAMLIntUInt Addend;
635 ELF_REL Type;
636 std::optional<StringRef> Symbol;
637};
638
639struct RelocationSection : Section {
640 std::optional<std::vector<Relocation>> Relocations;
641 StringRef RelocatableSec; /* Info */
642
643 RelocationSection() : Section(ChunkKind::Relocation) {}
644
645 std::vector<std::pair<StringRef, bool>> getEntries() const override {
646 return {{"Relocations", Relocations.has_value()}};
647 };
648
649 static bool classof(const Chunk *S) {
650 return S->Kind == ChunkKind::Relocation;
651 }
652};
653
654struct RelrSection : Section {
655 std::optional<std::vector<llvm::yaml::Hex64>> Entries;
656
657 RelrSection() : Section(ChunkKind::Relr) {}
658
659 std::vector<std::pair<StringRef, bool>> getEntries() const override {
660 return {{"Entries", Entries.has_value()}};
661 };
662
663 static bool classof(const Chunk *S) {
664 return S->Kind == ChunkKind::Relr;
665 }
666};
667
668struct SymtabShndxSection : Section {
669 std::optional<std::vector<uint32_t>> Entries;
670
671 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
672
673 std::vector<std::pair<StringRef, bool>> getEntries() const override {
674 return {{"Entries", Entries.has_value()}};
675 };
676
677 static bool classof(const Chunk *S) {
678 return S->Kind == ChunkKind::SymtabShndxSection;
679 }
680};
681
682struct ARMIndexTableEntry {
683 llvm::yaml::Hex32 Offset;
684 llvm::yaml::Hex32 Value;
685};
686
687struct ARMIndexTableSection : Section {
688 std::optional<std::vector<ARMIndexTableEntry>> Entries;
689
690 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
691
692 std::vector<std::pair<StringRef, bool>> getEntries() const override {
693 return {{"Entries", Entries.has_value()}};
694 };
695
696 static bool classof(const Chunk *S) {
697 return S->Kind == ChunkKind::ARMIndexTable;
698 }
699};
700
701// Represents .MIPS.abiflags section
702struct MipsABIFlags : Section {
703 llvm::yaml::Hex16 Version;
704 MIPS_ISA ISALevel;
705 llvm::yaml::Hex8 ISARevision;
706 MIPS_AFL_REG GPRSize;
707 MIPS_AFL_REG CPR1Size;
708 MIPS_AFL_REG CPR2Size;
709 MIPS_ABI_FP FpABI;
710 MIPS_AFL_EXT ISAExtension;
711 MIPS_AFL_ASE ASEs;
712 MIPS_AFL_FLAGS1 Flags1;
713 llvm::yaml::Hex32 Flags2;
714
715 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
716
717 static bool classof(const Chunk *S) {
718 return S->Kind == ChunkKind::MipsABIFlags;
719 }
720};
721
722struct ProgramHeader {
723 ELF_PT Type;
724 ELF_PF Flags;
725 llvm::yaml::Hex64 VAddr;
726 llvm::yaml::Hex64 PAddr;
727 std::optional<llvm::yaml::Hex64> Align;
728 std::optional<llvm::yaml::Hex64> FileSize;
729 std::optional<llvm::yaml::Hex64> MemSize;
730 std::optional<llvm::yaml::Hex64> Offset;
731 std::optional<StringRef> FirstSec;
732 std::optional<StringRef> LastSec;
733
734 // This vector contains all chunks from [FirstSec, LastSec].
735 std::vector<Chunk *> Chunks;
736};
737
738struct Object {
739 FileHeader Header;
740 std::vector<ProgramHeader> ProgramHeaders;
741
742 // An object might contain output section descriptions as well as
743 // custom data that does not belong to any section.
744 std::vector<std::unique_ptr<Chunk>> Chunks;
745
746 // Although in reality the symbols reside in a section, it is a lot
747 // cleaner and nicer if we read them from the YAML as a separate
748 // top-level key, which automatically ensures that invariants like there
749 // being a single SHT_SYMTAB section are upheld.
750 std::optional<std::vector<Symbol>> Symbols;
751 std::optional<std::vector<Symbol>> DynamicSymbols;
752 std::optional<DWARFYAML::Data> DWARF;
753
754 std::vector<Section *> getSections() {
755 std::vector<Section *> Ret;
756 for (const std::unique_ptr<Chunk> &Sec : Chunks)
757 if (auto S = dyn_cast<ELFYAML::Section>(Val: Sec.get()))
758 Ret.push_back(x: S);
759 return Ret;
760 }
761
762 const SectionHeaderTable &getSectionHeaderTable() const {
763 for (const std::unique_ptr<Chunk> &C : Chunks)
764 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(Val: C.get()))
765 return *S;
766 llvm_unreachable("the section header table chunk must always be present");
767 }
768
769 ELF_ELFOSABI getOSAbi() const;
770 unsigned getMachine() const;
771};
772
773bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
774 const NoBitsSection &S);
775
776} // end namespace ELFYAML
777} // end namespace llvm
778
779LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
780LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
781LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
782LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry)
783LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
784LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
785LLVM_YAML_IS_SEQUENCE_VECTOR(
786 llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry)
787LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
788LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
789LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
790LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
791LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
792LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
793LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
794LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
795LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
796LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
797LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
798LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
799LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
800LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
801
802namespace llvm {
803namespace yaml {
804
805template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
806 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
807 raw_ostream &Out);
808 static StringRef input(StringRef Scalar, void *Ctx,
809 ELFYAML::YAMLIntUInt &Val);
810 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
811};
812
813template <>
814struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
815 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
816};
817
818template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
819 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
820};
821
822template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
823 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
824};
825
826template <>
827struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
828 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
829};
830
831template <>
832struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
833 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
834};
835
836template <>
837struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
838 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
839};
840
841template <>
842struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
843 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
844};
845
846template <>
847struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
848 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
849};
850
851template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
852 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
853};
854
855template <>
856struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
857 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
858};
859
860template <>
861struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
862 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
863};
864
865template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
866 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
867};
868
869template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
870 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
871};
872
873template <>
874struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
875 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
876};
877
878template <>
879struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
880 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
881};
882
883template <>
884struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
885 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
886};
887
888template <>
889struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
890 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
891};
892
893template <>
894struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
895 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
896};
897
898template <>
899struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
900 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
901};
902
903template <>
904struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
905 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
906};
907
908template <>
909struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
910 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
911};
912
913template <>
914struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
915 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
916};
917
918template <>
919struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
920 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
921};
922
923template <>
924struct MappingTraits<ELFYAML::FileHeader> {
925 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
926};
927
928template <> struct MappingTraits<ELFYAML::SectionHeader> {
929 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
930};
931
932template <> struct MappingTraits<ELFYAML::ProgramHeader> {
933 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
934 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
935};
936
937template <>
938struct MappingTraits<ELFYAML::Symbol> {
939 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
940 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
941};
942
943template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
944 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
945};
946
947template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
948 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E);
949};
950
951template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> {
952 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E);
953};
954
955template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
956 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E);
957};
958
959template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
960 static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel);
961};
962
963template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> {
964 static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel);
965};
966
967template <>
968struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> {
969 static void
970 mapping(IO &IO,
971 ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel);
972};
973
974template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
975 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
976};
977
978template <> struct MappingTraits<ELFYAML::DynamicEntry> {
979 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
980};
981
982template <> struct MappingTraits<ELFYAML::NoteEntry> {
983 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
984};
985
986template <> struct MappingTraits<ELFYAML::VerdefEntry> {
987 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
988};
989
990template <> struct MappingTraits<ELFYAML::VerneedEntry> {
991 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
992};
993
994template <> struct MappingTraits<ELFYAML::VernauxEntry> {
995 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
996};
997
998template <> struct MappingTraits<ELFYAML::LinkerOption> {
999 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
1000};
1001
1002template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
1003 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
1004};
1005
1006template <> struct MappingTraits<ELFYAML::Relocation> {
1007 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
1008};
1009
1010template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
1011 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
1012};
1013
1014template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
1015 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
1016 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
1017};
1018
1019template <>
1020struct MappingTraits<ELFYAML::Object> {
1021 static void mapping(IO &IO, ELFYAML::Object &Object);
1022};
1023
1024template <> struct MappingTraits<ELFYAML::SectionOrType> {
1025 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
1026};
1027
1028} // end namespace yaml
1029} // end namespace llvm
1030
1031#endif // LLVM_OBJECTYAML_ELFYAML_H
1032