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