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
;
121 enum class SectionKind
{
136 Optional
<ELF_SHF
> Flags
;
137 llvm::yaml::Hex64 Address
;
139 llvm::yaml::Hex64 AddressAlign
;
140 Optional
<llvm::yaml::Hex64
> EntSize
;
142 // Usually sections are not created implicitly, but loaded from YAML.
143 // When they are, this flag is used to signal about that.
146 Section(SectionKind Kind
, bool IsImplicit
= false)
147 : Kind(Kind
), IsImplicit(IsImplicit
) {}
150 // The following members are used to override section fields which is
151 // useful for creating invalid objects.
153 // This can be used to override the offset stored in the sh_name field.
154 // It does not affect the name stored in the string table.
155 Optional
<llvm::yaml::Hex64
> ShName
;
157 // This can be used to override the sh_offset field. It does not place the
158 // section data at the offset specified.
159 Optional
<llvm::yaml::Hex64
> ShOffset
;
161 // This can be used to override the sh_size field. It does not affect the
163 Optional
<llvm::yaml::Hex64
> ShSize
;
166 struct DynamicSection
: Section
{
167 std::vector
<DynamicEntry
> Entries
;
168 Optional
<yaml::BinaryRef
> Content
;
170 DynamicSection() : Section(SectionKind::Dynamic
) {}
172 static bool classof(const Section
*S
) {
173 return S
->Kind
== SectionKind::Dynamic
;
177 struct RawContentSection
: Section
{
178 Optional
<yaml::BinaryRef
> Content
;
179 Optional
<llvm::yaml::Hex64
> Size
;
180 Optional
<llvm::yaml::Hex64
> Info
;
182 RawContentSection() : Section(SectionKind::RawContent
) {}
184 static bool classof(const Section
*S
) {
185 return S
->Kind
== SectionKind::RawContent
;
189 struct NoBitsSection
: Section
{
190 llvm::yaml::Hex64 Size
;
192 NoBitsSection() : Section(SectionKind::NoBits
) {}
194 static bool classof(const Section
*S
) {
195 return S
->Kind
== SectionKind::NoBits
;
199 struct VernauxEntry
{
206 struct VerneedEntry
{
209 std::vector
<VernauxEntry
> AuxV
;
212 struct VerneedSection
: Section
{
213 std::vector
<VerneedEntry
> VerneedV
;
214 llvm::yaml::Hex64 Info
;
216 VerneedSection() : Section(SectionKind::Verneed
) {}
218 static bool classof(const Section
*S
) {
219 return S
->Kind
== SectionKind::Verneed
;
223 struct SymverSection
: Section
{
224 std::vector
<uint16_t> Entries
;
226 SymverSection() : Section(SectionKind::Symver
) {}
228 static bool classof(const Section
*S
) {
229 return S
->Kind
== SectionKind::Symver
;
238 std::vector
<StringRef
> VerNames
;
241 struct VerdefSection
: Section
{
242 std::vector
<VerdefEntry
> Entries
;
243 llvm::yaml::Hex64 Info
;
245 VerdefSection() : Section(SectionKind::Verdef
) {}
247 static bool classof(const Section
*S
) {
248 return S
->Kind
== SectionKind::Verdef
;
252 struct Group
: Section
{
253 // Members of a group contain a flag and a list of section indices
254 // that are part of the group.
255 std::vector
<SectionOrType
> Members
;
256 StringRef Signature
; /* Info */
258 Group() : Section(SectionKind::Group
) {}
260 static bool classof(const Section
*S
) {
261 return S
->Kind
== SectionKind::Group
;
266 llvm::yaml::Hex64 Offset
;
269 Optional
<StringRef
> Symbol
;
272 struct RelocationSection
: Section
{
273 std::vector
<Relocation
> Relocations
;
274 StringRef RelocatableSec
; /* Info */
276 RelocationSection() : Section(SectionKind::Relocation
) {}
278 static bool classof(const Section
*S
) {
279 return S
->Kind
== SectionKind::Relocation
;
283 struct SymtabShndxSection
: Section
{
284 std::vector
<uint32_t> Entries
;
286 SymtabShndxSection() : Section(SectionKind::SymtabShndxSection
) {}
288 static bool classof(const Section
*S
) {
289 return S
->Kind
== SectionKind::SymtabShndxSection
;
293 // Represents .MIPS.abiflags section
294 struct MipsABIFlags
: Section
{
295 llvm::yaml::Hex16 Version
;
297 llvm::yaml::Hex8 ISARevision
;
298 MIPS_AFL_REG GPRSize
;
299 MIPS_AFL_REG CPR1Size
;
300 MIPS_AFL_REG CPR2Size
;
302 MIPS_AFL_EXT ISAExtension
;
304 MIPS_AFL_FLAGS1 Flags1
;
305 llvm::yaml::Hex32 Flags2
;
307 MipsABIFlags() : Section(SectionKind::MipsABIFlags
) {}
309 static bool classof(const Section
*S
) {
310 return S
->Kind
== SectionKind::MipsABIFlags
;
316 std::vector
<ProgramHeader
> ProgramHeaders
;
317 std::vector
<std::unique_ptr
<Section
>> Sections
;
318 // Although in reality the symbols reside in a section, it is a lot
319 // cleaner and nicer if we read them from the YAML as a separate
320 // top-level key, which automatically ensures that invariants like there
321 // being a single SHT_SYMTAB section are upheld.
322 std::vector
<Symbol
> Symbols
;
323 std::vector
<Symbol
> DynamicSymbols
;
326 } // end namespace ELFYAML
327 } // end namespace llvm
329 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry
)
330 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader
)
331 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr
<llvm::ELFYAML::Section
>)
332 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol
)
333 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry
)
334 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry
)
335 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry
)
336 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation
)
337 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType
)
338 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName
)
344 struct ScalarEnumerationTraits
<ELFYAML::ELF_ET
> {
345 static void enumeration(IO
&IO
, ELFYAML::ELF_ET
&Value
);
348 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_PT
> {
349 static void enumeration(IO
&IO
, ELFYAML::ELF_PT
&Value
);
353 struct ScalarEnumerationTraits
<ELFYAML::ELF_EM
> {
354 static void enumeration(IO
&IO
, ELFYAML::ELF_EM
&Value
);
358 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFCLASS
> {
359 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFCLASS
&Value
);
363 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFDATA
> {
364 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFDATA
&Value
);
368 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFOSABI
> {
369 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFOSABI
&Value
);
373 struct ScalarBitSetTraits
<ELFYAML::ELF_EF
> {
374 static void bitset(IO
&IO
, ELFYAML::ELF_EF
&Value
);
377 template <> struct ScalarBitSetTraits
<ELFYAML::ELF_PF
> {
378 static void bitset(IO
&IO
, ELFYAML::ELF_PF
&Value
);
382 struct ScalarEnumerationTraits
<ELFYAML::ELF_SHT
> {
383 static void enumeration(IO
&IO
, ELFYAML::ELF_SHT
&Value
);
387 struct ScalarBitSetTraits
<ELFYAML::ELF_SHF
> {
388 static void bitset(IO
&IO
, ELFYAML::ELF_SHF
&Value
);
391 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_SHN
> {
392 static void enumeration(IO
&IO
, ELFYAML::ELF_SHN
&Value
);
395 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_STB
> {
396 static void enumeration(IO
&IO
, ELFYAML::ELF_STB
&Value
);
400 struct ScalarEnumerationTraits
<ELFYAML::ELF_STT
> {
401 static void enumeration(IO
&IO
, ELFYAML::ELF_STT
&Value
);
405 struct ScalarEnumerationTraits
<ELFYAML::ELF_REL
> {
406 static void enumeration(IO
&IO
, ELFYAML::ELF_REL
&Value
);
410 struct ScalarEnumerationTraits
<ELFYAML::ELF_DYNTAG
> {
411 static void enumeration(IO
&IO
, ELFYAML::ELF_DYNTAG
&Value
);
415 struct ScalarEnumerationTraits
<ELFYAML::ELF_RSS
> {
416 static void enumeration(IO
&IO
, ELFYAML::ELF_RSS
&Value
);
420 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_REG
> {
421 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_REG
&Value
);
425 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ABI_FP
> {
426 static void enumeration(IO
&IO
, ELFYAML::MIPS_ABI_FP
&Value
);
430 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_EXT
> {
431 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_EXT
&Value
);
435 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ISA
> {
436 static void enumeration(IO
&IO
, ELFYAML::MIPS_ISA
&Value
);
440 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_ASE
> {
441 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_ASE
&Value
);
445 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_FLAGS1
> {
446 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_FLAGS1
&Value
);
450 struct MappingTraits
<ELFYAML::FileHeader
> {
451 static void mapping(IO
&IO
, ELFYAML::FileHeader
&FileHdr
);
454 template <> struct MappingTraits
<ELFYAML::ProgramHeader
> {
455 static void mapping(IO
&IO
, ELFYAML::ProgramHeader
&FileHdr
);
459 struct MappingTraits
<ELFYAML::Symbol
> {
460 static void mapping(IO
&IO
, ELFYAML::Symbol
&Symbol
);
461 static StringRef
validate(IO
&IO
, ELFYAML::Symbol
&Symbol
);
464 template <> struct MappingTraits
<ELFYAML::DynamicEntry
> {
465 static void mapping(IO
&IO
, ELFYAML::DynamicEntry
&Rel
);
468 template <> struct MappingTraits
<ELFYAML::VerdefEntry
> {
469 static void mapping(IO
&IO
, ELFYAML::VerdefEntry
&E
);
472 template <> struct MappingTraits
<ELFYAML::VerneedEntry
> {
473 static void mapping(IO
&IO
, ELFYAML::VerneedEntry
&E
);
476 template <> struct MappingTraits
<ELFYAML::VernauxEntry
> {
477 static void mapping(IO
&IO
, ELFYAML::VernauxEntry
&E
);
480 template <> struct MappingTraits
<ELFYAML::Relocation
> {
481 static void mapping(IO
&IO
, ELFYAML::Relocation
&Rel
);
485 struct MappingTraits
<std::unique_ptr
<ELFYAML::Section
>> {
486 static void mapping(IO
&IO
, std::unique_ptr
<ELFYAML::Section
> &Section
);
487 static StringRef
validate(IO
&io
, std::unique_ptr
<ELFYAML::Section
> &Section
);
491 struct MappingTraits
<ELFYAML::Object
> {
492 static void mapping(IO
&IO
, ELFYAML::Object
&Object
);
495 template <> struct MappingTraits
<ELFYAML::SectionOrType
> {
496 static void mapping(IO
&IO
, ELFYAML::SectionOrType
§ionOrType
);
499 template <> struct MappingTraits
<ELFYAML::SectionName
> {
500 static void mapping(IO
&IO
, ELFYAML::SectionName
§ionName
);
503 } // end namespace yaml
504 } // end namespace llvm
506 #endif // LLVM_OBJECTYAML_ELFYAML_H