blob: c9e90527380e1813ce36b16a205dfdaa4923854a [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
Andrew Scullcdfcccc2018-10-05 20:58:37 +010010/// This file declares classes for handling the YAML representation
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010011/// of ELF.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OBJECTYAML_ELFYAML_H
16#define LLVM_OBJECTYAML_ELFYAML_H
17
18#include "llvm/ADT/StringRef.h"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020019#include "llvm/BinaryFormat/ELF.h"
20#include "llvm/Object/ELFTypes.h"
21#include "llvm/ObjectYAML/DWARFYAML.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022#include "llvm/ObjectYAML/YAML.h"
23#include "llvm/Support/YAMLTraits.h"
24#include <cstdint>
25#include <memory>
26#include <vector>
27
28namespace llvm {
29namespace ELFYAML {
30
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020031StringRef dropUniqueSuffix(StringRef S);
32std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
33
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010034// These types are invariant across 32/64-bit ELF, so for simplicity just
35// directly give them their exact sizes. We don't need to worry about
36// endianness because these are just the types in the YAMLIO structures,
37// and are appropriately converted to the necessary endianness when
38// reading/generating binary object files.
39// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
40// the common prefix of the respective constants. E.g. ELF_EM corresponds
41// to the `e_machine` constants, like `EM_X86_64`.
42// In the future, these would probably be better suited by C++11 enum
43// class's with appropriate fixed underlying type.
44LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
45LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
46LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
47LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
48LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
49LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
50// Just use 64, since it can hold 32-bit values too.
51LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
Andrew Walbran16937d02019-10-22 13:54:20 +010052// Just use 64, since it can hold 32-bit values too.
53LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010054LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
55LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
56LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
57LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
58// Just use 64, since it can hold 32-bit values too.
59LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
60LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
Andrew Walbran3d2c1972020-04-07 12:24:26 +010061LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010062LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010063
64LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
65LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
66LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
67LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
68LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
69LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
70
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020071LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
72LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
73
74template <class ELFT>
75unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
76 StringRef SecName) {
77 if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
78 return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
79
80 switch (SecType) {
81 case ELF::SHT_GROUP:
82 return sizeof(typename ELFT::Word);
83 case ELF::SHT_REL:
84 return sizeof(typename ELFT::Rel);
85 case ELF::SHT_RELA:
86 return sizeof(typename ELFT::Rela);
87 case ELF::SHT_RELR:
88 return sizeof(typename ELFT::Relr);
89 case ELF::SHT_DYNAMIC:
90 return sizeof(typename ELFT::Dyn);
91 case ELF::SHT_HASH:
92 return sizeof(typename ELFT::Word);
93 case ELF::SHT_SYMTAB_SHNDX:
94 return sizeof(typename ELFT::Word);
95 case ELF::SHT_GNU_versym:
96 return sizeof(typename ELFT::Half);
97 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
98 return sizeof(object::Elf_CGProfile_Impl<ELFT>);
99 default:
100 if (SecName == ".debug_str")
101 return 1;
102 return 0;
103 }
104}
105
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100106// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
107// since 64-bit can hold 32-bit values too.
108struct FileHeader {
109 ELF_ELFCLASS Class;
110 ELF_ELFDATA Data;
111 ELF_ELFOSABI OSABI;
Andrew Walbran16937d02019-10-22 13:54:20 +0100112 llvm::yaml::Hex8 ABIVersion;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100113 ELF_ET Type;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200114 Optional<ELF_EM> Machine;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100115 ELF_EF Flags;
116 llvm::yaml::Hex64 Entry;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100117
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200118 Optional<llvm::yaml::Hex64> EPhOff;
119 Optional<llvm::yaml::Hex16> EPhEntSize;
120 Optional<llvm::yaml::Hex16> EPhNum;
121 Optional<llvm::yaml::Hex16> EShEntSize;
122 Optional<llvm::yaml::Hex64> EShOff;
123 Optional<llvm::yaml::Hex16> EShNum;
124 Optional<llvm::yaml::Hex16> EShStrNdx;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100125};
126
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200127struct SectionHeader {
128 StringRef Name;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100129};
130
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200131struct SectionHeaderTable {
132 Optional<std::vector<SectionHeader>> Sections;
133 Optional<std::vector<SectionHeader>> Excluded;
134 Optional<bool> NoHeaders;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100135};
136
137struct Symbol {
138 StringRef Name;
139 ELF_STT Type;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200140 Optional<StringRef> Section;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100141 Optional<ELF_SHN> Index;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100142 ELF_STB Binding;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200143 Optional<llvm::yaml::Hex64> Value;
144 Optional<llvm::yaml::Hex64> Size;
145 Optional<uint8_t> Other;
146
147 Optional<uint32_t> StName;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100148};
149
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100150struct SectionOrType {
151 StringRef sectionNameOrType;
152};
153
Andrew Walbran16937d02019-10-22 13:54:20 +0100154struct DynamicEntry {
155 ELF_DYNTAG Tag;
156 llvm::yaml::Hex64 Val;
157};
158
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200159struct BBAddrMapEntry {
160 struct BBEntry {
161 llvm::yaml::Hex32 AddressOffset;
162 llvm::yaml::Hex32 Size;
163 llvm::yaml::Hex32 Metadata;
164 };
165 llvm::yaml::Hex64 Address;
166 Optional<std::vector<BBEntry>> BBEntries;
167};
168
169struct StackSizeEntry {
170 llvm::yaml::Hex64 Address;
171 llvm::yaml::Hex64 Size;
172};
173
174struct NoteEntry {
175 StringRef Name;
176 yaml::BinaryRef Desc;
177 llvm::yaml::Hex32 Type;
178};
179
180struct Chunk {
181 enum class ChunkKind {
Andrew Walbran16937d02019-10-22 13:54:20 +0100182 Dynamic,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100183 Group,
184 RawContent,
185 Relocation,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200186 Relr,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100187 NoBits,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200188 Note,
189 Hash,
190 GnuHash,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100191 Verdef,
192 Verneed,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200193 StackSizes,
194 SymtabShndxSection,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100195 Symver,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200196 ARMIndexTable,
197 MipsABIFlags,
198 Addrsig,
199 Fill,
200 LinkerOptions,
201 DependentLibraries,
202 CallGraphProfile,
203 BBAddrMap
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100204 };
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200205
206 ChunkKind Kind;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100207 StringRef Name;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200208 Optional<llvm::yaml::Hex64> Offset;
209
210 Chunk(ChunkKind K) : Kind(K) {}
211 virtual ~Chunk();
212};
213
214struct Section : public Chunk {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100215 ELF_SHT Type;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100216 Optional<ELF_SHF> Flags;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200217 Optional<llvm::yaml::Hex64> Address;
218 Optional<StringRef> Link;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100219 llvm::yaml::Hex64 AddressAlign;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100220 Optional<llvm::yaml::Hex64> EntSize;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100221
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200222 Optional<yaml::BinaryRef> Content;
223 Optional<llvm::yaml::Hex64> Size;
224
225 // Usually sections are not created implicitly, but loaded from YAML.
226 // When they are, this flag is used to signal about that.
227 bool IsImplicit;
228
229 // Holds the original section index.
230 unsigned OriginalSecNdx;
231
232 Section(ChunkKind Kind, bool IsImplicit = false)
233 : Chunk(Kind), IsImplicit(IsImplicit) {}
234
235 static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; }
236
237 // Some derived sections might have their own special entries. This method
238 // returns a vector of <entry name, is used> pairs. It is used for section
239 // validation.
240 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
241 return {};
242 };
243
244 // The following members are used to override section fields which is
245 // useful for creating invalid objects.
246
247 // This can be used to override the sh_addralign field.
248 Optional<llvm::yaml::Hex64> ShAddrAlign;
249
250 // This can be used to override the offset stored in the sh_name field.
251 // It does not affect the name stored in the string table.
252 Optional<llvm::yaml::Hex64> ShName;
253
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100254 // This can be used to override the sh_offset field. It does not place the
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200255 // section data at the offset specified.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100256 Optional<llvm::yaml::Hex64> ShOffset;
257
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200258 // This can be used to override the sh_size field. It does not affect the
259 // content written.
260 Optional<llvm::yaml::Hex64> ShSize;
261
262 // This can be used to override the sh_flags field.
263 Optional<llvm::yaml::Hex64> ShFlags;
264
265 // This can be used to override the sh_type field. It is useful when we
266 // want to use specific YAML keys for a section of a particular type to
267 // describe the content, but still want to have a different final type
268 // for the section.
269 Optional<ELF_SHT> ShType;
270};
271
272// Fill is a block of data which is placed outside of sections. It is
273// not present in the sections header table, but it might affect the output file
274// size and program headers produced.
275struct Fill : Chunk {
276 Optional<yaml::BinaryRef> Pattern;
277 llvm::yaml::Hex64 Size;
278
279 Fill() : Chunk(ChunkKind::Fill) {}
280
281 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
282};
283
284struct BBAddrMapSection : Section {
285 Optional<std::vector<BBAddrMapEntry>> Entries;
286
287 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
288
289 std::vector<std::pair<StringRef, bool>> getEntries() const override {
290 return {{"Entries", Entries.hasValue()}};
291 };
292
293 static bool classof(const Chunk *S) {
294 return S->Kind == ChunkKind::BBAddrMap;
295 }
296};
297
298struct StackSizesSection : Section {
299 Optional<std::vector<StackSizeEntry>> Entries;
300
301 StackSizesSection() : Section(ChunkKind::StackSizes) {}
302
303 std::vector<std::pair<StringRef, bool>> getEntries() const override {
304 return {{"Entries", Entries.hasValue()}};
305 };
306
307 static bool classof(const Chunk *S) {
308 return S->Kind == ChunkKind::StackSizes;
309 }
310
311 static bool nameMatches(StringRef Name) {
312 return Name == ".stack_sizes";
313 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100314};
Andrew Walbran16937d02019-10-22 13:54:20 +0100315
316struct DynamicSection : Section {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200317 Optional<std::vector<DynamicEntry>> Entries;
Andrew Walbran16937d02019-10-22 13:54:20 +0100318
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200319 DynamicSection() : Section(ChunkKind::Dynamic) {}
Andrew Walbran16937d02019-10-22 13:54:20 +0100320
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200321 std::vector<std::pair<StringRef, bool>> getEntries() const override {
322 return {{"Entries", Entries.hasValue()}};
323 };
324
325 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
Andrew Walbran16937d02019-10-22 13:54:20 +0100326};
327
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100328struct RawContentSection : Section {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100329 Optional<llvm::yaml::Hex64> Info;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100330
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200331 RawContentSection() : Section(ChunkKind::RawContent) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100332
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200333 static bool classof(const Chunk *S) {
334 return S->Kind == ChunkKind::RawContent;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100335 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200336
337 // Is used when a content is read as an array of bytes.
338 Optional<std::vector<uint8_t>> ContentBuf;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100339};
340
341struct NoBitsSection : Section {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200342 NoBitsSection() : Section(ChunkKind::NoBits) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100343
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200344 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
345};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100346
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200347struct NoteSection : Section {
348 Optional<std::vector<ELFYAML::NoteEntry>> Notes;
349
350 NoteSection() : Section(ChunkKind::Note) {}
351
352 std::vector<std::pair<StringRef, bool>> getEntries() const override {
353 return {{"Notes", Notes.hasValue()}};
354 };
355
356 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
357};
358
359struct HashSection : Section {
360 Optional<std::vector<uint32_t>> Bucket;
361 Optional<std::vector<uint32_t>> Chain;
362
363 std::vector<std::pair<StringRef, bool>> getEntries() const override {
364 return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
365 };
366
367 // The following members are used to override section fields.
368 // This is useful for creating invalid objects.
369 Optional<llvm::yaml::Hex64> NBucket;
370 Optional<llvm::yaml::Hex64> NChain;
371
372 HashSection() : Section(ChunkKind::Hash) {}
373
374 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
375};
376
377struct GnuHashHeader {
378 // The number of hash buckets.
379 // Not used when dumping the object, but can be used to override
380 // the real number of buckets when emiting an object from a YAML document.
381 Optional<llvm::yaml::Hex32> NBuckets;
382
383 // Index of the first symbol in the dynamic symbol table
384 // included in the hash table.
385 llvm::yaml::Hex32 SymNdx;
386
387 // The number of words in the Bloom filter.
388 // Not used when dumping the object, but can be used to override the real
389 // number of words in the Bloom filter when emiting an object from a YAML
390 // document.
391 Optional<llvm::yaml::Hex32> MaskWords;
392
393 // A shift constant used by the Bloom filter.
394 llvm::yaml::Hex32 Shift2;
395};
396
397struct GnuHashSection : Section {
398 Optional<GnuHashHeader> Header;
399 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
400 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
401 Optional<std::vector<llvm::yaml::Hex32>> HashValues;
402
403 GnuHashSection() : Section(ChunkKind::GnuHash) {}
404
405 std::vector<std::pair<StringRef, bool>> getEntries() const override {
406 return {{"Header", Header.hasValue()},
407 {"BloomFilter", BloomFilter.hasValue()},
408 {"HashBuckets", HashBuckets.hasValue()},
409 {"HashValues", HashValues.hasValue()}};
410 };
411
412 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100413};
414
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100415struct VernauxEntry {
416 uint32_t Hash;
417 uint16_t Flags;
418 uint16_t Other;
419 StringRef Name;
420};
421
422struct VerneedEntry {
423 uint16_t Version;
424 StringRef File;
425 std::vector<VernauxEntry> AuxV;
426};
427
428struct VerneedSection : Section {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200429 Optional<std::vector<VerneedEntry>> VerneedV;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100430 llvm::yaml::Hex64 Info;
431
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200432 VerneedSection() : Section(ChunkKind::Verneed) {}
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100433
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200434 std::vector<std::pair<StringRef, bool>> getEntries() const override {
435 return {{"Dependencies", VerneedV.hasValue()}};
436 };
437
438 static bool classof(const Chunk *S) {
439 return S->Kind == ChunkKind::Verneed;
440 }
441};
442
443struct AddrsigSection : Section {
444 Optional<std::vector<YAMLFlowString>> Symbols;
445
446 AddrsigSection() : Section(ChunkKind::Addrsig) {}
447
448 std::vector<std::pair<StringRef, bool>> getEntries() const override {
449 return {{"Symbols", Symbols.hasValue()}};
450 };
451
452 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
453};
454
455struct LinkerOption {
456 StringRef Key;
457 StringRef Value;
458};
459
460struct LinkerOptionsSection : Section {
461 Optional<std::vector<LinkerOption>> Options;
462
463 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
464
465 std::vector<std::pair<StringRef, bool>> getEntries() const override {
466 return {{"Options", Options.hasValue()}};
467 };
468
469 static bool classof(const Chunk *S) {
470 return S->Kind == ChunkKind::LinkerOptions;
471 }
472};
473
474struct DependentLibrariesSection : Section {
475 Optional<std::vector<YAMLFlowString>> Libs;
476
477 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
478
479 std::vector<std::pair<StringRef, bool>> getEntries() const override {
480 return {{"Libraries", Libs.hasValue()}};
481 };
482
483 static bool classof(const Chunk *S) {
484 return S->Kind == ChunkKind::DependentLibraries;
485 }
486};
487
488// Represents the call graph profile section entry.
489struct CallGraphEntry {
490 // The symbol of the source of the edge.
491 StringRef From;
492 // The symbol index of the destination of the edge.
493 StringRef To;
494 // The weight of the edge.
495 uint64_t Weight;
496};
497
498struct CallGraphProfileSection : Section {
499 Optional<std::vector<CallGraphEntry>> Entries;
500
501 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
502
503 std::vector<std::pair<StringRef, bool>> getEntries() const override {
504 return {{"Entries", Entries.hasValue()}};
505 };
506
507 static bool classof(const Chunk *S) {
508 return S->Kind == ChunkKind::CallGraphProfile;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100509 }
510};
511
512struct SymverSection : Section {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200513 Optional<std::vector<uint16_t>> Entries;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100514
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200515 SymverSection() : Section(ChunkKind::Symver) {}
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100516
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200517 std::vector<std::pair<StringRef, bool>> getEntries() const override {
518 return {{"Entries", Entries.hasValue()}};
519 };
520
521 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100522};
523
524struct VerdefEntry {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200525 Optional<uint16_t> Version;
526 Optional<uint16_t> Flags;
527 Optional<uint16_t> VersionNdx;
528 Optional<uint32_t> Hash;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100529 std::vector<StringRef> VerNames;
530};
531
532struct VerdefSection : Section {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200533 Optional<std::vector<VerdefEntry>> Entries;
534
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100535 llvm::yaml::Hex64 Info;
536
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200537 VerdefSection() : Section(ChunkKind::Verdef) {}
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100538
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200539 std::vector<std::pair<StringRef, bool>> getEntries() const override {
540 return {{"Entries", Entries.hasValue()}};
541 };
542
543 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100544};
545
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200546struct GroupSection : Section {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100547 // Members of a group contain a flag and a list of section indices
548 // that are part of the group.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200549 Optional<std::vector<SectionOrType>> Members;
550 Optional<StringRef> Signature; /* Info */
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100551
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200552 GroupSection() : Section(ChunkKind::Group) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100553
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200554 std::vector<std::pair<StringRef, bool>> getEntries() const override {
555 return {{"Members", Members.hasValue()}};
556 };
557
558 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100559};
560
561struct Relocation {
562 llvm::yaml::Hex64 Offset;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200563 YAMLIntUInt Addend;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100564 ELF_REL Type;
565 Optional<StringRef> Symbol;
566};
567
568struct RelocationSection : Section {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200569 Optional<std::vector<Relocation>> Relocations;
Andrew Walbran16937d02019-10-22 13:54:20 +0100570 StringRef RelocatableSec; /* Info */
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100571
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200572 RelocationSection() : Section(ChunkKind::Relocation) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100573
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200574 std::vector<std::pair<StringRef, bool>> getEntries() const override {
575 return {{"Relocations", Relocations.hasValue()}};
576 };
577
578 static bool classof(const Chunk *S) {
579 return S->Kind == ChunkKind::Relocation;
580 }
581};
582
583struct RelrSection : Section {
584 Optional<std::vector<llvm::yaml::Hex64>> Entries;
585
586 RelrSection() : Section(ChunkKind::Relr) {}
587
588 std::vector<std::pair<StringRef, bool>> getEntries() const override {
589 return {{"Entries", Entries.hasValue()}};
590 };
591
592 static bool classof(const Chunk *S) {
593 return S->Kind == ChunkKind::Relr;
594 }
595};
596
597struct SymtabShndxSection : Section {
598 Optional<std::vector<uint32_t>> Entries;
599
600 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
601
602 std::vector<std::pair<StringRef, bool>> getEntries() const override {
603 return {{"Entries", Entries.hasValue()}};
604 };
605
606 static bool classof(const Chunk *S) {
607 return S->Kind == ChunkKind::SymtabShndxSection;
608 }
609};
610
611struct ARMIndexTableEntry {
612 llvm::yaml::Hex32 Offset;
613 llvm::yaml::Hex32 Value;
614};
615
616struct ARMIndexTableSection : Section {
617 Optional<std::vector<ARMIndexTableEntry>> Entries;
618
619 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
620
621 std::vector<std::pair<StringRef, bool>> getEntries() const override {
622 return {{"Entries", Entries.hasValue()}};
623 };
624
625 static bool classof(const Chunk *S) {
626 return S->Kind == ChunkKind::ARMIndexTable;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100627 }
628};
629
630// Represents .MIPS.abiflags section
631struct MipsABIFlags : Section {
632 llvm::yaml::Hex16 Version;
633 MIPS_ISA ISALevel;
634 llvm::yaml::Hex8 ISARevision;
635 MIPS_AFL_REG GPRSize;
636 MIPS_AFL_REG CPR1Size;
637 MIPS_AFL_REG CPR2Size;
638 MIPS_ABI_FP FpABI;
639 MIPS_AFL_EXT ISAExtension;
640 MIPS_AFL_ASE ASEs;
641 MIPS_AFL_FLAGS1 Flags1;
642 llvm::yaml::Hex32 Flags2;
643
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200644 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100645
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200646 static bool classof(const Chunk *S) {
647 return S->Kind == ChunkKind::MipsABIFlags;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100648 }
649};
650
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200651struct ProgramHeader {
652 ELF_PT Type;
653 ELF_PF Flags;
654 llvm::yaml::Hex64 VAddr;
655 llvm::yaml::Hex64 PAddr;
656 Optional<llvm::yaml::Hex64> Align;
657 Optional<llvm::yaml::Hex64> FileSize;
658 Optional<llvm::yaml::Hex64> MemSize;
659 Optional<llvm::yaml::Hex64> Offset;
660 Optional<StringRef> FirstSec;
661 Optional<StringRef> LastSec;
662
663 // This vector contains all chunks from [FirstSec, LastSec].
664 std::vector<Chunk *> Chunks;
665};
666
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100667struct Object {
668 FileHeader Header;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200669 Optional<SectionHeaderTable> SectionHeaders;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100670 std::vector<ProgramHeader> ProgramHeaders;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200671
672 // An object might contain output section descriptions as well as
673 // custom data that does not belong to any section.
674 std::vector<std::unique_ptr<Chunk>> Chunks;
675
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100676 // Although in reality the symbols reside in a section, it is a lot
677 // cleaner and nicer if we read them from the YAML as a separate
678 // top-level key, which automatically ensures that invariants like there
679 // being a single SHT_SYMTAB section are upheld.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200680 Optional<std::vector<Symbol>> Symbols;
681 Optional<std::vector<Symbol>> DynamicSymbols;
682 Optional<DWARFYAML::Data> DWARF;
683
684 std::vector<Section *> getSections() {
685 std::vector<Section *> Ret;
686 for (const std::unique_ptr<Chunk> &Sec : Chunks)
687 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
688 Ret.push_back(S);
689 return Ret;
690 }
691
692 unsigned getMachine() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100693};
694
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200695bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
696 const NoBitsSection &S);
697
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100698} // end namespace ELFYAML
699} // end namespace llvm
700
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200701LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
702LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
703LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
Andrew Walbran16937d02019-10-22 13:54:20 +0100704LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200705LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
706LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntry)
707LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100708LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200709LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
710LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100711LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100712LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
713LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
714LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100715LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
716LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200717LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100718
719namespace llvm {
720namespace yaml {
721
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200722template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
723 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
724 raw_ostream &Out);
725 static StringRef input(StringRef Scalar, void *Ctx,
726 ELFYAML::YAMLIntUInt &Val);
727 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
728};
729
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100730template <>
731struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
732 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
733};
734
735template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
736 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
737};
738
739template <>
740struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
741 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
742};
743
744template <>
745struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
746 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
747};
748
749template <>
750struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
751 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
752};
753
754template <>
755struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
756 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
757};
758
759template <>
760struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
761 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
762};
763
764template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
765 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
766};
767
768template <>
769struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
770 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
771};
772
773template <>
774struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
775 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
776};
777
778template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
779 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
780};
781
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100782template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
783 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
784};
785
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100786template <>
787struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
788 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
789};
790
791template <>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100792struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
793 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
794};
795
796template <>
Andrew Walbran16937d02019-10-22 13:54:20 +0100797struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
798 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
799};
800
801template <>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100802struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
803 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
804};
805
806template <>
807struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
808 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
809};
810
811template <>
812struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
813 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
814};
815
816template <>
817struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
818 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
819};
820
821template <>
822struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
823 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
824};
825
826template <>
827struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
828 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
829};
830
831template <>
832struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
833 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
834};
835
836template <>
837struct MappingTraits<ELFYAML::FileHeader> {
838 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
839};
840
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200841template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
842 static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
843 static std::string validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
844};
845
846template <> struct MappingTraits<ELFYAML::SectionHeader> {
847 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
848};
849
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100850template <> struct MappingTraits<ELFYAML::ProgramHeader> {
851 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200852 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100853};
854
855template <>
856struct MappingTraits<ELFYAML::Symbol> {
857 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200858 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
859};
860
861template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
862 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
863};
864
865template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
866 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
867};
868
869template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
870 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
871};
872
873template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
874 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100875};
876
Andrew Walbran16937d02019-10-22 13:54:20 +0100877template <> struct MappingTraits<ELFYAML::DynamicEntry> {
878 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
879};
880
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200881template <> struct MappingTraits<ELFYAML::NoteEntry> {
882 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
883};
884
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100885template <> struct MappingTraits<ELFYAML::VerdefEntry> {
886 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
887};
888
889template <> struct MappingTraits<ELFYAML::VerneedEntry> {
890 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
891};
892
893template <> struct MappingTraits<ELFYAML::VernauxEntry> {
894 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
895};
896
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200897template <> struct MappingTraits<ELFYAML::LinkerOption> {
898 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
899};
900
901template <> struct MappingTraits<ELFYAML::CallGraphEntry> {
902 static void mapping(IO &IO, ELFYAML::CallGraphEntry &E);
903};
904
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100905template <> struct MappingTraits<ELFYAML::Relocation> {
906 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
907};
908
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200909template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
910 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
911};
912
913template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
914 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
915 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100916};
917
918template <>
919struct MappingTraits<ELFYAML::Object> {
920 static void mapping(IO &IO, ELFYAML::Object &Object);
921};
922
923template <> struct MappingTraits<ELFYAML::SectionOrType> {
924 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
925};
926
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100927} // end namespace yaml
928} // end namespace llvm
929
930#endif // LLVM_OBJECTYAML_ELFYAML_H