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 Header; 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 Header; 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 PEHeader { 111 COFF::PE32Header Header; 112 std::optional<COFF::DataDirectory> 113 DataDirectories[COFF::NUM_DATA_DIRECTORIES]; 114 }; 115 116 struct Object { 117 std::optional<PEHeader> OptionalHeader; 118 COFF::header 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 mapping(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 mapping(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