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 26namespace llvm { 27 28namespace COFF { 29 30inline 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 35inline 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 41inline 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. 51namespace COFFYAML { 52 53LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType) 54LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics) 55LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType) 56 57struct 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 69struct 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 83struct 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 98struct PEHeader { 99 COFF::PE32Header Header; 100 Optional<COFF::DataDirectory> DataDirectories[COFF::NUM_DATA_DIRECTORIES]; 101}; 102 103struct 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 116LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section) 117LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol) 118LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation) 119 120namespace llvm { 121namespace yaml { 122 123template <> 124struct ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics> { 125 static void enumeration(IO &IO, COFFYAML::WeakExternalCharacteristics &Value); 126}; 127 128template <> 129struct ScalarEnumerationTraits<COFFYAML::AuxSymbolType> { 130 static void enumeration(IO &IO, COFFYAML::AuxSymbolType &Value); 131}; 132 133template <> 134struct ScalarEnumerationTraits<COFFYAML::COMDATType> { 135 static void enumeration(IO &IO, COFFYAML::COMDATType &Value); 136}; 137 138template <> 139struct ScalarEnumerationTraits<COFF::MachineTypes> { 140 static void enumeration(IO &IO, COFF::MachineTypes &Value); 141}; 142 143template <> 144struct ScalarEnumerationTraits<COFF::SymbolBaseType> { 145 static void enumeration(IO &IO, COFF::SymbolBaseType &Value); 146}; 147 148template <> 149struct ScalarEnumerationTraits<COFF::SymbolStorageClass> { 150 static void enumeration(IO &IO, COFF::SymbolStorageClass &Value); 151}; 152 153template <> 154struct ScalarEnumerationTraits<COFF::SymbolComplexType> { 155 static void enumeration(IO &IO, COFF::SymbolComplexType &Value); 156}; 157 158template <> 159struct ScalarEnumerationTraits<COFF::RelocationTypeI386> { 160 static void enumeration(IO &IO, COFF::RelocationTypeI386 &Value); 161}; 162 163template <> 164struct ScalarEnumerationTraits<COFF::RelocationTypeAMD64> { 165 static void enumeration(IO &IO, COFF::RelocationTypeAMD64 &Value); 166}; 167 168template <> 169struct ScalarEnumerationTraits<COFF::RelocationTypesARM> { 170 static void enumeration(IO &IO, COFF::RelocationTypesARM &Value); 171}; 172 173template <> 174struct ScalarEnumerationTraits<COFF::RelocationTypesARM64> { 175 static void enumeration(IO &IO, COFF::RelocationTypesARM64 &Value); 176}; 177 178template <> 179struct ScalarEnumerationTraits<COFF::WindowsSubsystem> { 180 static void enumeration(IO &IO, COFF::WindowsSubsystem &Value); 181}; 182 183template <> 184struct ScalarBitSetTraits<COFF::Characteristics> { 185 static void bitset(IO &IO, COFF::Characteristics &Value); 186}; 187 188template <> 189struct ScalarBitSetTraits<COFF::SectionCharacteristics> { 190 static void bitset(IO &IO, COFF::SectionCharacteristics &Value); 191}; 192 193template <> 194struct ScalarBitSetTraits<COFF::DLLCharacteristics> { 195 static void bitset(IO &IO, COFF::DLLCharacteristics &Value); 196}; 197 198template <> 199struct MappingTraits<COFFYAML::Relocation> { 200 static void mapping(IO &IO, COFFYAML::Relocation &Rel); 201}; 202 203template <> 204struct MappingTraits<COFFYAML::PEHeader> { 205 static void mapping(IO &IO, COFFYAML::PEHeader &PH); 206}; 207 208template <> 209struct MappingTraits<COFF::DataDirectory> { 210 static void mapping(IO &IO, COFF::DataDirectory &DD); 211}; 212 213template <> 214struct MappingTraits<COFF::header> { 215 static void mapping(IO &IO, COFF::header &H); 216}; 217 218template <> struct MappingTraits<COFF::AuxiliaryFunctionDefinition> { 219 static void mapping(IO &IO, COFF::AuxiliaryFunctionDefinition &AFD); 220}; 221 222template <> struct MappingTraits<COFF::AuxiliarybfAndefSymbol> { 223 static void mapping(IO &IO, COFF::AuxiliarybfAndefSymbol &AAS); 224}; 225 226template <> struct MappingTraits<COFF::AuxiliaryWeakExternal> { 227 static void mapping(IO &IO, COFF::AuxiliaryWeakExternal &AWE); 228}; 229 230template <> struct MappingTraits<COFF::AuxiliarySectionDefinition> { 231 static void mapping(IO &IO, COFF::AuxiliarySectionDefinition &ASD); 232}; 233 234template <> struct MappingTraits<COFF::AuxiliaryCLRToken> { 235 static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT); 236}; 237 238template <> 239struct MappingTraits<COFFYAML::Symbol> { 240 static void mapping(IO &IO, COFFYAML::Symbol &S); 241}; 242 243template <> 244struct MappingTraits<COFFYAML::Section> { 245 static void mapping(IO &IO, COFFYAML::Section &Sec); 246}; 247 248template <> 249struct 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