406 lines · cpp
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-exception6//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 17namespace llvm {18namespace XCOFFYAML {19 20Object::Object() { memset(&Header, 0, sizeof(Header)); }21 22AuxSymbolEnt::~AuxSymbolEnt() = default;23 24} // namespace XCOFFYAML25 26namespace yaml {27 28void 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 ECase45}46 47void 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 ECase62 IO.enumFallback<Hex32>(Value);63}64 65void 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 ECase119}120 121void 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 ECase146}147 148void 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 ECase156 IO.enumFallback<Hex8>(Value);157}158 159void 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 ECase170}171 172void 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 ECase180}181 182struct 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 191void 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 202void 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 233void 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 241void 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 258static 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 275static void auxSymMapping(IO &IO, XCOFFYAML::FileAuxEnt &AuxSym) {276 IO.mapOptional("FileNameOrString", AuxSym.FileNameOrString);277 IO.mapOptional("FileStringType", AuxSym.FileStringType);278}279 280static 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 289static 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 298static 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 304static void auxSymMapping(IO &IO, XCOFFYAML::SectAuxEntForDWARF &AuxSym) {305 IO.mapOptional("LengthOfSectionPortion", AuxSym.LengthOfSectionPortion);306 IO.mapOptional("NumberOfRelocEnt", AuxSym.NumberOfRelocEnt);307}308 309static 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 315template <typename AuxEntT>316static void ResetAuxSym(IO &IO,317 std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) {318 if (!IO.outputting())319 AuxSym.reset(new AuxEntT);320}321 322void 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 374void 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 385void 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 393void 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 yaml405} // namespace llvm406