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 // These types are invariant across 32/64-bit ELF, so for simplicity just
29 // directly give them their exact sizes. We don't need to worry about
30 // endianness because these are just the types in the YAMLIO structures,
31 // and are appropriately converted to the necessary endianness when
32 // reading/generating binary object files.
33 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
34 // the common prefix of the respective constants. E.g. ELF_EM corresponds
35 // to the `e_machine` constants, like `EM_X86_64`.
36 // In the future, these would probably be better suited by C++11 enum
37 // class's with appropriate fixed underlying type.
38 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET
)
39 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT
)
40 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM
)
41 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS
)
42 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA
)
43 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI
)
44 // Just use 64, since it can hold 32-bit values too.
45 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF
)
46 // Just use 64, since it can hold 32-bit values too.
47 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG
)
48 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF
)
49 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT
)
50 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL
)
51 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS
)
52 // Just use 64, since it can hold 32-bit values too.
53 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF
)
54 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN
)
55 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB
)
56 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT
)
58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG
)
59 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP
)
60 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT
)
61 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE
)
62 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1
)
63 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA
)
65 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
66 // since 64-bit can hold 32-bit values too.
71 llvm::yaml::Hex8 ABIVersion
;
75 llvm::yaml::Hex64 Entry
;
77 Optional
<llvm::yaml::Hex16
> SHEntSize
;
78 Optional
<llvm::yaml::Hex64
> SHOff
;
79 Optional
<llvm::yaml::Hex16
> SHNum
;
80 Optional
<llvm::yaml::Hex16
> SHStrNdx
;
87 struct ProgramHeader
{
90 llvm::yaml::Hex64 VAddr
;
91 llvm::yaml::Hex64 PAddr
;
92 Optional
<llvm::yaml::Hex64
> Align
;
93 Optional
<llvm::yaml::Hex64
> FileSize
;
94 Optional
<llvm::yaml::Hex64
> MemSize
;
95 Optional
<llvm::yaml::Hex64
> Offset
;
96 std::vector
<SectionName
> Sections
;
101 Optional
<uint32_t> NameIndex
;
104 Optional
<ELF_SHN
> Index
;
106 llvm::yaml::Hex64 Value
;
107 llvm::yaml::Hex64 Size
;
108 Optional
<uint8_t> Other
;
111 struct SectionOrType
{
112 StringRef sectionNameOrType
;
115 struct DynamicEntry
{
117 llvm::yaml::Hex64 Val
;
120 struct StackSizeEntry
{
121 llvm::yaml::Hex64 Address
;
122 llvm::yaml::Hex64 Size
;
126 enum class SectionKind
{
142 Optional
<ELF_SHF
> Flags
;
143 llvm::yaml::Hex64 Address
;
145 llvm::yaml::Hex64 AddressAlign
;
146 Optional
<llvm::yaml::Hex64
> EntSize
;
148 // Usually sections are not created implicitly, but loaded from YAML.
149 // When they are, this flag is used to signal about that.
152 Section(SectionKind Kind
, bool IsImplicit
= false)
153 : Kind(Kind
), IsImplicit(IsImplicit
) {}
156 // The following members are used to override section fields which is
157 // useful for creating invalid objects.
159 // This can be used to override the offset stored in the sh_name field.
160 // It does not affect the name stored in the string table.
161 Optional
<llvm::yaml::Hex64
> ShName
;
163 // This can be used to override the sh_offset field. It does not place the
164 // section data at the offset specified.
165 Optional
<llvm::yaml::Hex64
> ShOffset
;
167 // This can be used to override the sh_size field. It does not affect the
169 Optional
<llvm::yaml::Hex64
> ShSize
;
172 struct StackSizesSection
: Section
{
173 Optional
<yaml::BinaryRef
> Content
;
174 Optional
<std::vector
<StackSizeEntry
>> Entries
;
176 StackSizesSection() : Section(SectionKind::StackSizes
) {}
178 static bool classof(const Section
*S
) {
179 return S
->Kind
== SectionKind::StackSizes
;
182 static bool nameMatches(StringRef Name
) {
183 return Name
== ".stack_sizes";
187 struct DynamicSection
: Section
{
188 std::vector
<DynamicEntry
> Entries
;
189 Optional
<yaml::BinaryRef
> Content
;
191 DynamicSection() : Section(SectionKind::Dynamic
) {}
193 static bool classof(const Section
*S
) {
194 return S
->Kind
== SectionKind::Dynamic
;
198 struct RawContentSection
: Section
{
199 Optional
<yaml::BinaryRef
> Content
;
200 Optional
<llvm::yaml::Hex64
> Size
;
201 Optional
<llvm::yaml::Hex64
> Info
;
203 RawContentSection() : Section(SectionKind::RawContent
) {}
205 static bool classof(const Section
*S
) {
206 return S
->Kind
== SectionKind::RawContent
;
210 struct NoBitsSection
: Section
{
211 llvm::yaml::Hex64 Size
;
213 NoBitsSection() : Section(SectionKind::NoBits
) {}
215 static bool classof(const Section
*S
) {
216 return S
->Kind
== SectionKind::NoBits
;
220 struct VernauxEntry
{
227 struct VerneedEntry
{
230 std::vector
<VernauxEntry
> AuxV
;
233 struct VerneedSection
: Section
{
234 std::vector
<VerneedEntry
> VerneedV
;
235 llvm::yaml::Hex64 Info
;
237 VerneedSection() : Section(SectionKind::Verneed
) {}
239 static bool classof(const Section
*S
) {
240 return S
->Kind
== SectionKind::Verneed
;
244 struct SymverSection
: Section
{
245 std::vector
<uint16_t> Entries
;
247 SymverSection() : Section(SectionKind::Symver
) {}
249 static bool classof(const Section
*S
) {
250 return S
->Kind
== SectionKind::Symver
;
259 std::vector
<StringRef
> VerNames
;
262 struct VerdefSection
: Section
{
263 std::vector
<VerdefEntry
> Entries
;
264 llvm::yaml::Hex64 Info
;
266 VerdefSection() : Section(SectionKind::Verdef
) {}
268 static bool classof(const Section
*S
) {
269 return S
->Kind
== SectionKind::Verdef
;
273 struct Group
: Section
{
274 // Members of a group contain a flag and a list of section indices
275 // that are part of the group.
276 std::vector
<SectionOrType
> Members
;
277 StringRef Signature
; /* Info */
279 Group() : Section(SectionKind::Group
) {}
281 static bool classof(const Section
*S
) {
282 return S
->Kind
== SectionKind::Group
;
287 llvm::yaml::Hex64 Offset
;
290 Optional
<StringRef
> Symbol
;
293 struct RelocationSection
: Section
{
294 std::vector
<Relocation
> Relocations
;
295 StringRef RelocatableSec
; /* Info */
297 RelocationSection() : Section(SectionKind::Relocation
) {}
299 static bool classof(const Section
*S
) {
300 return S
->Kind
== SectionKind::Relocation
;
304 struct SymtabShndxSection
: Section
{
305 std::vector
<uint32_t> Entries
;
307 SymtabShndxSection() : Section(SectionKind::SymtabShndxSection
) {}
309 static bool classof(const Section
*S
) {
310 return S
->Kind
== SectionKind::SymtabShndxSection
;
314 // Represents .MIPS.abiflags section
315 struct MipsABIFlags
: Section
{
316 llvm::yaml::Hex16 Version
;
318 llvm::yaml::Hex8 ISARevision
;
319 MIPS_AFL_REG GPRSize
;
320 MIPS_AFL_REG CPR1Size
;
321 MIPS_AFL_REG CPR2Size
;
323 MIPS_AFL_EXT ISAExtension
;
325 MIPS_AFL_FLAGS1 Flags1
;
326 llvm::yaml::Hex32 Flags2
;
328 MipsABIFlags() : Section(SectionKind::MipsABIFlags
) {}
330 static bool classof(const Section
*S
) {
331 return S
->Kind
== SectionKind::MipsABIFlags
;
337 std::vector
<ProgramHeader
> ProgramHeaders
;
338 std::vector
<std::unique_ptr
<Section
>> Sections
;
339 // Although in reality the symbols reside in a section, it is a lot
340 // cleaner and nicer if we read them from the YAML as a separate
341 // top-level key, which automatically ensures that invariants like there
342 // being a single SHT_SYMTAB section are upheld.
343 std::vector
<Symbol
> Symbols
;
344 std::vector
<Symbol
> DynamicSymbols
;
347 } // end namespace ELFYAML
348 } // end namespace llvm
350 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry
)
351 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry
)
352 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader
)
353 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr
<llvm::ELFYAML::Section
>)
354 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol
)
355 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry
)
356 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry
)
357 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry
)
358 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation
)
359 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType
)
360 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName
)
366 struct ScalarEnumerationTraits
<ELFYAML::ELF_ET
> {
367 static void enumeration(IO
&IO
, ELFYAML::ELF_ET
&Value
);
370 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_PT
> {
371 static void enumeration(IO
&IO
, ELFYAML::ELF_PT
&Value
);
375 struct ScalarEnumerationTraits
<ELFYAML::ELF_EM
> {
376 static void enumeration(IO
&IO
, ELFYAML::ELF_EM
&Value
);
380 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFCLASS
> {
381 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFCLASS
&Value
);
385 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFDATA
> {
386 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFDATA
&Value
);
390 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFOSABI
> {
391 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFOSABI
&Value
);
395 struct ScalarBitSetTraits
<ELFYAML::ELF_EF
> {
396 static void bitset(IO
&IO
, ELFYAML::ELF_EF
&Value
);
399 template <> struct ScalarBitSetTraits
<ELFYAML::ELF_PF
> {
400 static void bitset(IO
&IO
, ELFYAML::ELF_PF
&Value
);
404 struct ScalarEnumerationTraits
<ELFYAML::ELF_SHT
> {
405 static void enumeration(IO
&IO
, ELFYAML::ELF_SHT
&Value
);
409 struct ScalarBitSetTraits
<ELFYAML::ELF_SHF
> {
410 static void bitset(IO
&IO
, ELFYAML::ELF_SHF
&Value
);
413 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_SHN
> {
414 static void enumeration(IO
&IO
, ELFYAML::ELF_SHN
&Value
);
417 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_STB
> {
418 static void enumeration(IO
&IO
, ELFYAML::ELF_STB
&Value
);
422 struct ScalarEnumerationTraits
<ELFYAML::ELF_STT
> {
423 static void enumeration(IO
&IO
, ELFYAML::ELF_STT
&Value
);
427 struct ScalarEnumerationTraits
<ELFYAML::ELF_REL
> {
428 static void enumeration(IO
&IO
, ELFYAML::ELF_REL
&Value
);
432 struct ScalarEnumerationTraits
<ELFYAML::ELF_DYNTAG
> {
433 static void enumeration(IO
&IO
, ELFYAML::ELF_DYNTAG
&Value
);
437 struct ScalarEnumerationTraits
<ELFYAML::ELF_RSS
> {
438 static void enumeration(IO
&IO
, ELFYAML::ELF_RSS
&Value
);
442 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_REG
> {
443 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_REG
&Value
);
447 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ABI_FP
> {
448 static void enumeration(IO
&IO
, ELFYAML::MIPS_ABI_FP
&Value
);
452 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_EXT
> {
453 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_EXT
&Value
);
457 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ISA
> {
458 static void enumeration(IO
&IO
, ELFYAML::MIPS_ISA
&Value
);
462 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_ASE
> {
463 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_ASE
&Value
);
467 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_FLAGS1
> {
468 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_FLAGS1
&Value
);
472 struct MappingTraits
<ELFYAML::FileHeader
> {
473 static void mapping(IO
&IO
, ELFYAML::FileHeader
&FileHdr
);
476 template <> struct MappingTraits
<ELFYAML::ProgramHeader
> {
477 static void mapping(IO
&IO
, ELFYAML::ProgramHeader
&FileHdr
);
481 struct MappingTraits
<ELFYAML::Symbol
> {
482 static void mapping(IO
&IO
, ELFYAML::Symbol
&Symbol
);
483 static StringRef
validate(IO
&IO
, ELFYAML::Symbol
&Symbol
);
486 template <> struct MappingTraits
<ELFYAML::StackSizeEntry
> {
487 static void mapping(IO
&IO
, ELFYAML::StackSizeEntry
&Rel
);
490 template <> struct MappingTraits
<ELFYAML::DynamicEntry
> {
491 static void mapping(IO
&IO
, ELFYAML::DynamicEntry
&Rel
);
494 template <> struct MappingTraits
<ELFYAML::VerdefEntry
> {
495 static void mapping(IO
&IO
, ELFYAML::VerdefEntry
&E
);
498 template <> struct MappingTraits
<ELFYAML::VerneedEntry
> {
499 static void mapping(IO
&IO
, ELFYAML::VerneedEntry
&E
);
502 template <> struct MappingTraits
<ELFYAML::VernauxEntry
> {
503 static void mapping(IO
&IO
, ELFYAML::VernauxEntry
&E
);
506 template <> struct MappingTraits
<ELFYAML::Relocation
> {
507 static void mapping(IO
&IO
, ELFYAML::Relocation
&Rel
);
511 struct MappingTraits
<std::unique_ptr
<ELFYAML::Section
>> {
512 static void mapping(IO
&IO
, std::unique_ptr
<ELFYAML::Section
> &Section
);
513 static StringRef
validate(IO
&io
, std::unique_ptr
<ELFYAML::Section
> &Section
);
517 struct MappingTraits
<ELFYAML::Object
> {
518 static void mapping(IO
&IO
, ELFYAML::Object
&Object
);
521 template <> struct MappingTraits
<ELFYAML::SectionOrType
> {
522 static void mapping(IO
&IO
, ELFYAML::SectionOrType
§ionOrType
);
525 template <> struct MappingTraits
<ELFYAML::SectionName
> {
526 static void mapping(IO
&IO
, ELFYAML::SectionName
§ionName
);
529 } // end namespace yaml
530 } // end namespace llvm
532 #endif // LLVM_OBJECTYAML_ELFYAML_H