1 //===----- XCOFFYAML.h - XCOFF 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 XCOFF. 10 // 11 //===----------------------------------------------------------------------===// 12 #ifndef LLVM_OBJECTYAML_XCOFFYAML_H 13 #define LLVM_OBJECTYAML_XCOFFYAML_H 14 15 #include "llvm/BinaryFormat/XCOFF.h" 16 #include "llvm/ObjectYAML/YAML.h" 17 #include <optional> 18 #include <vector> 19 20 namespace llvm { 21 namespace XCOFFYAML { 22 23 struct FileHeader { 24 llvm::yaml::Hex16 Magic; 25 uint16_t NumberOfSections; 26 int32_t TimeStamp; 27 llvm::yaml::Hex64 SymbolTableOffset; 28 int32_t NumberOfSymTableEntries; 29 uint16_t AuxHeaderSize; 30 llvm::yaml::Hex16 Flags; 31 }; 32 33 struct AuxiliaryHeader { 34 std::optional<llvm::yaml::Hex16> Magic; 35 std::optional<llvm::yaml::Hex16> Version; 36 std::optional<llvm::yaml::Hex64> TextStartAddr; 37 std::optional<llvm::yaml::Hex64> DataStartAddr; 38 std::optional<llvm::yaml::Hex64> TOCAnchorAddr; 39 std::optional<uint16_t> SecNumOfEntryPoint; 40 std::optional<uint16_t> SecNumOfText; 41 std::optional<uint16_t> SecNumOfData; 42 std::optional<uint16_t> SecNumOfTOC; 43 std::optional<uint16_t> SecNumOfLoader; 44 std::optional<uint16_t> SecNumOfBSS; 45 std::optional<llvm::yaml::Hex16> MaxAlignOfText; 46 std::optional<llvm::yaml::Hex16> MaxAlignOfData; 47 std::optional<llvm::yaml::Hex16> ModuleType; 48 std::optional<llvm::yaml::Hex8> CpuFlag; 49 std::optional<llvm::yaml::Hex8> CpuType; 50 std::optional<llvm::yaml::Hex8> TextPageSize; 51 std::optional<llvm::yaml::Hex8> DataPageSize; 52 std::optional<llvm::yaml::Hex8> StackPageSize; 53 std::optional<llvm::yaml::Hex8> FlagAndTDataAlignment; 54 std::optional<llvm::yaml::Hex64> TextSize; 55 std::optional<llvm::yaml::Hex64> InitDataSize; 56 std::optional<llvm::yaml::Hex64> BssDataSize; 57 std::optional<llvm::yaml::Hex64> EntryPointAddr; 58 std::optional<llvm::yaml::Hex64> MaxStackSize; 59 std::optional<llvm::yaml::Hex64> MaxDataSize; 60 std::optional<uint16_t> SecNumOfTData; 61 std::optional<uint16_t> SecNumOfTBSS; 62 std::optional<llvm::yaml::Hex16> Flag; 63 }; 64 65 struct Relocation { 66 llvm::yaml::Hex64 VirtualAddress; 67 llvm::yaml::Hex64 SymbolIndex; 68 llvm::yaml::Hex8 Info; 69 llvm::yaml::Hex8 Type; 70 }; 71 72 struct Section { 73 StringRef SectionName; 74 llvm::yaml::Hex64 Address; 75 llvm::yaml::Hex64 Size; 76 llvm::yaml::Hex64 FileOffsetToData; 77 llvm::yaml::Hex64 FileOffsetToRelocations; 78 llvm::yaml::Hex64 FileOffsetToLineNumbers; // Line number pointer. Not supported yet. 79 llvm::yaml::Hex16 NumberOfRelocations; 80 llvm::yaml::Hex16 NumberOfLineNumbers; // Line number counts. Not supported yet. 81 uint32_t Flags; 82 yaml::BinaryRef SectionData; 83 std::vector<Relocation> Relocations; 84 }; 85 86 enum AuxSymbolType : uint8_t { 87 AUX_EXCEPT = 255, 88 AUX_FCN = 254, 89 AUX_SYM = 253, 90 AUX_FILE = 252, 91 AUX_CSECT = 251, 92 AUX_SECT = 250, 93 AUX_STAT = 249 94 }; 95 96 struct AuxSymbolEnt { 97 AuxSymbolType Type; 98 99 explicit AuxSymbolEnt(AuxSymbolType T) : Type(T) {} 100 virtual ~AuxSymbolEnt(); 101 }; 102 103 struct FileAuxEnt : AuxSymbolEnt { 104 std::optional<StringRef> FileNameOrString; 105 std::optional<XCOFF::CFileStringType> FileStringType; 106 107 FileAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FILE) {} 108 static bool classof(const AuxSymbolEnt *S) { 109 return S->Type == AuxSymbolType::AUX_FILE; 110 } 111 }; 112 113 struct CsectAuxEnt : AuxSymbolEnt { 114 // Only for XCOFF32. 115 std::optional<uint32_t> SectionOrLength; 116 std::optional<uint32_t> StabInfoIndex; 117 std::optional<uint16_t> StabSectNum; 118 // Only for XCOFF64. 119 std::optional<uint32_t> SectionOrLengthLo; 120 std::optional<uint32_t> SectionOrLengthHi; 121 // Common fields for both XCOFF32 and XCOFF64. 122 std::optional<uint32_t> ParameterHashIndex; 123 std::optional<uint16_t> TypeChkSectNum; 124 std::optional<uint8_t> SymbolAlignmentAndType; 125 std::optional<XCOFF::StorageMappingClass> StorageMappingClass; 126 127 CsectAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_CSECT) {} 128 static bool classof(const AuxSymbolEnt *S) { 129 return S->Type == AuxSymbolType::AUX_CSECT; 130 } 131 }; 132 133 struct FunctionAuxEnt : AuxSymbolEnt { 134 std::optional<uint32_t> OffsetToExceptionTbl; // Only for XCOFF32. 135 std::optional<uint64_t> PtrToLineNum; 136 std::optional<uint32_t> SizeOfFunction; 137 std::optional<int32_t> SymIdxOfNextBeyond; 138 139 FunctionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FCN) {} 140 static bool classof(const AuxSymbolEnt *S) { 141 return S->Type == AuxSymbolType::AUX_FCN; 142 } 143 }; 144 145 struct ExcpetionAuxEnt : AuxSymbolEnt { 146 std::optional<uint64_t> OffsetToExceptionTbl; 147 std::optional<uint32_t> SizeOfFunction; 148 std::optional<int32_t> SymIdxOfNextBeyond; 149 150 ExcpetionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_EXCEPT) {} 151 static bool classof(const AuxSymbolEnt *S) { 152 return S->Type == AuxSymbolType::AUX_EXCEPT; 153 } 154 }; // Only for XCOFF64. 155 156 struct BlockAuxEnt : AuxSymbolEnt { 157 // Only for XCOFF32. 158 std::optional<uint16_t> LineNumHi; 159 std::optional<uint16_t> LineNumLo; 160 // Only for XCOFF64. 161 std::optional<uint32_t> LineNum; 162 163 BlockAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_SYM) {} 164 static bool classof(const AuxSymbolEnt *S) { 165 return S->Type == AuxSymbolType::AUX_SYM; 166 } 167 }; 168 169 struct SectAuxEntForDWARF : AuxSymbolEnt { 170 std::optional<uint32_t> LengthOfSectionPortion; 171 std::optional<uint32_t> NumberOfRelocEnt; 172 173 SectAuxEntForDWARF() : AuxSymbolEnt(AuxSymbolType::AUX_SECT) {} 174 static bool classof(const AuxSymbolEnt *S) { 175 return S->Type == AuxSymbolType::AUX_SECT; 176 } 177 }; 178 179 struct SectAuxEntForStat : AuxSymbolEnt { 180 std::optional<uint32_t> SectionLength; 181 std::optional<uint16_t> NumberOfRelocEnt; 182 std::optional<uint16_t> NumberOfLineNum; 183 184 SectAuxEntForStat() : AuxSymbolEnt(AuxSymbolType::AUX_STAT) {} 185 static bool classof(const AuxSymbolEnt *S) { 186 return S->Type == AuxSymbolType::AUX_STAT; 187 } 188 }; // Only for XCOFF32. 189 190 struct Symbol { 191 StringRef SymbolName; 192 llvm::yaml::Hex64 Value; // Symbol value; storage class-dependent. 193 std::optional<StringRef> SectionName; 194 std::optional<uint16_t> SectionIndex; 195 llvm::yaml::Hex16 Type; 196 XCOFF::StorageClass StorageClass; 197 std::optional<uint8_t> NumberOfAuxEntries; 198 std::vector<std::unique_ptr<AuxSymbolEnt>> AuxEntries; 199 }; 200 201 struct StringTable { 202 std::optional<uint32_t> ContentSize; // The total size of the string table. 203 std::optional<uint32_t> Length; // The value of the length field for the first 204 // 4 bytes of the table. 205 std::optional<std::vector<StringRef>> Strings; 206 std::optional<yaml::BinaryRef> RawContent; 207 }; 208 209 struct Object { 210 FileHeader Header; 211 std::optional<AuxiliaryHeader> AuxHeader; 212 std::vector<Section> Sections; 213 std::vector<Symbol> Symbols; 214 StringTable StrTbl; 215 Object(); 216 }; 217 } // namespace XCOFFYAML 218 } // namespace llvm 219 220 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol) 221 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Relocation) 222 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Section) 223 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::XCOFFYAML::AuxSymbolEnt>) 224 225 namespace llvm { 226 namespace yaml { 227 228 template <> struct ScalarBitSetTraits<XCOFF::SectionTypeFlags> { 229 static void bitset(IO &IO, XCOFF::SectionTypeFlags &Value); 230 }; 231 232 template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> { 233 static void enumeration(IO &IO, XCOFF::StorageClass &Value); 234 }; 235 236 template <> struct ScalarEnumerationTraits<XCOFF::StorageMappingClass> { 237 static void enumeration(IO &IO, XCOFF::StorageMappingClass &Value); 238 }; 239 240 template <> struct ScalarEnumerationTraits<XCOFF::CFileStringType> { 241 static void enumeration(IO &IO, XCOFF::CFileStringType &Type); 242 }; 243 244 template <> struct ScalarEnumerationTraits<XCOFFYAML::AuxSymbolType> { 245 static void enumeration(IO &IO, XCOFFYAML::AuxSymbolType &Type); 246 }; 247 248 template <> struct MappingTraits<XCOFFYAML::FileHeader> { 249 static void mapping(IO &IO, XCOFFYAML::FileHeader &H); 250 }; 251 252 template <> struct MappingTraits<XCOFFYAML::AuxiliaryHeader> { 253 static void mapping(IO &IO, XCOFFYAML::AuxiliaryHeader &AuxHdr); 254 }; 255 256 template <> struct MappingTraits<std::unique_ptr<XCOFFYAML::AuxSymbolEnt>> { 257 static void mapping(IO &IO, std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym); 258 }; 259 260 template <> struct MappingTraits<XCOFFYAML::Symbol> { 261 static void mapping(IO &IO, XCOFFYAML::Symbol &S); 262 }; 263 264 template <> struct MappingTraits<XCOFFYAML::Relocation> { 265 static void mapping(IO &IO, XCOFFYAML::Relocation &R); 266 }; 267 268 template <> struct MappingTraits<XCOFFYAML::Section> { 269 static void mapping(IO &IO, XCOFFYAML::Section &Sec); 270 }; 271 272 template <> struct MappingTraits<XCOFFYAML::StringTable> { 273 static void mapping(IO &IO, XCOFFYAML::StringTable &Str); 274 }; 275 276 template <> struct MappingTraits<XCOFFYAML::Object> { 277 static void mapping(IO &IO, XCOFFYAML::Object &Obj); 278 }; 279 280 } // namespace yaml 281 } // namespace llvm 282 283 #endif // LLVM_OBJECTYAML_XCOFFYAML_H 284