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_STT
)
56 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV
)
57 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO
)
59 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG
)
60 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP
)
61 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT
)
62 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE
)
63 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1
)
64 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA
)
66 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
67 // since 64-bit can hold 32-bit values too.
72 llvm::yaml::Hex8 ABIVersion
;
76 llvm::yaml::Hex64 Entry
;
83 struct ProgramHeader
{
86 llvm::yaml::Hex64 VAddr
;
87 llvm::yaml::Hex64 PAddr
;
88 Optional
<llvm::yaml::Hex64
> Align
;
89 std::vector
<SectionName
> Sections
;
96 Optional
<ELF_SHN
> Index
;
97 llvm::yaml::Hex64 Value
;
98 llvm::yaml::Hex64 Size
;
102 struct LocalGlobalWeakSymbols
{
103 std::vector
<Symbol
> Local
;
104 std::vector
<Symbol
> Global
;
105 std::vector
<Symbol
> Weak
;
108 struct SectionOrType
{
109 StringRef sectionNameOrType
;
112 struct DynamicEntry
{
114 llvm::yaml::Hex64 Val
;
118 enum class SectionKind
{
130 llvm::yaml::Hex64 Address
;
132 llvm::yaml::Hex64 AddressAlign
;
133 Optional
<llvm::yaml::Hex64
> EntSize
;
135 Section(SectionKind Kind
) : Kind(Kind
) {}
139 struct DynamicSection
: Section
{
140 std::vector
<DynamicEntry
> Entries
;
142 DynamicSection() : Section(SectionKind::Dynamic
) {}
144 static bool classof(const Section
*S
) {
145 return S
->Kind
== SectionKind::Dynamic
;
149 struct RawContentSection
: Section
{
150 yaml::BinaryRef Content
;
151 llvm::yaml::Hex64 Size
;
153 RawContentSection() : Section(SectionKind::RawContent
) {}
155 static bool classof(const Section
*S
) {
156 return S
->Kind
== SectionKind::RawContent
;
160 struct NoBitsSection
: Section
{
161 llvm::yaml::Hex64 Size
;
163 NoBitsSection() : Section(SectionKind::NoBits
) {}
165 static bool classof(const Section
*S
) {
166 return S
->Kind
== SectionKind::NoBits
;
170 struct Group
: Section
{
171 // Members of a group contain a flag and a list of section indices
172 // that are part of the group.
173 std::vector
<SectionOrType
> Members
;
174 StringRef Signature
; /* Info */
176 Group() : Section(SectionKind::Group
) {}
178 static bool classof(const Section
*S
) {
179 return S
->Kind
== SectionKind::Group
;
184 llvm::yaml::Hex64 Offset
;
187 Optional
<StringRef
> Symbol
;
190 struct RelocationSection
: Section
{
191 std::vector
<Relocation
> Relocations
;
192 StringRef RelocatableSec
; /* Info */
194 RelocationSection() : Section(SectionKind::Relocation
) {}
196 static bool classof(const Section
*S
) {
197 return S
->Kind
== SectionKind::Relocation
;
201 // Represents .MIPS.abiflags section
202 struct MipsABIFlags
: Section
{
203 llvm::yaml::Hex16 Version
;
205 llvm::yaml::Hex8 ISARevision
;
206 MIPS_AFL_REG GPRSize
;
207 MIPS_AFL_REG CPR1Size
;
208 MIPS_AFL_REG CPR2Size
;
210 MIPS_AFL_EXT ISAExtension
;
212 MIPS_AFL_FLAGS1 Flags1
;
213 llvm::yaml::Hex32 Flags2
;
215 MipsABIFlags() : Section(SectionKind::MipsABIFlags
) {}
217 static bool classof(const Section
*S
) {
218 return S
->Kind
== SectionKind::MipsABIFlags
;
224 std::vector
<ProgramHeader
> ProgramHeaders
;
225 std::vector
<std::unique_ptr
<Section
>> Sections
;
226 // Although in reality the symbols reside in a section, it is a lot
227 // cleaner and nicer if we read them from the YAML as a separate
228 // top-level key, which automatically ensures that invariants like there
229 // being a single SHT_SYMTAB section are upheld.
230 LocalGlobalWeakSymbols Symbols
;
231 LocalGlobalWeakSymbols DynamicSymbols
;
234 } // end namespace ELFYAML
235 } // end namespace llvm
237 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry
)
238 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader
)
239 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr
<llvm::ELFYAML::Section
>)
240 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol
)
241 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation
)
242 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType
)
243 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName
)
249 struct ScalarEnumerationTraits
<ELFYAML::ELF_ET
> {
250 static void enumeration(IO
&IO
, ELFYAML::ELF_ET
&Value
);
253 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_PT
> {
254 static void enumeration(IO
&IO
, ELFYAML::ELF_PT
&Value
);
258 struct ScalarEnumerationTraits
<ELFYAML::ELF_EM
> {
259 static void enumeration(IO
&IO
, ELFYAML::ELF_EM
&Value
);
263 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFCLASS
> {
264 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFCLASS
&Value
);
268 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFDATA
> {
269 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFDATA
&Value
);
273 struct ScalarEnumerationTraits
<ELFYAML::ELF_ELFOSABI
> {
274 static void enumeration(IO
&IO
, ELFYAML::ELF_ELFOSABI
&Value
);
278 struct ScalarBitSetTraits
<ELFYAML::ELF_EF
> {
279 static void bitset(IO
&IO
, ELFYAML::ELF_EF
&Value
);
282 template <> struct ScalarBitSetTraits
<ELFYAML::ELF_PF
> {
283 static void bitset(IO
&IO
, ELFYAML::ELF_PF
&Value
);
287 struct ScalarEnumerationTraits
<ELFYAML::ELF_SHT
> {
288 static void enumeration(IO
&IO
, ELFYAML::ELF_SHT
&Value
);
292 struct ScalarBitSetTraits
<ELFYAML::ELF_SHF
> {
293 static void bitset(IO
&IO
, ELFYAML::ELF_SHF
&Value
);
296 template <> struct ScalarEnumerationTraits
<ELFYAML::ELF_SHN
> {
297 static void enumeration(IO
&IO
, ELFYAML::ELF_SHN
&Value
);
301 struct ScalarEnumerationTraits
<ELFYAML::ELF_STT
> {
302 static void enumeration(IO
&IO
, ELFYAML::ELF_STT
&Value
);
306 struct ScalarEnumerationTraits
<ELFYAML::ELF_STV
> {
307 static void enumeration(IO
&IO
, ELFYAML::ELF_STV
&Value
);
311 struct ScalarBitSetTraits
<ELFYAML::ELF_STO
> {
312 static void bitset(IO
&IO
, ELFYAML::ELF_STO
&Value
);
316 struct ScalarEnumerationTraits
<ELFYAML::ELF_REL
> {
317 static void enumeration(IO
&IO
, ELFYAML::ELF_REL
&Value
);
321 struct ScalarEnumerationTraits
<ELFYAML::ELF_DYNTAG
> {
322 static void enumeration(IO
&IO
, ELFYAML::ELF_DYNTAG
&Value
);
326 struct ScalarEnumerationTraits
<ELFYAML::ELF_RSS
> {
327 static void enumeration(IO
&IO
, ELFYAML::ELF_RSS
&Value
);
331 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_REG
> {
332 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_REG
&Value
);
336 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ABI_FP
> {
337 static void enumeration(IO
&IO
, ELFYAML::MIPS_ABI_FP
&Value
);
341 struct ScalarEnumerationTraits
<ELFYAML::MIPS_AFL_EXT
> {
342 static void enumeration(IO
&IO
, ELFYAML::MIPS_AFL_EXT
&Value
);
346 struct ScalarEnumerationTraits
<ELFYAML::MIPS_ISA
> {
347 static void enumeration(IO
&IO
, ELFYAML::MIPS_ISA
&Value
);
351 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_ASE
> {
352 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_ASE
&Value
);
356 struct ScalarBitSetTraits
<ELFYAML::MIPS_AFL_FLAGS1
> {
357 static void bitset(IO
&IO
, ELFYAML::MIPS_AFL_FLAGS1
&Value
);
361 struct MappingTraits
<ELFYAML::FileHeader
> {
362 static void mapping(IO
&IO
, ELFYAML::FileHeader
&FileHdr
);
365 template <> struct MappingTraits
<ELFYAML::ProgramHeader
> {
366 static void mapping(IO
&IO
, ELFYAML::ProgramHeader
&FileHdr
);
370 struct MappingTraits
<ELFYAML::Symbol
> {
371 static void mapping(IO
&IO
, ELFYAML::Symbol
&Symbol
);
372 static StringRef
validate(IO
&IO
, ELFYAML::Symbol
&Symbol
);
376 struct MappingTraits
<ELFYAML::LocalGlobalWeakSymbols
> {
377 static void mapping(IO
&IO
, ELFYAML::LocalGlobalWeakSymbols
&Symbols
);
380 template <> struct MappingTraits
<ELFYAML::DynamicEntry
> {
381 static void mapping(IO
&IO
, ELFYAML::DynamicEntry
&Rel
);
384 template <> struct MappingTraits
<ELFYAML::Relocation
> {
385 static void mapping(IO
&IO
, ELFYAML::Relocation
&Rel
);
389 struct MappingTraits
<std::unique_ptr
<ELFYAML::Section
>> {
390 static void mapping(IO
&IO
, std::unique_ptr
<ELFYAML::Section
> &Section
);
391 static StringRef
validate(IO
&io
, std::unique_ptr
<ELFYAML::Section
> &Section
);
395 struct MappingTraits
<ELFYAML::Object
> {
396 static void mapping(IO
&IO
, ELFYAML::Object
&Object
);
399 template <> struct MappingTraits
<ELFYAML::SectionOrType
> {
400 static void mapping(IO
&IO
, ELFYAML::SectionOrType
§ionOrType
);
403 template <> struct MappingTraits
<ELFYAML::SectionName
> {
404 static void mapping(IO
&IO
, ELFYAML::SectionName
§ionName
);
407 } // end namespace yaml
408 } // end namespace llvm
410 #endif // LLVM_OBJECTYAML_ELFYAML_H