1 //===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file declares classes for handling the YAML representation
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_OBJECTYAML_ELFYAML_H
16 #define LLVM_OBJECTYAML_ELFYAML_H
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ObjectYAML/YAML.h"
20 #include "llvm/Support/YAMLTraits.h"
28 StringRef
dropUniqueSuffix(StringRef S
);
30 // These types are invariant across 32/64-bit ELF, so for simplicity just
31 // directly give them their exact sizes. We don't need to worry about
32 // endianness because these are just the types in the YAMLIO structures,
33 // and are appropriately converted to the necessary endianness when
34 // reading/generating binary object files.
35 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
36 // the common prefix of the respective constants. E.g. ELF_EM corresponds
37 // to the `e_machine` constants, like `EM_X86_64`.
38 // In the future, these would probably be better suited by C++11 enum
39 // class's with appropriate fixed underlying type.
40 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET
)
41 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT
)
42 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM
)
43 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS
)
44 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA
)
45 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI
)
46 // Just use 64, since it can hold 32-bit values too.
47 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF
)
48 // Just use 64, since it can hold 32-bit values too.
49 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG
)
50 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF
)
51 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT
)
52 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL
)
53 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS
)
54 // Just use 64, since it can hold 32-bit values too.
55 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF
)
56 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN
)
57 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB
)
58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT
)
60 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG
)
61 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP
)
62 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT
)
63 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE
)
64 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1
)
65 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA
)
67 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
68 // since 64-bit can hold 32-bit values too.
73 llvm::yaml::Hex8 ABIVersion
;
77 llvm::yaml::Hex64 Entry
;
79 Optional
<llvm::yaml::Hex16
> SHEntSize
;
80 Optional
<llvm::yaml::Hex64
> SHOff
;
81 Optional
<llvm::yaml::Hex16
> SHNum
;
82 Optional
<llvm::yaml::Hex16
> SHStrNdx
;
89 struct ProgramHeader
{
92 llvm::yaml::Hex64 VAddr
;
93 llvm::yaml::Hex64 PAddr
;
94 Optional
<llvm::yaml::Hex64
> Align
;
95 Optional
<llvm::yaml::Hex64
> FileSize
;
96 Optional
<llvm::yaml::Hex64
> MemSize
;
97 Optional
<llvm::yaml::Hex64
> Offset
;
98 std::vector
<SectionName
> Sections
;
103 Optional
<uint32_t> NameIndex
;
106 Optional
<ELF_SHN
> Index
;
108 llvm::yaml::Hex64 Value
;
109 llvm::yaml::Hex64 Size
;
110 Optional
<uint8_t> Other
;
113 struct SectionOrType
{
114 StringRef sectionNameOrType
;
117 struct DynamicEntry
{
119 llvm::yaml::Hex64 Val
;
122 struct StackSizeEntry
{
123 llvm::yaml::Hex64 Address
;
124 llvm::yaml::Hex64 Size
;
128 enum class SectionKind
{
146 Optional
<ELF_SHF
> Flags
;
147 llvm::yaml::Hex64 Address
;
149 llvm::yaml::Hex64 AddressAlign
;
150 Optional
<llvm::yaml::Hex64
> EntSize
;
152 // Usually sections are not created implicitly, but loaded from YAML.
153 // When they are, this flag is used to signal about that.
156 Section(SectionKind Kind
, bool IsImplicit
= false)
157 : Kind(Kind
), IsImplicit(IsImplicit
) {}
160 // The following members are used to override section fields which is
161 // useful for creating invalid objects.
163 // This can be used to override the offset stored in the sh_name field.
164 // It does not affect the name stored in the string table.
165 Optional
<llvm::yaml::Hex64
> ShName
;
167 // This can be used to override the sh_offset field. It does not place the
168 // section data at the offset specified.
169 Optional
<llvm::yaml::Hex64
> ShOffset
;
171 // This can be used to override the sh_size field. It does not affect the
173 Optional
<llvm::yaml::Hex64
> ShSize
;
176 struct StackSizesSection
: Section
{
177 Optional
<yaml::BinaryRef
> Content
;
178 Optional
<llvm::yaml::Hex64
> Size
;
179 Optional
<std::vector
<StackSizeEntry
>> Entries
;
181 StackSizesSection() : Section(SectionKind::StackSizes
) {}
183 static bool classof(const Section
*S
) {
184 return S
->Kind
== SectionKind::StackSizes
;
187 static bool nameMatches(StringRef Name
) {
188 return Name
== ".stack_sizes";
192 struct DynamicSection
: Section
{
193 std::vector
<DynamicEntry
> Entries
;
194 Optional
<yaml::BinaryRef
> Content
;
196 DynamicSection() : Section(SectionKind::Dynamic
) {}
198 static bool classof(const Section
*S
) {
199 return S
->Kind
== SectionKind::Dynamic
;
203 struct RawContentSection
: Section
{
204 Optional
<yaml::BinaryRef
> Content
;
205 Optional
<llvm::yaml::Hex64
> Size
;
206 Optional
<llvm::yaml::Hex64
> Info
;
208 RawContentSection() : Section(SectionKind::RawContent
) {}
210 static bool classof(const Section
*S
) {
211 return S
->Kind
== SectionKind::RawContent
;
215 struct NoBitsSection
: Section
{
216 llvm::yaml::Hex64 Size
;
218 NoBitsSection() : Section(SectionKind::NoBits
) {}
220 static bool classof(const Section
*S
) {
221 return S
->Kind
== SectionKind::NoBits
;
225 struct HashSection
: Section
{
226 Optional
<yaml::BinaryRef
> Content
;
227 Optional
<llvm::yaml::Hex64
> Size
;
228 Optional
<std::vector
<uint32_t>> Bucket
;
229 Optional
<std::vector
<uint32_t>> Chain
;
231 HashSection() : Section(SectionKind::Hash
) {}
233 static bool classof(const Section
*S
) { return S
->Kind
== SectionKind::Hash
; }
236 struct VernauxEntry
{
243 struct VerneedEntry
{
246 std::vector
<VernauxEntry
> AuxV
;
249 struct VerneedSection
: Section
{
250 std::vector
<VerneedEntry
> VerneedV
;
251 llvm::yaml::Hex64 Info
;
253 VerneedSection() : Section(SectionKind::Verneed
) {}
255 static bool classof(const Section
*S
) {
256 return S
->Kind
== SectionKind::Verneed
;
260 struct AddrsigSymbol
{
261 AddrsigSymbol(StringRef N
) : Name(N
), Index(None
) {}
262 AddrsigSymbol(llvm::yaml::Hex32 Ndx
) : Name(None
), Index(Ndx
) {}
263 AddrsigSymbol() : Name(None
), Index(None
) {}
265 Optional
<StringRef
> Name
;
266 Optional
<llvm::yaml::Hex32
> Index
;
269 struct AddrsigSection
: Section
{
270 Optional
<yaml::BinaryRef
> Content
;
271 Optional
<std::vector
<AddrsigSymbol
>> Symbols
;
273 AddrsigSection() : Section(SectionKind::Addrsig
) {}
274 static bool classof(const Section
*S
) {
275 return S
->Kind
== SectionKind::Addrsig
;
279 struct SymverSection
: Section
{
280 std::vector
<uint16_t> Entries
;
282 SymverSection() : Section(SectionKind::Symver
) {}
284 static bool classof(const Section
*S
) {
285 return S
->Kind
== SectionKind::Symver
;
294 std::vector
<StringRef
> VerNames
;
297 struct VerdefSection
: Section
{
298 std::vector
<VerdefEntry
> Entries
;
299 llvm::yaml::Hex64 Info
;
301 VerdefSection() : Section(SectionKind::Verdef
) {}
303 static bool classof(const Section
*S
) {
304 return S
->Kind
== SectionKind::Verdef
;
308 struct Group
: Section
{
309 // Members of a group contain a flag and a list of section indices
310 // that are part of the group.
311 std::vector
<SectionOrType
> Members
;
312 StringRef Signature
; /* Info */
314 Group() : Section(SectionKind::Group
) {}
316 static bool classof(const Section
*S
) {
317 return S
->Kind
== SectionKind::Group
;
322 llvm::yaml::Hex64 Offset
;
325 Optional
<StringRef
> Symbol
;
328 struct RelocationSection
: Section
{
329 std::vector
<Relocation
> Relocations
;
330 StringRef RelocatableSec
; /* Info */
332 RelocationSection() : Section(SectionKind::Relocation
) {}
334 static bool classof(const Section
*S
) {
335 return S
->Kind
== SectionKind::Relocation
;
339 struct SymtabShndxSection
: Section
{
340 std::vector
<uint32_t> Entries
;
342 SymtabShndxSection() : Section(SectionKind::SymtabShndxSection
) {}
344 static bool classof(const Section
*S
) {
345 return S
->Kind
== SectionKind::SymtabShndxSection
;
349 // Represents .MIPS.abiflags section
350 struct MipsABIFlags
: Section
{
351 llvm::yaml::Hex16 Version
;
353 llvm::yaml::Hex8 ISARevision
;
354 MIPS_AFL_REG GPRSize
;
355 MIPS_AFL_REG CPR1Size
;
356 MIPS_AFL_REG CPR2Size
;
358 MIPS_AFL_EXT ISAExtension
;
360 MIPS_AFL_FLAGS1 Flags1
;
361 llvm::yaml::Hex32 Flags2
;
363 MipsABIFlags() : Section(SectionKind::MipsABIFlags
) {}
365 static bool classof(const Section
*S
) {
366 return S
->Kind
== SectionKind::MipsABIFlags
;
372 std::vector
<ProgramHeader
> ProgramHeaders
;
373 std::vector
<std::unique_ptr
<Section
>> Sections
;
374 // Although in reality the symbols reside in a section, it is a lot
375 // cleaner and nicer if we read them from the YAML as a separate
376 // top-level key, which automatically ensures that invariants like there
377 // being a single SHT_SYMTAB section are upheld.
378 std::vector
<Symbol
> Symbols
;
379 std::vector
<Symbol
> DynamicSymbols
;
382 } // end namespace ELFYAML
383 } // end namespace llvm
385 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::AddrsigSymbol
)
386 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry
)
387 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry
)
388 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader
)
389 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr
<llvm::ELFYAML::Section
>)
390 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol
)
391 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry
)
392 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry
)
393 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry
)
394 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation
)
395 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType
)
396 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName
)
402 struct ScalarEnumerationTraits
<ELFYAML::ELF_ET
> {
403 static void enumeration(IO
&IO
, ELFYAML::ELF_ET
&Value
);
406 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_PT
> {
407 static void enumeration(IO
&IO
, ELFYAML::ELF_PT
&Value
);
411 struct ScalarEnumerationTraits
<ELFYAML::ELF_EM
> {
412 static void enumeration(IO
&IO
, ELFYAML::ELF_EM
&Value
);
416 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFCLASS
> {
417 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFCLASS
&Value
);
421 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFDATA
> {
422 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFDATA
&Value
);
426 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFOSABI
> {
427 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFOSABI
&Value
);
431 struct ScalarBitSetTraits
<ELFYAML::ELF_EF
> {
432 static void bitset(IO
&IO
, ELFYAML::ELF_EF
&Value
);
435 template <> struct ScalarBitSetTraits
<ELFYAML::ELF_PF
> {
436 static void bitset(IO
&IO
, ELFYAML::ELF_PF
&Value
);
440 struct ScalarEnumerationTraits
<ELFYAML::ELF_SHT
> {
441 static void enumeration(IO
&IO
, ELFYAML::ELF_SHT
&Value
);
445 struct ScalarBitSetTraits
<ELFYAML::ELF_SHF
> {
446 static void bitset(IO
&IO
, ELFYAML::ELF_SHF
&Value
);
449 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_SHN
> {
450 static void enumeration(IO
&IO
, ELFYAML::ELF_SHN
&Value
);
453 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_STB
> {
454 static void enumeration(IO
&IO
, ELFYAML::ELF_STB
&Value
);
458 struct ScalarEnumerationTraits
<ELFYAML::ELF_STT
> {
459 static void enumeration(IO
&IO
, ELFYAML::ELF_STT
&Value
);
463 struct ScalarEnumerationTraits
<ELFYAML::ELF_REL
> {
464 static void enumeration(IO
&IO
, ELFYAML::ELF_REL
&Value
);
468 struct ScalarEnumerationTraits
<ELFYAML::ELF_DYNTAG
> {
469 static void enumeration(IO
&IO
, ELFYAML::ELF_DYNTAG
&Value
);
473 struct ScalarEnumerationTraits
<ELFYAML::ELF_RSS
> {
474 static void enumeration(IO
&IO
, ELFYAML::ELF_RSS
&Value
);
478 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_REG
> {
479 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_REG
&Value
);
483 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ABI_FP
> {
484 static void enumeration(IO
&IO
, ELFYAML::MIPS_ABI_FP
&Value
);
488 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_EXT
> {
489 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_EXT
&Value
);
493 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ISA
> {
494 static void enumeration(IO
&IO
, ELFYAML::MIPS_ISA
&Value
);
498 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_ASE
> {
499 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_ASE
&Value
);
503 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_FLAGS1
> {
504 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_FLAGS1
&Value
);
508 struct MappingTraits
<ELFYAML::FileHeader
> {
509 static void mapping(IO
&IO
, ELFYAML::FileHeader
&FileHdr
);
512 template <> struct MappingTraits
<ELFYAML::ProgramHeader
> {
513 static void mapping(IO
&IO
, ELFYAML::ProgramHeader
&FileHdr
);
517 struct MappingTraits
<ELFYAML::Symbol
> {
518 static void mapping(IO
&IO
, ELFYAML::Symbol
&Symbol
);
519 static StringRef
validate(IO
&IO
, ELFYAML::Symbol
&Symbol
);
522 template <> struct MappingTraits
<ELFYAML::StackSizeEntry
> {
523 static void mapping(IO
&IO
, ELFYAML::StackSizeEntry
&Rel
);
526 template <> struct MappingTraits
<ELFYAML::DynamicEntry
> {
527 static void mapping(IO
&IO
, ELFYAML::DynamicEntry
&Rel
);
530 template <> struct MappingTraits
<ELFYAML::VerdefEntry
> {
531 static void mapping(IO
&IO
, ELFYAML::VerdefEntry
&E
);
534 template <> struct MappingTraits
<ELFYAML::VerneedEntry
> {
535 static void mapping(IO
&IO
, ELFYAML::VerneedEntry
&E
);
538 template <> struct MappingTraits
<ELFYAML::VernauxEntry
> {
539 static void mapping(IO
&IO
, ELFYAML::VernauxEntry
&E
);
542 template <> struct MappingTraits
<ELFYAML::AddrsigSymbol
> {
543 static void mapping(IO
&IO
, ELFYAML::AddrsigSymbol
&Sym
);
546 template <> struct MappingTraits
<ELFYAML::Relocation
> {
547 static void mapping(IO
&IO
, ELFYAML::Relocation
&Rel
);
551 struct MappingTraits
<std::unique_ptr
<ELFYAML::Section
>> {
552 static void mapping(IO
&IO
, std::unique_ptr
<ELFYAML::Section
> &Section
);
553 static StringRef
validate(IO
&io
, std::unique_ptr
<ELFYAML::Section
> &Section
);
557 struct MappingTraits
<ELFYAML::Object
> {
558 static void mapping(IO
&IO
, ELFYAML::Object
&Object
);
561 template <> struct MappingTraits
<ELFYAML::SectionOrType
> {
562 static void mapping(IO
&IO
, ELFYAML::SectionOrType
§ionOrType
);
565 template <> struct MappingTraits
<ELFYAML::SectionName
> {
566 static void mapping(IO
&IO
, ELFYAML::SectionName
§ionName
);
569 } // end namespace yaml
570 } // end namespace llvm
572 #endif // LLVM_OBJECTYAML_ELFYAML_H