XCOFFYAML.cpp 12 KB

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