1 //===-- XCOFFYAML.cpp - 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 defines classes for handling the YAML representation of XCOFF. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ObjectYAML/XCOFFYAML.h" 14 #include "llvm/BinaryFormat/XCOFF.h" 15 #include <string.h> 16 17 namespace llvm { 18 namespace XCOFFYAML { 19 20 Object::Object() { memset(&Header, 0, sizeof(Header)); } 21 22 AuxSymbolEnt::~AuxSymbolEnt() = default; 23 24 } // namespace XCOFFYAML 25 26 namespace yaml { 27 28 void ScalarBitSetTraits<XCOFF::SectionTypeFlags>::bitset( 29 IO &IO, XCOFF::SectionTypeFlags &Value) { 30 #define ECase(X) IO.bitSetCase(Value, #X, XCOFF::X) 31 ECase(STYP_PAD); 32 ECase(STYP_DWARF); 33 ECase(STYP_TEXT); 34 ECase(STYP_DATA); 35 ECase(STYP_BSS); 36 ECase(STYP_EXCEPT); 37 ECase(STYP_INFO); 38 ECase(STYP_TDATA); 39 ECase(STYP_TBSS); 40 ECase(STYP_LOADER); 41 ECase(STYP_DEBUG); 42 ECase(STYP_TYPCHK); 43 ECase(STYP_OVRFLO); 44 #undef ECase 45 } 46 47 void ScalarEnumerationTraits<XCOFF::DwarfSectionSubtypeFlags>::enumeration( 48 IO &IO, XCOFF::DwarfSectionSubtypeFlags &Value) { 49 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X) 50 ECase(SSUBTYP_DWINFO); 51 ECase(SSUBTYP_DWLINE); 52 ECase(SSUBTYP_DWPBNMS); 53 ECase(SSUBTYP_DWPBTYP); 54 ECase(SSUBTYP_DWARNGE); 55 ECase(SSUBTYP_DWABREV); 56 ECase(SSUBTYP_DWSTR); 57 ECase(SSUBTYP_DWRNGES); 58 ECase(SSUBTYP_DWLOC); 59 ECase(SSUBTYP_DWFRAME); 60 ECase(SSUBTYP_DWMAC); 61 #undef ECase 62 IO.enumFallback<Hex32>(Value); 63 } 64 65 void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration( 66 IO &IO, XCOFF::StorageClass &Value) { 67 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X) 68 ECase(C_NULL); 69 ECase(C_AUTO); 70 ECase(C_EXT); 71 ECase(C_STAT); 72 ECase(C_REG); 73 ECase(C_EXTDEF); 74 ECase(C_LABEL); 75 ECase(C_ULABEL); 76 ECase(C_MOS); 77 ECase(C_ARG); 78 ECase(C_STRTAG); 79 ECase(C_MOU); 80 ECase(C_UNTAG); 81 ECase(C_TPDEF); 82 ECase(C_USTATIC); 83 ECase(C_ENTAG); 84 ECase(C_MOE); 85 ECase(C_REGPARM); 86 ECase(C_FIELD); 87 ECase(C_BLOCK); 88 ECase(C_FCN); 89 ECase(C_EOS); 90 ECase(C_FILE); 91 ECase(C_LINE); 92 ECase(C_ALIAS); 93 ECase(C_HIDDEN); 94 ECase(C_HIDEXT); 95 ECase(C_BINCL); 96 ECase(C_EINCL); 97 ECase(C_INFO); 98 ECase(C_WEAKEXT); 99 ECase(C_DWARF); 100 ECase(C_GSYM); 101 ECase(C_LSYM); 102 ECase(C_PSYM); 103 ECase(C_RSYM); 104 ECase(C_RPSYM); 105 ECase(C_STSYM); 106 ECase(C_TCSYM); 107 ECase(C_BCOMM); 108 ECase(C_ECOML); 109 ECase(C_ECOMM); 110 ECase(C_DECL); 111 ECase(C_ENTRY); 112 ECase(C_FUN); 113 ECase(C_BSTAT); 114 ECase(C_ESTAT); 115 ECase(C_GTLS); 116 ECase(C_STTLS); 117 ECase(C_EFCN); 118 #undef ECase 119 } 120 121 void ScalarEnumerationTraits<XCOFF::StorageMappingClass>::enumeration( 122 IO &IO, XCOFF::StorageMappingClass &Value) { 123 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X) 124 ECase(XMC_PR); 125 ECase(XMC_RO); 126 ECase(XMC_DB); 127 ECase(XMC_GL); 128 ECase(XMC_XO); 129 ECase(XMC_SV); 130 ECase(XMC_SV64); 131 ECase(XMC_SV3264); 132 ECase(XMC_TI); 133 ECase(XMC_TB); 134 ECase(XMC_RW); 135 ECase(XMC_TC0); 136 ECase(XMC_TC); 137 ECase(XMC_TD); 138 ECase(XMC_DS); 139 ECase(XMC_UA); 140 ECase(XMC_BS); 141 ECase(XMC_UC); 142 ECase(XMC_TL); 143 ECase(XMC_UL); 144 ECase(XMC_TE); 145 #undef ECase 146 } 147 148 void ScalarEnumerationTraits<XCOFF::SymbolType>::enumeration( 149 IO &IO, XCOFF::SymbolType &Value) { 150 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X) 151 ECase(XTY_ER); 152 ECase(XTY_SD); 153 ECase(XTY_LD); 154 ECase(XTY_CM); 155 #undef ECase 156 IO.enumFallback<Hex8>(Value); 157 } 158 159 void ScalarEnumerationTraits<XCOFFYAML::AuxSymbolType>::enumeration( 160 IO &IO, XCOFFYAML::AuxSymbolType &Type) { 161 #define ECase(X) IO.enumCase(Type, #X, XCOFFYAML::X) 162 ECase(AUX_EXCEPT); 163 ECase(AUX_FCN); 164 ECase(AUX_SYM); 165 ECase(AUX_FILE); 166 ECase(AUX_CSECT); 167 ECase(AUX_SECT); 168 ECase(AUX_STAT); 169 #undef ECase 170 } 171 172 void ScalarEnumerationTraits<XCOFF::CFileStringType>::enumeration( 173 IO &IO, XCOFF::CFileStringType &Type) { 174 #define ECase(X) IO.enumCase(Type, #X, XCOFF::X) 175 ECase(XFT_FN); 176 ECase(XFT_CT); 177 ECase(XFT_CV); 178 ECase(XFT_CD); 179 #undef ECase 180 } 181 182 struct NSectionFlags { 183 NSectionFlags(IO &) : Flags(XCOFF::SectionTypeFlags(0)) {} 184 NSectionFlags(IO &, uint32_t C) : Flags(XCOFF::SectionTypeFlags(C)) {} 185 186 uint32_t denormalize(IO &) { return Flags; } 187 188 XCOFF::SectionTypeFlags Flags; 189 }; 190 191 void MappingTraits<XCOFFYAML::FileHeader>::mapping( 192 IO &IO, XCOFFYAML::FileHeader &FileHdr) { 193 IO.mapOptional("MagicNumber", FileHdr.Magic); 194 IO.mapOptional("NumberOfSections", FileHdr.NumberOfSections); 195 IO.mapOptional("CreationTime", FileHdr.TimeStamp); 196 IO.mapOptional("OffsetToSymbolTable", FileHdr.SymbolTableOffset); 197 IO.mapOptional("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries); 198 IO.mapOptional("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize); 199 IO.mapOptional("Flags", FileHdr.Flags); 200 } 201 202 void MappingTraits<XCOFFYAML::AuxiliaryHeader>::mapping( 203 IO &IO, XCOFFYAML::AuxiliaryHeader &AuxHdr) { 204 IO.mapOptional("Magic", AuxHdr.Magic); 205 IO.mapOptional("Version", AuxHdr.Version); 206 IO.mapOptional("TextStartAddr", AuxHdr.TextStartAddr); 207 IO.mapOptional("DataStartAddr", AuxHdr.DataStartAddr); 208 IO.mapOptional("TOCAnchorAddr", AuxHdr.TOCAnchorAddr); 209 IO.mapOptional("TextSectionSize", AuxHdr.TextSize); 210 IO.mapOptional("DataSectionSize", AuxHdr.InitDataSize); 211 IO.mapOptional("BssSectionSize", AuxHdr.BssDataSize); 212 IO.mapOptional("SecNumOfEntryPoint", AuxHdr.SecNumOfEntryPoint); 213 IO.mapOptional("SecNumOfText", AuxHdr.SecNumOfText); 214 IO.mapOptional("SecNumOfData", AuxHdr.SecNumOfData); 215 IO.mapOptional("SecNumOfTOC", AuxHdr.SecNumOfTOC); 216 IO.mapOptional("SecNumOfLoader", AuxHdr.SecNumOfLoader); 217 IO.mapOptional("SecNumOfBSS", AuxHdr.SecNumOfBSS); 218 IO.mapOptional("MaxAlignOfText", AuxHdr.MaxAlignOfText); 219 IO.mapOptional("MaxAlignOfData", AuxHdr.MaxAlignOfData); 220 IO.mapOptional("ModuleType", AuxHdr.CpuFlag); 221 IO.mapOptional("TextPageSize", AuxHdr.TextPageSize); 222 IO.mapOptional("DataPageSize", AuxHdr.DataPageSize); 223 IO.mapOptional("StackPageSize", AuxHdr.StackPageSize); 224 IO.mapOptional("FlagAndTDataAlignment", AuxHdr.FlagAndTDataAlignment); 225 IO.mapOptional("EntryPointAddr", AuxHdr.EntryPointAddr); 226 IO.mapOptional("MaxStackSize", AuxHdr.MaxStackSize); 227 IO.mapOptional("MaxDataSize", AuxHdr.MaxDataSize); 228 IO.mapOptional("SecNumOfTData", AuxHdr.SecNumOfTData); 229 IO.mapOptional("SecNumOfTBSS", AuxHdr.SecNumOfTBSS); 230 IO.mapOptional("Flag", AuxHdr.Flag); 231 } 232 233 void MappingTraits<XCOFFYAML::Relocation>::mapping(IO &IO, 234 XCOFFYAML::Relocation &R) { 235 IO.mapOptional("Address", R.VirtualAddress); 236 IO.mapOptional("Symbol", R.SymbolIndex); 237 IO.mapOptional("Info", R.Info); 238 IO.mapOptional("Type", R.Type); 239 } 240 241 void MappingTraits<XCOFFYAML::Section>::mapping(IO &IO, 242 XCOFFYAML::Section &Sec) { 243 MappingNormalization<NSectionFlags, uint32_t> NC(IO, Sec.Flags); 244 IO.mapOptional("Name", Sec.SectionName); 245 IO.mapOptional("Address", Sec.Address); 246 IO.mapOptional("Size", Sec.Size); 247 IO.mapOptional("FileOffsetToData", Sec.FileOffsetToData); 248 IO.mapOptional("FileOffsetToRelocations", Sec.FileOffsetToRelocations); 249 IO.mapOptional("FileOffsetToLineNumbers", Sec.FileOffsetToLineNumbers); 250 IO.mapOptional("NumberOfRelocations", Sec.NumberOfRelocations); 251 IO.mapOptional("NumberOfLineNumbers", Sec.NumberOfLineNumbers); 252 IO.mapOptional("Flags", NC->Flags); 253 IO.mapOptional("DWARFSectionSubtype", Sec.SectionSubtype); 254 IO.mapOptional("SectionData", Sec.SectionData); 255 IO.mapOptional("Relocations", Sec.Relocations); 256 } 257 258 static void auxSymMapping(IO &IO, XCOFFYAML::CsectAuxEnt &AuxSym, bool Is64) { 259 IO.mapOptional("ParameterHashIndex", AuxSym.ParameterHashIndex); 260 IO.mapOptional("TypeChkSectNum", AuxSym.TypeChkSectNum); 261 IO.mapOptional("SymbolAlignmentAndType", AuxSym.SymbolAlignmentAndType); 262 IO.mapOptional("SymbolType", AuxSym.SymbolType); 263 IO.mapOptional("SymbolAlignment", AuxSym.SymbolAlignment); 264 IO.mapOptional("StorageMappingClass", AuxSym.StorageMappingClass); 265 if (Is64) { 266 IO.mapOptional("SectionOrLengthLo", AuxSym.SectionOrLengthLo); 267 IO.mapOptional("SectionOrLengthHi", AuxSym.SectionOrLengthHi); 268 } else { 269 IO.mapOptional("SectionOrLength", AuxSym.SectionOrLength); 270 IO.mapOptional("StabInfoIndex", AuxSym.StabInfoIndex); 271 IO.mapOptional("StabSectNum", AuxSym.StabSectNum); 272 } 273 } 274 275 static void auxSymMapping(IO &IO, XCOFFYAML::FileAuxEnt &AuxSym) { 276 IO.mapOptional("FileNameOrString", AuxSym.FileNameOrString); 277 IO.mapOptional("FileStringType", AuxSym.FileStringType); 278 } 279 280 static void auxSymMapping(IO &IO, XCOFFYAML::BlockAuxEnt &AuxSym, bool Is64) { 281 if (Is64) { 282 IO.mapOptional("LineNum", AuxSym.LineNum); 283 } else { 284 IO.mapOptional("LineNumHi", AuxSym.LineNumHi); 285 IO.mapOptional("LineNumLo", AuxSym.LineNumLo); 286 } 287 } 288 289 static void auxSymMapping(IO &IO, XCOFFYAML::FunctionAuxEnt &AuxSym, 290 bool Is64) { 291 if (!Is64) 292 IO.mapOptional("OffsetToExceptionTbl", AuxSym.OffsetToExceptionTbl); 293 IO.mapOptional("SizeOfFunction", AuxSym.SizeOfFunction); 294 IO.mapOptional("SymIdxOfNextBeyond", AuxSym.SymIdxOfNextBeyond); 295 IO.mapOptional("PtrToLineNum", AuxSym.PtrToLineNum); 296 } 297 298 static void auxSymMapping(IO &IO, XCOFFYAML::ExcpetionAuxEnt &AuxSym) { 299 IO.mapOptional("OffsetToExceptionTbl", AuxSym.OffsetToExceptionTbl); 300 IO.mapOptional("SizeOfFunction", AuxSym.SizeOfFunction); 301 IO.mapOptional("SymIdxOfNextBeyond", AuxSym.SymIdxOfNextBeyond); 302 } 303 304 static void auxSymMapping(IO &IO, XCOFFYAML::SectAuxEntForDWARF &AuxSym) { 305 IO.mapOptional("LengthOfSectionPortion", AuxSym.LengthOfSectionPortion); 306 IO.mapOptional("NumberOfRelocEnt", AuxSym.NumberOfRelocEnt); 307 } 308 309 static void auxSymMapping(IO &IO, XCOFFYAML::SectAuxEntForStat &AuxSym) { 310 IO.mapOptional("SectionLength", AuxSym.SectionLength); 311 IO.mapOptional("NumberOfRelocEnt", AuxSym.NumberOfRelocEnt); 312 IO.mapOptional("NumberOfLineNum", AuxSym.NumberOfLineNum); 313 } 314 315 template <typename AuxEntT> 316 static void ResetAuxSym(IO &IO, 317 std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) { 318 if (!IO.outputting()) 319 AuxSym.reset(new AuxEntT); 320 } 321 322 void MappingTraits<std::unique_ptr<XCOFFYAML::AuxSymbolEnt>>::mapping( 323 IO &IO, std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) { 324 const bool Is64 = 325 static_cast<XCOFFYAML::Object *>(IO.getContext())->Header.Magic == 326 (llvm::yaml::Hex16)XCOFF::XCOFF64; 327 328 XCOFFYAML::AuxSymbolType AuxType; 329 if (IO.outputting()) 330 AuxType = AuxSym->Type; 331 IO.mapRequired("Type", AuxType); 332 switch (AuxType) { 333 case XCOFFYAML::AUX_EXCEPT: 334 if (!Is64) { 335 IO.setError("an auxiliary symbol of type AUX_EXCEPT cannot be defined in " 336 "XCOFF32"); 337 return; 338 } 339 ResetAuxSym<XCOFFYAML::ExcpetionAuxEnt>(IO, AuxSym); 340 auxSymMapping(IO, *cast<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get())); 341 break; 342 case XCOFFYAML::AUX_FCN: 343 ResetAuxSym<XCOFFYAML::FunctionAuxEnt>(IO, AuxSym); 344 auxSymMapping(IO, *cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get()), Is64); 345 break; 346 case XCOFFYAML::AUX_SYM: 347 ResetAuxSym<XCOFFYAML::BlockAuxEnt>(IO, AuxSym); 348 auxSymMapping(IO, *cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get()), Is64); 349 break; 350 case XCOFFYAML::AUX_FILE: 351 ResetAuxSym<XCOFFYAML::FileAuxEnt>(IO, AuxSym); 352 auxSymMapping(IO, *cast<XCOFFYAML::FileAuxEnt>(AuxSym.get())); 353 break; 354 case XCOFFYAML::AUX_CSECT: 355 ResetAuxSym<XCOFFYAML::CsectAuxEnt>(IO, AuxSym); 356 auxSymMapping(IO, *cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get()), Is64); 357 break; 358 case XCOFFYAML::AUX_SECT: 359 ResetAuxSym<XCOFFYAML::SectAuxEntForDWARF>(IO, AuxSym); 360 auxSymMapping(IO, *cast<XCOFFYAML::SectAuxEntForDWARF>(AuxSym.get())); 361 break; 362 case XCOFFYAML::AUX_STAT: 363 if (Is64) { 364 IO.setError( 365 "an auxiliary symbol of type AUX_STAT cannot be defined in XCOFF64"); 366 return; 367 } 368 ResetAuxSym<XCOFFYAML::SectAuxEntForStat>(IO, AuxSym); 369 auxSymMapping(IO, *cast<XCOFFYAML::SectAuxEntForStat>(AuxSym.get())); 370 break; 371 } 372 } 373 374 void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) { 375 IO.mapOptional("Name", S.SymbolName); 376 IO.mapOptional("Value", S.Value); 377 IO.mapOptional("Section", S.SectionName); 378 IO.mapOptional("SectionIndex", S.SectionIndex); 379 IO.mapOptional("Type", S.Type); 380 IO.mapOptional("StorageClass", S.StorageClass); 381 IO.mapOptional("NumberOfAuxEntries", S.NumberOfAuxEntries); 382 IO.mapOptional("AuxEntries", S.AuxEntries); 383 } 384 385 void MappingTraits<XCOFFYAML::StringTable>::mapping( 386 IO &IO, XCOFFYAML::StringTable &Str) { 387 IO.mapOptional("ContentSize", Str.ContentSize); 388 IO.mapOptional("Length", Str.Length); 389 IO.mapOptional("Strings", Str.Strings); 390 IO.mapOptional("RawContent", Str.RawContent); 391 } 392 393 void MappingTraits<XCOFFYAML::Object>::mapping(IO &IO, XCOFFYAML::Object &Obj) { 394 IO.setContext(&Obj); 395 IO.mapTag("!XCOFF", true); 396 IO.mapRequired("FileHeader", Obj.Header); 397 IO.mapOptional("AuxiliaryHeader", Obj.AuxHeader); 398 IO.mapOptional("Sections", Obj.Sections); 399 IO.mapOptional("Symbols", Obj.Symbols); 400 IO.mapOptional("StringTable", Obj.StrTbl); 401 IO.setContext(nullptr); 402 } 403 404 } // namespace yaml 405 } // namespace llvm 406