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