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 std::optional<XCOFF::DwarfSectionSubtypeFlags> SectionSubtype; 83 yaml::BinaryRef SectionData; 84 std::vector<Relocation> Relocations; 85 }; 86 87 enum AuxSymbolType : uint8_t { 88 AUX_EXCEPT = 255, 89 AUX_FCN = 254, 90 AUX_SYM = 253, 91 AUX_FILE = 252, 92 AUX_CSECT = 251, 93 AUX_SECT = 250, 94 AUX_STAT = 249 95 }; 96 97 struct AuxSymbolEnt { 98 AuxSymbolType Type; 99 100 explicit AuxSymbolEnt(AuxSymbolType T) : Type(T) {} 101 virtual ~AuxSymbolEnt(); 102 }; 103 104 struct FileAuxEnt : AuxSymbolEnt { 105 std::optional<StringRef> FileNameOrString; 106 std::optional<XCOFF::CFileStringType> FileStringType; 107 108 FileAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FILE) {} 109 static bool classof(const AuxSymbolEnt *S) { 110 return S->Type == AuxSymbolType::AUX_FILE; 111 } 112 }; 113 114 struct CsectAuxEnt : AuxSymbolEnt { 115 // Only for XCOFF32. 116 std::optional<uint32_t> SectionOrLength; 117 std::optional<uint32_t> StabInfoIndex; 118 std::optional<uint16_t> StabSectNum; 119 // Only for XCOFF64. 120 std::optional<uint32_t> SectionOrLengthLo; 121 std::optional<uint32_t> SectionOrLengthHi; 122 // Common fields for both XCOFF32 and XCOFF64. 123 std::optional<uint32_t> ParameterHashIndex; 124 std::optional<uint16_t> TypeChkSectNum; 125 std::optional<XCOFF::SymbolType> SymbolType; 126 std::optional<uint8_t> SymbolAlignment; 127 // The two previous values can be encoded as a single value. 128 std::optional<uint8_t> SymbolAlignmentAndType; 129 std::optional<XCOFF::StorageMappingClass> StorageMappingClass; 130 131 CsectAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_CSECT) {} 132 static bool classof(const AuxSymbolEnt *S) { 133 return S->Type == AuxSymbolType::AUX_CSECT; 134 } 135 }; 136 137 struct FunctionAuxEnt : AuxSymbolEnt { 138 std::optional<uint32_t> OffsetToExceptionTbl; // Only for XCOFF32. 139 std::optional<uint64_t> PtrToLineNum; 140 std::optional<uint32_t> SizeOfFunction; 141 std::optional<int32_t> SymIdxOfNextBeyond; 142 143 FunctionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FCN) {} 144 static bool classof(const AuxSymbolEnt *S) { 145 return S->Type == AuxSymbolType::AUX_FCN; 146 } 147 }; 148 149 struct ExcpetionAuxEnt : AuxSymbolEnt { 150 std::optional<uint64_t> OffsetToExceptionTbl; 151 std::optional<uint32_t> SizeOfFunction; 152 std::optional<int32_t> SymIdxOfNextBeyond; 153 154 ExcpetionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_EXCEPT) {} 155 static bool classof(const AuxSymbolEnt *S) { 156 return S->Type == AuxSymbolType::AUX_EXCEPT; 157 } 158 }; // Only for XCOFF64. 159 160 struct BlockAuxEnt : AuxSymbolEnt { 161 // Only for XCOFF32. 162 std::optional<uint16_t> LineNumHi; 163 std::optional<uint16_t> LineNumLo; 164 // Only for XCOFF64. 165 std::optional<uint32_t> LineNum; 166 167 BlockAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_SYM) {} 168 static bool classof(const AuxSymbolEnt *S) { 169 return S->Type == AuxSymbolType::AUX_SYM; 170 } 171 }; 172 173 struct SectAuxEntForDWARF : AuxSymbolEnt { 174 std::optional<uint32_t> LengthOfSectionPortion; 175 std::optional<uint32_t> NumberOfRelocEnt; 176 177 SectAuxEntForDWARF() : AuxSymbolEnt(AuxSymbolType::AUX_SECT) {} 178 static bool classof(const AuxSymbolEnt *S) { 179 return S->Type == AuxSymbolType::AUX_SECT; 180 } 181 }; 182 183 struct SectAuxEntForStat : AuxSymbolEnt { 184 std::optional<uint32_t> SectionLength; 185 std::optional<uint16_t> NumberOfRelocEnt; 186 std::optional<uint16_t> NumberOfLineNum; 187 188 SectAuxEntForStat() : AuxSymbolEnt(AuxSymbolType::AUX_STAT) {} 189 static bool classof(const AuxSymbolEnt *S) { 190 return S->Type == AuxSymbolType::AUX_STAT; 191 } 192 }; // Only for XCOFF32. 193 194 struct Symbol { 195 StringRef SymbolName; 196 llvm::yaml::Hex64 Value; // Symbol value; storage class-dependent. 197 std::optional<StringRef> SectionName; 198 std::optional<uint16_t> SectionIndex; 199 llvm::yaml::Hex16 Type; 200 XCOFF::StorageClass StorageClass; 201 std::optional<uint8_t> NumberOfAuxEntries; 202 std::vector<std::unique_ptr<AuxSymbolEnt>> AuxEntries; 203 }; 204 205 struct StringTable { 206 std::optional<uint32_t> ContentSize; // The total size of the string table. 207 std::optional<uint32_t> Length; // The value of the length field for the first 208 // 4 bytes of the table. 209 std::optional<std::vector<StringRef>> Strings; 210 std::optional<yaml::BinaryRef> RawContent; 211 }; 212 213 struct Object { 214 FileHeader Header; 215 std::optional<AuxiliaryHeader> AuxHeader; 216 std::vector<Section> Sections; 217 std::vector<Symbol> Symbols; 218 StringTable StrTbl; 219 Object(); 220 }; 221 } // namespace XCOFFYAML 222 } // namespace llvm 223 224 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol) 225 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Relocation) 226 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Section) 227 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::XCOFFYAML::AuxSymbolEnt>) 228 229 namespace llvm { 230 namespace yaml { 231 232 template <> struct ScalarBitSetTraits<XCOFF::SectionTypeFlags> { 233 static void bitset(IO &IO, XCOFF::SectionTypeFlags &Value); 234 }; 235 236 template <> struct ScalarEnumerationTraits<XCOFF::DwarfSectionSubtypeFlags> { 237 static void enumeration(IO &IO, XCOFF::DwarfSectionSubtypeFlags &Value); 238 }; 239 240 template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> { 241 static void enumeration(IO &IO, XCOFF::StorageClass &Value); 242 }; 243 244 template <> struct ScalarEnumerationTraits<XCOFF::StorageMappingClass> { 245 static void enumeration(IO &IO, XCOFF::StorageMappingClass &Value); 246 }; 247 248 template <> struct ScalarEnumerationTraits<XCOFF::SymbolType> { 249 static void enumeration(IO &IO, XCOFF::SymbolType &Value); 250 }; 251 252 template <> struct ScalarEnumerationTraits<XCOFF::CFileStringType> { 253 static void enumeration(IO &IO, XCOFF::CFileStringType &Type); 254 }; 255 256 template <> struct ScalarEnumerationTraits<XCOFFYAML::AuxSymbolType> { 257 static void enumeration(IO &IO, XCOFFYAML::AuxSymbolType &Type); 258 }; 259 260 template <> struct MappingTraits<XCOFFYAML::FileHeader> { 261 static void mapping(IO &IO, XCOFFYAML::FileHeader &H); 262 }; 263 264 template <> struct MappingTraits<XCOFFYAML::AuxiliaryHeader> { 265 static void mapping(IO &IO, XCOFFYAML::AuxiliaryHeader &AuxHdr); 266 }; 267 268 template <> struct MappingTraits<std::unique_ptr<XCOFFYAML::AuxSymbolEnt>> { 269 static void mapping(IO &IO, std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym); 270 }; 271 272 template <> struct MappingTraits<XCOFFYAML::Symbol> { 273 static void mapping(IO &IO, XCOFFYAML::Symbol &S); 274 }; 275 276 template <> struct MappingTraits<XCOFFYAML::Relocation> { 277 static void mapping(IO &IO, XCOFFYAML::Relocation &R); 278 }; 279 280 template <> struct MappingTraits<XCOFFYAML::Section> { 281 static void mapping(IO &IO, XCOFFYAML::Section &Sec); 282 }; 283 284 template <> struct MappingTraits<XCOFFYAML::StringTable> { 285 static void mapping(IO &IO, XCOFFYAML::StringTable &Str); 286 }; 287 288 template <> struct MappingTraits<XCOFFYAML::Object> { 289 static void mapping(IO &IO, XCOFFYAML::Object &Obj); 290 }; 291 292 } // namespace yaml 293 } // namespace llvm 294 295 #endif // LLVM_OBJECTYAML_XCOFFYAML_H 296