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
)
57 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV
)
58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO
)
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
> SHOffset
;
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
;
113 struct SectionOrType
{
114 StringRef sectionNameOrType
;
117 struct DynamicEntry
{
119 llvm::yaml::Hex64 Val
;
123 enum class SectionKind
{
138 Optional
<ELF_SHF
> Flags
;
139 llvm::yaml::Hex64 Address
;
141 llvm::yaml::Hex64 AddressAlign
;
142 Optional
<llvm::yaml::Hex64
> EntSize
;
144 // This can be used to override the sh_offset field. It does not place the
145 // section data at the offset specified. Useful for creating invalid objects.
146 Optional
<llvm::yaml::Hex64
> ShOffset
;
148 // This can be used to override the sh_size field. It does not affect the
150 Optional
<llvm::yaml::Hex64
> ShSize
;
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
) {}
161 struct DynamicSection
: Section
{
162 std::vector
<DynamicEntry
> Entries
;
163 Optional
<yaml::BinaryRef
> Content
;
165 DynamicSection() : Section(SectionKind::Dynamic
) {}
167 static bool classof(const Section
*S
) {
168 return S
->Kind
== SectionKind::Dynamic
;
172 struct RawContentSection
: Section
{
173 Optional
<yaml::BinaryRef
> Content
;
174 Optional
<llvm::yaml::Hex64
> Size
;
175 Optional
<llvm::yaml::Hex64
> Info
;
177 RawContentSection() : Section(SectionKind::RawContent
) {}
179 static bool classof(const Section
*S
) {
180 return S
->Kind
== SectionKind::RawContent
;
184 struct NoBitsSection
: Section
{
185 llvm::yaml::Hex64 Size
;
187 NoBitsSection() : Section(SectionKind::NoBits
) {}
189 static bool classof(const Section
*S
) {
190 return S
->Kind
== SectionKind::NoBits
;
194 struct VernauxEntry
{
201 struct VerneedEntry
{
204 std::vector
<VernauxEntry
> AuxV
;
207 struct VerneedSection
: Section
{
208 std::vector
<VerneedEntry
> VerneedV
;
209 llvm::yaml::Hex64 Info
;
211 VerneedSection() : Section(SectionKind::Verneed
) {}
213 static bool classof(const Section
*S
) {
214 return S
->Kind
== SectionKind::Verneed
;
218 struct SymverSection
: Section
{
219 std::vector
<uint16_t> Entries
;
221 SymverSection() : Section(SectionKind::Symver
) {}
223 static bool classof(const Section
*S
) {
224 return S
->Kind
== SectionKind::Symver
;
233 std::vector
<StringRef
> VerNames
;
236 struct VerdefSection
: Section
{
237 std::vector
<VerdefEntry
> Entries
;
238 llvm::yaml::Hex64 Info
;
240 VerdefSection() : Section(SectionKind::Verdef
) {}
242 static bool classof(const Section
*S
) {
243 return S
->Kind
== SectionKind::Verdef
;
247 struct Group
: Section
{
248 // Members of a group contain a flag and a list of section indices
249 // that are part of the group.
250 std::vector
<SectionOrType
> Members
;
251 StringRef Signature
; /* Info */
253 Group() : Section(SectionKind::Group
) {}
255 static bool classof(const Section
*S
) {
256 return S
->Kind
== SectionKind::Group
;
261 llvm::yaml::Hex64 Offset
;
264 Optional
<StringRef
> Symbol
;
267 struct RelocationSection
: Section
{
268 std::vector
<Relocation
> Relocations
;
269 StringRef RelocatableSec
; /* Info */
271 RelocationSection() : Section(SectionKind::Relocation
) {}
273 static bool classof(const Section
*S
) {
274 return S
->Kind
== SectionKind::Relocation
;
278 struct SymtabShndxSection
: Section
{
279 std::vector
<uint32_t> Entries
;
281 SymtabShndxSection() : Section(SectionKind::SymtabShndxSection
) {}
283 static bool classof(const Section
*S
) {
284 return S
->Kind
== SectionKind::SymtabShndxSection
;
288 // Represents .MIPS.abiflags section
289 struct MipsABIFlags
: Section
{
290 llvm::yaml::Hex16 Version
;
292 llvm::yaml::Hex8 ISARevision
;
293 MIPS_AFL_REG GPRSize
;
294 MIPS_AFL_REG CPR1Size
;
295 MIPS_AFL_REG CPR2Size
;
297 MIPS_AFL_EXT ISAExtension
;
299 MIPS_AFL_FLAGS1 Flags1
;
300 llvm::yaml::Hex32 Flags2
;
302 MipsABIFlags() : Section(SectionKind::MipsABIFlags
) {}
304 static bool classof(const Section
*S
) {
305 return S
->Kind
== SectionKind::MipsABIFlags
;
311 std::vector
<ProgramHeader
> ProgramHeaders
;
312 std::vector
<std::unique_ptr
<Section
>> Sections
;
313 // Although in reality the symbols reside in a section, it is a lot
314 // cleaner and nicer if we read them from the YAML as a separate
315 // top-level key, which automatically ensures that invariants like there
316 // being a single SHT_SYMTAB section are upheld.
317 std::vector
<Symbol
> Symbols
;
318 std::vector
<Symbol
> DynamicSymbols
;
321 } // end namespace ELFYAML
322 } // end namespace llvm
324 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry
)
325 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader
)
326 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr
<llvm::ELFYAML::Section
>)
327 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol
)
328 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry
)
329 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry
)
330 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry
)
331 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation
)
332 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType
)
333 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName
)
339 struct ScalarEnumerationTraits
<ELFYAML::ELF_ET
> {
340 static void enumeration(IO
&IO
, ELFYAML::ELF_ET
&Value
);
343 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_PT
> {
344 static void enumeration(IO
&IO
, ELFYAML::ELF_PT
&Value
);
348 struct ScalarEnumerationTraits
<ELFYAML::ELF_EM
> {
349 static void enumeration(IO
&IO
, ELFYAML::ELF_EM
&Value
);
353 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFCLASS
> {
354 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFCLASS
&Value
);
358 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFDATA
> {
359 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFDATA
&Value
);
363 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFOSABI
> {
364 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFOSABI
&Value
);
368 struct ScalarBitSetTraits
<ELFYAML::ELF_EF
> {
369 static void bitset(IO
&IO
, ELFYAML::ELF_EF
&Value
);
372 template <> struct ScalarBitSetTraits
<ELFYAML::ELF_PF
> {
373 static void bitset(IO
&IO
, ELFYAML::ELF_PF
&Value
);
377 struct ScalarEnumerationTraits
<ELFYAML::ELF_SHT
> {
378 static void enumeration(IO
&IO
, ELFYAML::ELF_SHT
&Value
);
382 struct ScalarBitSetTraits
<ELFYAML::ELF_SHF
> {
383 static void bitset(IO
&IO
, ELFYAML::ELF_SHF
&Value
);
386 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_SHN
> {
387 static void enumeration(IO
&IO
, ELFYAML::ELF_SHN
&Value
);
390 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_STB
> {
391 static void enumeration(IO
&IO
, ELFYAML::ELF_STB
&Value
);
395 struct ScalarEnumerationTraits
<ELFYAML::ELF_STT
> {
396 static void enumeration(IO
&IO
, ELFYAML::ELF_STT
&Value
);
400 struct ScalarEnumerationTraits
<ELFYAML::ELF_STV
> {
401 static void enumeration(IO
&IO
, ELFYAML::ELF_STV
&Value
);
405 struct ScalarBitSetTraits
<ELFYAML::ELF_STO
> {
406 static void bitset(IO
&IO
, ELFYAML::ELF_STO
&Value
);
410 struct ScalarEnumerationTraits
<ELFYAML::ELF_REL
> {
411 static void enumeration(IO
&IO
, ELFYAML::ELF_REL
&Value
);
415 struct ScalarEnumerationTraits
<ELFYAML::ELF_DYNTAG
> {
416 static void enumeration(IO
&IO
, ELFYAML::ELF_DYNTAG
&Value
);
420 struct ScalarEnumerationTraits
<ELFYAML::ELF_RSS
> {
421 static void enumeration(IO
&IO
, ELFYAML::ELF_RSS
&Value
);
425 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_REG
> {
426 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_REG
&Value
);
430 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ABI_FP
> {
431 static void enumeration(IO
&IO
, ELFYAML::MIPS_ABI_FP
&Value
);
435 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_EXT
> {
436 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_EXT
&Value
);
440 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ISA
> {
441 static void enumeration(IO
&IO
, ELFYAML::MIPS_ISA
&Value
);
445 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_ASE
> {
446 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_ASE
&Value
);
450 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_FLAGS1
> {
451 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_FLAGS1
&Value
);
455 struct MappingTraits
<ELFYAML::FileHeader
> {
456 static void mapping(IO
&IO
, ELFYAML::FileHeader
&FileHdr
);
459 template <> struct MappingTraits
<ELFYAML::ProgramHeader
> {
460 static void mapping(IO
&IO
, ELFYAML::ProgramHeader
&FileHdr
);
464 struct MappingTraits
<ELFYAML::Symbol
> {
465 static void mapping(IO
&IO
, ELFYAML::Symbol
&Symbol
);
466 static StringRef
validate(IO
&IO
, ELFYAML::Symbol
&Symbol
);
469 template <> struct MappingTraits
<ELFYAML::DynamicEntry
> {
470 static void mapping(IO
&IO
, ELFYAML::DynamicEntry
&Rel
);
473 template <> struct MappingTraits
<ELFYAML::VerdefEntry
> {
474 static void mapping(IO
&IO
, ELFYAML::VerdefEntry
&E
);
477 template <> struct MappingTraits
<ELFYAML::VerneedEntry
> {
478 static void mapping(IO
&IO
, ELFYAML::VerneedEntry
&E
);
481 template <> struct MappingTraits
<ELFYAML::VernauxEntry
> {
482 static void mapping(IO
&IO
, ELFYAML::VernauxEntry
&E
);
485 template <> struct MappingTraits
<ELFYAML::Relocation
> {
486 static void mapping(IO
&IO
, ELFYAML::Relocation
&Rel
);
490 struct MappingTraits
<std::unique_ptr
<ELFYAML::Section
>> {
491 static void mapping(IO
&IO
, std::unique_ptr
<ELFYAML::Section
> &Section
);
492 static StringRef
validate(IO
&io
, std::unique_ptr
<ELFYAML::Section
> &Section
);
496 struct MappingTraits
<ELFYAML::Object
> {
497 static void mapping(IO
&IO
, ELFYAML::Object
&Object
);
500 template <> struct MappingTraits
<ELFYAML::SectionOrType
> {
501 static void mapping(IO
&IO
, ELFYAML::SectionOrType
§ionOrType
);
504 template <> struct MappingTraits
<ELFYAML::SectionName
> {
505 static void mapping(IO
&IO
, ELFYAML::SectionName
§ionName
);
508 } // end namespace yaml
509 } // end namespace llvm
511 #endif // LLVM_OBJECTYAML_ELFYAML_H