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