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