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
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
getFunctionAddressBBAddrMapEntry178 llvm::yaml::Hex64 getFunctionAddress() const {
179 if (!BBRanges || BBRanges->empty())
180 return 0;
181 return BBRanges->front().BaseAddress;
182 }
183 };
184
185 struct 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
198 struct StackSizeEntry {
199 llvm::yaml::Hex64 Address;
200 llvm::yaml::Hex64 Size;
201 };
202
203 struct NoteEntry {
204 StringRef Name;
205 yaml::BinaryRef Desc;
206 ELF_NT Type;
207 };
208
209 struct 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
ChunkChunk247 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
248 virtual ~Chunk();
249 };
250
251 struct 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
ChunkSection265 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
266
classofSection267 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.
getEntriesSection274 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.
309 struct Fill : Chunk {
310 std::optional<yaml::BinaryRef> Pattern;
311 llvm::yaml::Hex64 Size;
312
FillFill313 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
314
classofFill315 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
316 };
317
318 struct SectionHeaderTable : Chunk {
SectionHeaderTableSectionHeaderTable319 SectionHeaderTable(bool IsImplicit)
320 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
321
classofSectionHeaderTable322 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
getNumHeadersSectionHeaderTable330 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
isDefaultSectionHeaderTable338 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
339
340 static constexpr StringRef TypeStr = "SectionHeaderTable";
341 };
342
343 struct BBAddrMapSection : Section {
344 std::optional<std::vector<BBAddrMapEntry>> Entries;
345 std::optional<std::vector<PGOAnalysisMapEntry>> PGOAnalyses;
346
BBAddrMapSectionBBAddrMapSection347 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
348
getEntriesBBAddrMapSection349 std::vector<std::pair<StringRef, bool>> getEntries() const override {
350 return {{"Entries", Entries.has_value()}};
351 };
352
classofBBAddrMapSection353 static bool classof(const Chunk *S) {
354 return S->Kind == ChunkKind::BBAddrMap;
355 }
356 };
357
358 struct StackSizesSection : Section {
359 std::optional<std::vector<StackSizeEntry>> Entries;
360
StackSizesSectionStackSizesSection361 StackSizesSection() : Section(ChunkKind::StackSizes) {}
362
getEntriesStackSizesSection363 std::vector<std::pair<StringRef, bool>> getEntries() const override {
364 return {{"Entries", Entries.has_value()}};
365 };
366
classofStackSizesSection367 static bool classof(const Chunk *S) {
368 return S->Kind == ChunkKind::StackSizes;
369 }
370
nameMatchesStackSizesSection371 static bool nameMatches(StringRef Name) {
372 return Name == ".stack_sizes";
373 }
374 };
375
376 struct DynamicSection : Section {
377 std::optional<std::vector<DynamicEntry>> Entries;
378
DynamicSectionDynamicSection379 DynamicSection() : Section(ChunkKind::Dynamic) {}
380
getEntriesDynamicSection381 std::vector<std::pair<StringRef, bool>> getEntries() const override {
382 return {{"Entries", Entries.has_value()}};
383 };
384
classofDynamicSection385 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
386 };
387
388 struct RawContentSection : Section {
389 std::optional<llvm::yaml::Hex64> Info;
390
RawContentSectionRawContentSection391 RawContentSection() : Section(ChunkKind::RawContent) {}
392
classofRawContentSection393 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
401 struct NoBitsSection : Section {
NoBitsSectionNoBitsSection402 NoBitsSection() : Section(ChunkKind::NoBits) {}
403
classofNoBitsSection404 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
405 };
406
407 struct NoteSection : Section {
408 std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
409
NoteSectionNoteSection410 NoteSection() : Section(ChunkKind::Note) {}
411
getEntriesNoteSection412 std::vector<std::pair<StringRef, bool>> getEntries() const override {
413 return {{"Notes", Notes.has_value()}};
414 };
415
classofNoteSection416 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
417 };
418
419 struct HashSection : Section {
420 std::optional<std::vector<uint32_t>> Bucket;
421 std::optional<std::vector<uint32_t>> Chain;
422
getEntriesHashSection423 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
HashSectionHashSection432 HashSection() : Section(ChunkKind::Hash) {}
433
classofHashSection434 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
435 };
436
437 struct 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
457 struct 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
GnuHashSectionGnuHashSection463 GnuHashSection() : Section(ChunkKind::GnuHash) {}
464
getEntriesGnuHashSection465 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
classofGnuHashSection472 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
473 };
474
475 struct VernauxEntry {
476 uint32_t Hash;
477 uint16_t Flags;
478 uint16_t Other;
479 StringRef Name;
480 };
481
482 struct VerneedEntry {
483 uint16_t Version;
484 StringRef File;
485 std::vector<VernauxEntry> AuxV;
486 };
487
488 struct VerneedSection : Section {
489 std::optional<std::vector<VerneedEntry>> VerneedV;
490 std::optional<llvm::yaml::Hex64> Info;
491
VerneedSectionVerneedSection492 VerneedSection() : Section(ChunkKind::Verneed) {}
493
getEntriesVerneedSection494 std::vector<std::pair<StringRef, bool>> getEntries() const override {
495 return {{"Dependencies", VerneedV.has_value()}};
496 };
497
classofVerneedSection498 static bool classof(const Chunk *S) {
499 return S->Kind == ChunkKind::Verneed;
500 }
501 };
502
503 struct AddrsigSection : Section {
504 std::optional<std::vector<YAMLFlowString>> Symbols;
505
AddrsigSectionAddrsigSection506 AddrsigSection() : Section(ChunkKind::Addrsig) {}
507
getEntriesAddrsigSection508 std::vector<std::pair<StringRef, bool>> getEntries() const override {
509 return {{"Symbols", Symbols.has_value()}};
510 };
511
classofAddrsigSection512 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
513 };
514
515 struct LinkerOption {
516 StringRef Key;
517 StringRef Value;
518 };
519
520 struct LinkerOptionsSection : Section {
521 std::optional<std::vector<LinkerOption>> Options;
522
LinkerOptionsSectionLinkerOptionsSection523 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
524
getEntriesLinkerOptionsSection525 std::vector<std::pair<StringRef, bool>> getEntries() const override {
526 return {{"Options", Options.has_value()}};
527 };
528
classofLinkerOptionsSection529 static bool classof(const Chunk *S) {
530 return S->Kind == ChunkKind::LinkerOptions;
531 }
532 };
533
534 struct DependentLibrariesSection : Section {
535 std::optional<std::vector<YAMLFlowString>> Libs;
536
DependentLibrariesSectionDependentLibrariesSection537 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
538
getEntriesDependentLibrariesSection539 std::vector<std::pair<StringRef, bool>> getEntries() const override {
540 return {{"Libraries", Libs.has_value()}};
541 };
542
classofDependentLibrariesSection543 static bool classof(const Chunk *S) {
544 return S->Kind == ChunkKind::DependentLibraries;
545 }
546 };
547
548 // Represents the call graph profile section entry.
549 struct CallGraphEntryWeight {
550 // The weight of the edge.
551 uint64_t Weight;
552 };
553
554 struct CallGraphProfileSection : Section {
555 std::optional<std::vector<CallGraphEntryWeight>> Entries;
556
CallGraphProfileSectionCallGraphProfileSection557 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
558
getEntriesCallGraphProfileSection559 std::vector<std::pair<StringRef, bool>> getEntries() const override {
560 return {{"Entries", Entries.has_value()}};
561 };
562
classofCallGraphProfileSection563 static bool classof(const Chunk *S) {
564 return S->Kind == ChunkKind::CallGraphProfile;
565 }
566 };
567
568 struct SymverSection : Section {
569 std::optional<std::vector<uint16_t>> Entries;
570
SymverSectionSymverSection571 SymverSection() : Section(ChunkKind::Symver) {}
572
getEntriesSymverSection573 std::vector<std::pair<StringRef, bool>> getEntries() const override {
574 return {{"Entries", Entries.has_value()}};
575 };
576
classofSymverSection577 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
578 };
579
580 struct 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
588 struct VerdefSection : Section {
589 std::optional<std::vector<VerdefEntry>> Entries;
590 std::optional<llvm::yaml::Hex64> Info;
591
VerdefSectionVerdefSection592 VerdefSection() : Section(ChunkKind::Verdef) {}
593
getEntriesVerdefSection594 std::vector<std::pair<StringRef, bool>> getEntries() const override {
595 return {{"Entries", Entries.has_value()}};
596 };
597
classofVerdefSection598 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
599 };
600
601 struct 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
GroupSectionGroupSection607 GroupSection() : Section(ChunkKind::Group) {}
608
getEntriesGroupSection609 std::vector<std::pair<StringRef, bool>> getEntries() const override {
610 return {{"Members", Members.has_value()}};
611 };
612
classofGroupSection613 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
614 };
615
616 struct Relocation {
617 llvm::yaml::Hex64 Offset;
618 YAMLIntUInt Addend;
619 ELF_REL Type;
620 std::optional<StringRef> Symbol;
621 };
622
623 struct RelocationSection : Section {
624 std::optional<std::vector<Relocation>> Relocations;
625 StringRef RelocatableSec; /* Info */
626
RelocationSectionRelocationSection627 RelocationSection() : Section(ChunkKind::Relocation) {}
628
getEntriesRelocationSection629 std::vector<std::pair<StringRef, bool>> getEntries() const override {
630 return {{"Relocations", Relocations.has_value()}};
631 };
632
classofRelocationSection633 static bool classof(const Chunk *S) {
634 return S->Kind == ChunkKind::Relocation;
635 }
636 };
637
638 struct RelrSection : Section {
639 std::optional<std::vector<llvm::yaml::Hex64>> Entries;
640
RelrSectionRelrSection641 RelrSection() : Section(ChunkKind::Relr) {}
642
getEntriesRelrSection643 std::vector<std::pair<StringRef, bool>> getEntries() const override {
644 return {{"Entries", Entries.has_value()}};
645 };
646
classofRelrSection647 static bool classof(const Chunk *S) {
648 return S->Kind == ChunkKind::Relr;
649 }
650 };
651
652 struct SymtabShndxSection : Section {
653 std::optional<std::vector<uint32_t>> Entries;
654
SymtabShndxSectionSymtabShndxSection655 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
656
getEntriesSymtabShndxSection657 std::vector<std::pair<StringRef, bool>> getEntries() const override {
658 return {{"Entries", Entries.has_value()}};
659 };
660
classofSymtabShndxSection661 static bool classof(const Chunk *S) {
662 return S->Kind == ChunkKind::SymtabShndxSection;
663 }
664 };
665
666 struct ARMIndexTableEntry {
667 llvm::yaml::Hex32 Offset;
668 llvm::yaml::Hex32 Value;
669 };
670
671 struct ARMIndexTableSection : Section {
672 std::optional<std::vector<ARMIndexTableEntry>> Entries;
673
ARMIndexTableSectionARMIndexTableSection674 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
675
getEntriesARMIndexTableSection676 std::vector<std::pair<StringRef, bool>> getEntries() const override {
677 return {{"Entries", Entries.has_value()}};
678 };
679
classofARMIndexTableSection680 static bool classof(const Chunk *S) {
681 return S->Kind == ChunkKind::ARMIndexTable;
682 }
683 };
684
685 // Represents .MIPS.abiflags section
686 struct 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
MipsABIFlagsMipsABIFlags699 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
700
classofMipsABIFlags701 static bool classof(const Chunk *S) {
702 return S->Kind == ChunkKind::MipsABIFlags;
703 }
704 };
705
706 struct 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
722 struct 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
getSectionsObject738 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>(Sec.get()))
742 Ret.push_back(S);
743 return Ret;
744 }
745
getSectionHeaderTableObject746 const SectionHeaderTable &getSectionHeaderTable() const {
747 for (const std::unique_ptr<Chunk> &C : Chunks)
748 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(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
757 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
758 const NoBitsSection &S);
759
760 } // end namespace ELFYAML
761 } // end namespace llvm
762
763 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)764 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
765 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
766 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry)
767 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
768 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
769 LLVM_YAML_IS_SEQUENCE_VECTOR(
770 llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry)
771 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
772 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
773 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
774 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
775 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
776 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
777 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
778 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
779 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
780 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
781 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
782 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
783 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
784 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
785
786 namespace llvm {
787 namespace yaml {
788
789 template <> 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
797 template <>
798 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
799 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
800 };
801
802 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
803 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
804 };
805
806 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
807 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
808 };
809
810 template <>
811 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
812 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
813 };
814
815 template <>
816 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
817 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
818 };
819
820 template <>
821 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
822 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
823 };
824
825 template <>
826 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
827 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
828 };
829
830 template <>
831 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
832 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
833 };
834
835 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
836 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
837 };
838
839 template <>
840 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
841 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
842 };
843
844 template <>
845 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
846 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
847 };
848
849 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
850 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
851 };
852
853 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
854 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
855 };
856
857 template <>
858 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
859 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
860 };
861
862 template <>
863 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
864 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
865 };
866
867 template <>
868 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
869 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
870 };
871
872 template <>
873 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
874 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
875 };
876
877 template <>
878 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
879 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
880 };
881
882 template <>
883 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
884 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
885 };
886
887 template <>
888 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
889 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
890 };
891
892 template <>
893 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
894 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
895 };
896
897 template <>
898 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
899 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
900 };
901
902 template <>
903 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
904 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
905 };
906
907 template <>
908 struct MappingTraits<ELFYAML::FileHeader> {
909 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
910 };
911
912 template <> struct MappingTraits<ELFYAML::SectionHeader> {
913 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
914 };
915
916 template <> 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
921 template <>
922 struct MappingTraits<ELFYAML::Symbol> {
923 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
924 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
925 };
926
927 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
928 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
929 };
930
931 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
932 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E);
933 };
934
935 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> {
936 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E);
937 };
938
939 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
940 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E);
941 };
942
943 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
944 static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel);
945 };
946
947 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> {
948 static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel);
949 };
950
951 template <>
952 struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> {
953 static void
954 mapping(IO &IO,
955 ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel);
956 };
957
958 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
959 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
960 };
961
962 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
963 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
964 };
965
966 template <> struct MappingTraits<ELFYAML::NoteEntry> {
967 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
968 };
969
970 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
971 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
972 };
973
974 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
975 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
976 };
977
978 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
979 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
980 };
981
982 template <> struct MappingTraits<ELFYAML::LinkerOption> {
983 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
984 };
985
986 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
987 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
988 };
989
990 template <> struct MappingTraits<ELFYAML::Relocation> {
991 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
992 };
993
994 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
995 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
996 };
997
998 template <> 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
1003 template <>
1004 struct MappingTraits<ELFYAML::Object> {
1005 static void mapping(IO &IO, ELFYAML::Object &Object);
1006 };
1007
1008 template <> struct MappingTraits<ELFYAML::SectionOrType> {
1009 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType);
1010 };
1011
1012 } // end namespace yaml
1013 } // end namespace llvm
1014
1015 #endif // LLVM_OBJECTYAML_ELFYAML_H
1016