1 | //===- COFFYAML.h - COFF YAMLIO implementation ------------------*- C++ -*-===// |
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file declares classes for handling the YAML representation of COFF. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_OBJECTYAML_COFFYAML_H |
14 | #define LLVM_OBJECTYAML_COFFYAML_H |
15 | |
16 | #include "llvm/ADT/StringRef.h" |
17 | #include "llvm/BinaryFormat/COFF.h" |
18 | #include "llvm/Object/COFF.h" |
19 | #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" |
20 | #include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h" |
21 | #include "llvm/ObjectYAML/CodeViewYAMLTypes.h" |
22 | #include "llvm/ObjectYAML/YAML.h" |
23 | #include <cstdint> |
24 | #include <optional> |
25 | #include <vector> |
26 | |
27 | namespace llvm { |
28 | |
29 | namespace COFF { |
30 | |
31 | inline Characteristics operator|(Characteristics a, Characteristics b) { |
32 | uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b); |
33 | return static_cast<Characteristics>(Ret); |
34 | } |
35 | |
36 | inline SectionCharacteristics operator|(SectionCharacteristics a, |
37 | SectionCharacteristics b) { |
38 | uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b); |
39 | return static_cast<SectionCharacteristics>(Ret); |
40 | } |
41 | |
42 | inline DLLCharacteristics operator|(DLLCharacteristics a, |
43 | DLLCharacteristics b) { |
44 | uint16_t Ret = static_cast<uint16_t>(a) | static_cast<uint16_t>(b); |
45 | return static_cast<DLLCharacteristics>(Ret); |
46 | } |
47 | |
48 | } // end namespace COFF |
49 | |
50 | // The structure of the yaml files is not an exact 1:1 match to COFF. In order |
51 | // to use yaml::IO, we use these structures which are closer to the source. |
52 | namespace COFFYAML { |
53 | |
54 | LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType) |
55 | LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics) |
56 | LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType) |
57 | |
58 | struct Relocation { |
59 | uint32_t VirtualAddress; |
60 | uint16_t Type; |
61 | |
62 | // Normally a Relocation can refer to the symbol via its name. |
63 | // It can also use a direct symbol table index instead (with no name |
64 | // specified), allowing disambiguating between multiple symbols with the |
65 | // same name or crafting intentionally broken files for testing. |
66 | StringRef SymbolName; |
67 | std::optional<uint32_t> SymbolTableIndex; |
68 | }; |
69 | |
70 | struct SectionDataEntry { |
71 | std::optional<uint32_t> UInt32; |
72 | yaml::BinaryRef Binary; |
73 | std::optional<object::coff_load_configuration32> LoadConfig32; |
74 | std::optional<object::coff_load_configuration64> LoadConfig64; |
75 | |
76 | size_t size() const; |
77 | void writeAsBinary(raw_ostream &OS) const; |
78 | }; |
79 | |
80 | struct Section { |
81 | COFF::section ; |
82 | unsigned Alignment = 0; |
83 | yaml::BinaryRef SectionData; |
84 | std::vector<CodeViewYAML::YAMLDebugSubsection> DebugS; |
85 | std::vector<CodeViewYAML::LeafRecord> DebugT; |
86 | std::vector<CodeViewYAML::LeafRecord> DebugP; |
87 | std::optional<CodeViewYAML::DebugHSection> DebugH; |
88 | std::vector<SectionDataEntry> StructuredData; |
89 | std::vector<Relocation> Relocations; |
90 | StringRef Name; |
91 | |
92 | Section(); |
93 | }; |
94 | |
95 | struct Symbol { |
96 | COFF::symbol ; |
97 | COFF::SymbolBaseType SimpleType = COFF::IMAGE_SYM_TYPE_NULL; |
98 | COFF::SymbolComplexType ComplexType = COFF::IMAGE_SYM_DTYPE_NULL; |
99 | std::optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition; |
100 | std::optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol; |
101 | std::optional<COFF::AuxiliaryWeakExternal> WeakExternal; |
102 | StringRef File; |
103 | std::optional<COFF::AuxiliarySectionDefinition> SectionDefinition; |
104 | std::optional<COFF::AuxiliaryCLRToken> CLRToken; |
105 | StringRef Name; |
106 | |
107 | Symbol(); |
108 | }; |
109 | |
110 | struct { |
111 | COFF::PE32Header ; |
112 | std::optional<COFF::DataDirectory> |
113 | [COFF::NUM_DATA_DIRECTORIES]; |
114 | }; |
115 | |
116 | struct Object { |
117 | std::optional<PEHeader> ; |
118 | COFF::header ; |
119 | std::vector<Section> Sections; |
120 | std::vector<Symbol> Symbols; |
121 | |
122 | Object(); |
123 | }; |
124 | |
125 | } // end namespace COFFYAML |
126 | |
127 | } // end namespace llvm |
128 | |
129 | LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section) |
130 | LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol) |
131 | LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation) |
132 | LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::SectionDataEntry) |
133 | |
134 | namespace llvm { |
135 | namespace yaml { |
136 | |
137 | template <> |
138 | struct ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics> { |
139 | static void enumeration(IO &IO, COFFYAML::WeakExternalCharacteristics &Value); |
140 | }; |
141 | |
142 | template <> |
143 | struct ScalarEnumerationTraits<COFFYAML::AuxSymbolType> { |
144 | static void enumeration(IO &IO, COFFYAML::AuxSymbolType &Value); |
145 | }; |
146 | |
147 | template <> |
148 | struct ScalarEnumerationTraits<COFFYAML::COMDATType> { |
149 | static void enumeration(IO &IO, COFFYAML::COMDATType &Value); |
150 | }; |
151 | |
152 | template <> |
153 | struct ScalarEnumerationTraits<COFF::MachineTypes> { |
154 | static void enumeration(IO &IO, COFF::MachineTypes &Value); |
155 | }; |
156 | |
157 | template <> |
158 | struct ScalarEnumerationTraits<COFF::SymbolBaseType> { |
159 | static void enumeration(IO &IO, COFF::SymbolBaseType &Value); |
160 | }; |
161 | |
162 | template <> |
163 | struct ScalarEnumerationTraits<COFF::SymbolStorageClass> { |
164 | static void enumeration(IO &IO, COFF::SymbolStorageClass &Value); |
165 | }; |
166 | |
167 | template <> |
168 | struct ScalarEnumerationTraits<COFF::SymbolComplexType> { |
169 | static void enumeration(IO &IO, COFF::SymbolComplexType &Value); |
170 | }; |
171 | |
172 | template <> |
173 | struct ScalarEnumerationTraits<COFF::RelocationTypeI386> { |
174 | static void enumeration(IO &IO, COFF::RelocationTypeI386 &Value); |
175 | }; |
176 | |
177 | template <> |
178 | struct ScalarEnumerationTraits<COFF::RelocationTypeAMD64> { |
179 | static void enumeration(IO &IO, COFF::RelocationTypeAMD64 &Value); |
180 | }; |
181 | |
182 | template <> |
183 | struct ScalarEnumerationTraits<COFF::RelocationTypesARM> { |
184 | static void enumeration(IO &IO, COFF::RelocationTypesARM &Value); |
185 | }; |
186 | |
187 | template <> |
188 | struct ScalarEnumerationTraits<COFF::RelocationTypesARM64> { |
189 | static void enumeration(IO &IO, COFF::RelocationTypesARM64 &Value); |
190 | }; |
191 | |
192 | template <> |
193 | struct ScalarEnumerationTraits<COFF::WindowsSubsystem> { |
194 | static void enumeration(IO &IO, COFF::WindowsSubsystem &Value); |
195 | }; |
196 | |
197 | template <> |
198 | struct ScalarBitSetTraits<COFF::Characteristics> { |
199 | static void bitset(IO &IO, COFF::Characteristics &Value); |
200 | }; |
201 | |
202 | template <> |
203 | struct ScalarBitSetTraits<COFF::SectionCharacteristics> { |
204 | static void bitset(IO &IO, COFF::SectionCharacteristics &Value); |
205 | }; |
206 | |
207 | template <> |
208 | struct ScalarBitSetTraits<COFF::DLLCharacteristics> { |
209 | static void bitset(IO &IO, COFF::DLLCharacteristics &Value); |
210 | }; |
211 | |
212 | template <> |
213 | struct MappingTraits<COFFYAML::Relocation> { |
214 | static void mapping(IO &IO, COFFYAML::Relocation &Rel); |
215 | }; |
216 | |
217 | template <> |
218 | struct MappingTraits<COFFYAML::PEHeader> { |
219 | static void (IO &IO, COFFYAML::PEHeader &PH); |
220 | }; |
221 | |
222 | template <> |
223 | struct MappingTraits<COFF::DataDirectory> { |
224 | static void mapping(IO &IO, COFF::DataDirectory &DD); |
225 | }; |
226 | |
227 | template <> |
228 | struct MappingTraits<COFF::header> { |
229 | static void (IO &IO, COFF::header &H); |
230 | }; |
231 | |
232 | template <> struct MappingTraits<COFF::AuxiliaryFunctionDefinition> { |
233 | static void mapping(IO &IO, COFF::AuxiliaryFunctionDefinition &AFD); |
234 | }; |
235 | |
236 | template <> struct MappingTraits<COFF::AuxiliarybfAndefSymbol> { |
237 | static void mapping(IO &IO, COFF::AuxiliarybfAndefSymbol &AAS); |
238 | }; |
239 | |
240 | template <> struct MappingTraits<COFF::AuxiliaryWeakExternal> { |
241 | static void mapping(IO &IO, COFF::AuxiliaryWeakExternal &AWE); |
242 | }; |
243 | |
244 | template <> struct MappingTraits<COFF::AuxiliarySectionDefinition> { |
245 | static void mapping(IO &IO, COFF::AuxiliarySectionDefinition &ASD); |
246 | }; |
247 | |
248 | template <> struct MappingTraits<COFF::AuxiliaryCLRToken> { |
249 | static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT); |
250 | }; |
251 | |
252 | template <> struct MappingTraits<object::coff_load_configuration32> { |
253 | static void mapping(IO &IO, object::coff_load_configuration32 &ACT); |
254 | }; |
255 | |
256 | template <> struct MappingTraits<object::coff_load_configuration64> { |
257 | static void mapping(IO &IO, object::coff_load_configuration64 &ACT); |
258 | }; |
259 | |
260 | template <> struct MappingTraits<object::coff_load_config_code_integrity> { |
261 | static void mapping(IO &IO, object::coff_load_config_code_integrity &ACT); |
262 | }; |
263 | |
264 | template <> |
265 | struct MappingTraits<COFFYAML::Symbol> { |
266 | static void mapping(IO &IO, COFFYAML::Symbol &S); |
267 | }; |
268 | |
269 | template <> struct MappingTraits<COFFYAML::SectionDataEntry> { |
270 | static void mapping(IO &IO, COFFYAML::SectionDataEntry &Sec); |
271 | }; |
272 | |
273 | template <> |
274 | struct MappingTraits<COFFYAML::Section> { |
275 | static void mapping(IO &IO, COFFYAML::Section &Sec); |
276 | }; |
277 | |
278 | template <> |
279 | struct MappingTraits<COFFYAML::Object> { |
280 | static void mapping(IO &IO, COFFYAML::Object &Obj); |
281 | }; |
282 | |
283 | } // end namespace yaml |
284 | } // end namespace llvm |
285 | |
286 | #endif // LLVM_OBJECTYAML_COFFYAML_H |
287 | |