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
{
144 Optional
<ELF_SHF
> Flags
;
145 llvm::yaml::Hex64 Address
;
147 llvm::yaml::Hex64 AddressAlign
;
148 Optional
<llvm::yaml::Hex64
> EntSize
;
150 // Usually sections are not created implicitly, but loaded from YAML.
151 // When they are, this flag is used to signal about that.
154 Section(SectionKind Kind
, bool IsImplicit
= false)
155 : Kind(Kind
), IsImplicit(IsImplicit
) {}
158 // The following members are used to override section fields which is
159 // useful for creating invalid objects.
161 // This can be used to override the offset stored in the sh_name field.
162 // It does not affect the name stored in the string table.
163 Optional
<llvm::yaml::Hex64
> ShName
;
165 // This can be used to override the sh_offset field. It does not place the
166 // section data at the offset specified.
167 Optional
<llvm::yaml::Hex64
> ShOffset
;
169 // This can be used to override the sh_size field. It does not affect the
171 Optional
<llvm::yaml::Hex64
> ShSize
;
174 struct StackSizesSection
: Section
{
175 Optional
<yaml::BinaryRef
> Content
;
176 Optional
<llvm::yaml::Hex64
> Size
;
177 Optional
<std::vector
<StackSizeEntry
>> Entries
;
179 StackSizesSection() : Section(SectionKind::StackSizes
) {}
181 static bool classof(const Section
*S
) {
182 return S
->Kind
== SectionKind::StackSizes
;
185 static bool nameMatches(StringRef Name
) {
186 return Name
== ".stack_sizes";
190 struct DynamicSection
: Section
{
191 std::vector
<DynamicEntry
> Entries
;
192 Optional
<yaml::BinaryRef
> Content
;
194 DynamicSection() : Section(SectionKind::Dynamic
) {}
196 static bool classof(const Section
*S
) {
197 return S
->Kind
== SectionKind::Dynamic
;
201 struct RawContentSection
: Section
{
202 Optional
<yaml::BinaryRef
> Content
;
203 Optional
<llvm::yaml::Hex64
> Size
;
204 Optional
<llvm::yaml::Hex64
> Info
;
206 RawContentSection() : Section(SectionKind::RawContent
) {}
208 static bool classof(const Section
*S
) {
209 return S
->Kind
== SectionKind::RawContent
;
213 struct NoBitsSection
: Section
{
214 llvm::yaml::Hex64 Size
;
216 NoBitsSection() : Section(SectionKind::NoBits
) {}
218 static bool classof(const Section
*S
) {
219 return S
->Kind
== SectionKind::NoBits
;
223 struct VernauxEntry
{
230 struct VerneedEntry
{
233 std::vector
<VernauxEntry
> AuxV
;
236 struct VerneedSection
: Section
{
237 std::vector
<VerneedEntry
> VerneedV
;
238 llvm::yaml::Hex64 Info
;
240 VerneedSection() : Section(SectionKind::Verneed
) {}
242 static bool classof(const Section
*S
) {
243 return S
->Kind
== SectionKind::Verneed
;
247 struct SymverSection
: Section
{
248 std::vector
<uint16_t> Entries
;
250 SymverSection() : Section(SectionKind::Symver
) {}
252 static bool classof(const Section
*S
) {
253 return S
->Kind
== SectionKind::Symver
;
262 std::vector
<StringRef
> VerNames
;
265 struct VerdefSection
: Section
{
266 std::vector
<VerdefEntry
> Entries
;
267 llvm::yaml::Hex64 Info
;
269 VerdefSection() : Section(SectionKind::Verdef
) {}
271 static bool classof(const Section
*S
) {
272 return S
->Kind
== SectionKind::Verdef
;
276 struct Group
: Section
{
277 // Members of a group contain a flag and a list of section indices
278 // that are part of the group.
279 std::vector
<SectionOrType
> Members
;
280 StringRef Signature
; /* Info */
282 Group() : Section(SectionKind::Group
) {}
284 static bool classof(const Section
*S
) {
285 return S
->Kind
== SectionKind::Group
;
290 llvm::yaml::Hex64 Offset
;
293 Optional
<StringRef
> Symbol
;
296 struct RelocationSection
: Section
{
297 std::vector
<Relocation
> Relocations
;
298 StringRef RelocatableSec
; /* Info */
300 RelocationSection() : Section(SectionKind::Relocation
) {}
302 static bool classof(const Section
*S
) {
303 return S
->Kind
== SectionKind::Relocation
;
307 struct SymtabShndxSection
: Section
{
308 std::vector
<uint32_t> Entries
;
310 SymtabShndxSection() : Section(SectionKind::SymtabShndxSection
) {}
312 static bool classof(const Section
*S
) {
313 return S
->Kind
== SectionKind::SymtabShndxSection
;
317 // Represents .MIPS.abiflags section
318 struct MipsABIFlags
: Section
{
319 llvm::yaml::Hex16 Version
;
321 llvm::yaml::Hex8 ISARevision
;
322 MIPS_AFL_REG GPRSize
;
323 MIPS_AFL_REG CPR1Size
;
324 MIPS_AFL_REG CPR2Size
;
326 MIPS_AFL_EXT ISAExtension
;
328 MIPS_AFL_FLAGS1 Flags1
;
329 llvm::yaml::Hex32 Flags2
;
331 MipsABIFlags() : Section(SectionKind::MipsABIFlags
) {}
333 static bool classof(const Section
*S
) {
334 return S
->Kind
== SectionKind::MipsABIFlags
;
340 std::vector
<ProgramHeader
> ProgramHeaders
;
341 std::vector
<std::unique_ptr
<Section
>> Sections
;
342 // Although in reality the symbols reside in a section, it is a lot
343 // cleaner and nicer if we read them from the YAML as a separate
344 // top-level key, which automatically ensures that invariants like there
345 // being a single SHT_SYMTAB section are upheld.
346 std::vector
<Symbol
> Symbols
;
347 std::vector
<Symbol
> DynamicSymbols
;
350 } // end namespace ELFYAML
351 } // end namespace llvm
353 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry
)
354 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry
)
355 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader
)
356 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr
<llvm::ELFYAML::Section
>)
357 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol
)
358 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry
)
359 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry
)
360 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry
)
361 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation
)
362 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType
)
363 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName
)
369 struct ScalarEnumerationTraits
<ELFYAML::ELF_ET
> {
370 static void enumeration(IO
&IO
, ELFYAML::ELF_ET
&Value
);
373 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_PT
> {
374 static void enumeration(IO
&IO
, ELFYAML::ELF_PT
&Value
);
378 struct ScalarEnumerationTraits
<ELFYAML::ELF_EM
> {
379 static void enumeration(IO
&IO
, ELFYAML::ELF_EM
&Value
);
383 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFCLASS
> {
384 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFCLASS
&Value
);
388 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFDATA
> {
389 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFDATA
&Value
);
393 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFOSABI
> {
394 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFOSABI
&Value
);
398 struct ScalarBitSetTraits
<ELFYAML::ELF_EF
> {
399 static void bitset(IO
&IO
, ELFYAML::ELF_EF
&Value
);
402 template <> struct ScalarBitSetTraits
<ELFYAML::ELF_PF
> {
403 static void bitset(IO
&IO
, ELFYAML::ELF_PF
&Value
);
407 struct ScalarEnumerationTraits
<ELFYAML::ELF_SHT
> {
408 static void enumeration(IO
&IO
, ELFYAML::ELF_SHT
&Value
);
412 struct ScalarBitSetTraits
<ELFYAML::ELF_SHF
> {
413 static void bitset(IO
&IO
, ELFYAML::ELF_SHF
&Value
);
416 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_SHN
> {
417 static void enumeration(IO
&IO
, ELFYAML::ELF_SHN
&Value
);
420 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_STB
> {
421 static void enumeration(IO
&IO
, ELFYAML::ELF_STB
&Value
);
425 struct ScalarEnumerationTraits
<ELFYAML::ELF_STT
> {
426 static void enumeration(IO
&IO
, ELFYAML::ELF_STT
&Value
);
430 struct ScalarEnumerationTraits
<ELFYAML::ELF_REL
> {
431 static void enumeration(IO
&IO
, ELFYAML::ELF_REL
&Value
);
435 struct ScalarEnumerationTraits
<ELFYAML::ELF_DYNTAG
> {
436 static void enumeration(IO
&IO
, ELFYAML::ELF_DYNTAG
&Value
);
440 struct ScalarEnumerationTraits
<ELFYAML::ELF_RSS
> {
441 static void enumeration(IO
&IO
, ELFYAML::ELF_RSS
&Value
);
445 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_REG
> {
446 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_REG
&Value
);
450 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ABI_FP
> {
451 static void enumeration(IO
&IO
, ELFYAML::MIPS_ABI_FP
&Value
);
455 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_EXT
> {
456 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_EXT
&Value
);
460 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ISA
> {
461 static void enumeration(IO
&IO
, ELFYAML::MIPS_ISA
&Value
);
465 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_ASE
> {
466 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_ASE
&Value
);
470 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_FLAGS1
> {
471 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_FLAGS1
&Value
);
475 struct MappingTraits
<ELFYAML::FileHeader
> {
476 static void mapping(IO
&IO
, ELFYAML::FileHeader
&FileHdr
);
479 template <> struct MappingTraits
<ELFYAML::ProgramHeader
> {
480 static void mapping(IO
&IO
, ELFYAML::ProgramHeader
&FileHdr
);
484 struct MappingTraits
<ELFYAML::Symbol
> {
485 static void mapping(IO
&IO
, ELFYAML::Symbol
&Symbol
);
486 static StringRef
validate(IO
&IO
, ELFYAML::Symbol
&Symbol
);
489 template <> struct MappingTraits
<ELFYAML::StackSizeEntry
> {
490 static void mapping(IO
&IO
, ELFYAML::StackSizeEntry
&Rel
);
493 template <> struct MappingTraits
<ELFYAML::DynamicEntry
> {
494 static void mapping(IO
&IO
, ELFYAML::DynamicEntry
&Rel
);
497 template <> struct MappingTraits
<ELFYAML::VerdefEntry
> {
498 static void mapping(IO
&IO
, ELFYAML::VerdefEntry
&E
);
501 template <> struct MappingTraits
<ELFYAML::VerneedEntry
> {
502 static void mapping(IO
&IO
, ELFYAML::VerneedEntry
&E
);
505 template <> struct MappingTraits
<ELFYAML::VernauxEntry
> {
506 static void mapping(IO
&IO
, ELFYAML::VernauxEntry
&E
);
509 template <> struct MappingTraits
<ELFYAML::Relocation
> {
510 static void mapping(IO
&IO
, ELFYAML::Relocation
&Rel
);
514 struct MappingTraits
<std::unique_ptr
<ELFYAML::Section
>> {
515 static void mapping(IO
&IO
, std::unique_ptr
<ELFYAML::Section
> &Section
);
516 static StringRef
validate(IO
&io
, std::unique_ptr
<ELFYAML::Section
> &Section
);
520 struct MappingTraits
<ELFYAML::Object
> {
521 static void mapping(IO
&IO
, ELFYAML::Object
&Object
);
524 template <> struct MappingTraits
<ELFYAML::SectionOrType
> {
525 static void mapping(IO
&IO
, ELFYAML::SectionOrType
§ionOrType
);
528 template <> struct MappingTraits
<ELFYAML::SectionName
> {
529 static void mapping(IO
&IO
, ELFYAML::SectionName
§ionName
);
532 } // end namespace yaml
533 } // end namespace llvm
535 #endif // LLVM_OBJECTYAML_ELFYAML_H