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

source code of llvm/include/llvm/ObjectYAML/ELFYAML.h