CodeViewYAMLSymbols.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
  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 CodeView
  10. // Debug Info.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
  14. #include "llvm/ADT/ArrayRef.h"
  15. #include "llvm/ADT/StringRef.h"
  16. #include "llvm/DebugInfo/CodeView/CodeView.h"
  17. #include "llvm/DebugInfo/CodeView/CodeViewError.h"
  18. #include "llvm/DebugInfo/CodeView/EnumTables.h"
  19. #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
  20. #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
  21. #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
  22. #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
  23. #include "llvm/DebugInfo/CodeView/TypeIndex.h"
  24. #include "llvm/ObjectYAML/YAML.h"
  25. #include "llvm/Support/Allocator.h"
  26. #include "llvm/Support/Error.h"
  27. #include "llvm/Support/ScopedPrinter.h"
  28. #include "llvm/Support/YAMLTraits.h"
  29. #include <algorithm>
  30. #include <cstdint>
  31. #include <cstring>
  32. #include <optional>
  33. #include <string>
  34. #include <vector>
  35. using namespace llvm;
  36. using namespace llvm::codeview;
  37. using namespace llvm::CodeViewYAML;
  38. using namespace llvm::CodeViewYAML::detail;
  39. using namespace llvm::yaml;
  40. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
  41. LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
  42. // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
  43. LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
  44. LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
  45. LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
  46. LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
  47. LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
  48. LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
  49. LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
  50. LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
  51. LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
  52. LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
  53. LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
  54. LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
  55. LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
  56. LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
  57. LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
  58. LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
  59. LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
  60. StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
  61. return ScalarTraits<StringRef>::input(S, V, T.value);
  62. }
  63. void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
  64. raw_ostream &R) {
  65. ScalarTraits<StringRef>::output(T.value, V, R);
  66. }
  67. void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
  68. SymbolKind &Value) {
  69. auto SymbolNames = getSymbolTypeNames();
  70. for (const auto &E : SymbolNames)
  71. io.enumCase(Value, E.Name.str().c_str(), E.Value);
  72. }
  73. void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
  74. CompileSym2Flags &Flags) {
  75. auto FlagNames = getCompileSym2FlagNames();
  76. for (const auto &E : FlagNames) {
  77. io.bitSetCase(Flags, E.Name.str().c_str(),
  78. static_cast<CompileSym2Flags>(E.Value));
  79. }
  80. }
  81. void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
  82. CompileSym3Flags &Flags) {
  83. auto FlagNames = getCompileSym3FlagNames();
  84. for (const auto &E : FlagNames) {
  85. io.bitSetCase(Flags, E.Name.str().c_str(),
  86. static_cast<CompileSym3Flags>(E.Value));
  87. }
  88. }
  89. void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
  90. auto FlagNames = getExportSymFlagNames();
  91. for (const auto &E : FlagNames) {
  92. io.bitSetCase(Flags, E.Name.str().c_str(),
  93. static_cast<ExportFlags>(E.Value));
  94. }
  95. }
  96. void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
  97. auto FlagNames = getPublicSymFlagNames();
  98. for (const auto &E : FlagNames) {
  99. io.bitSetCase(Flags, E.Name.str().c_str(),
  100. static_cast<PublicSymFlags>(E.Value));
  101. }
  102. }
  103. void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
  104. auto FlagNames = getLocalFlagNames();
  105. for (const auto &E : FlagNames) {
  106. io.bitSetCase(Flags, E.Name.str().c_str(),
  107. static_cast<LocalSymFlags>(E.Value));
  108. }
  109. }
  110. void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
  111. auto FlagNames = getProcSymFlagNames();
  112. for (const auto &E : FlagNames) {
  113. io.bitSetCase(Flags, E.Name.str().c_str(),
  114. static_cast<ProcSymFlags>(E.Value));
  115. }
  116. }
  117. void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
  118. IO &io, FrameProcedureOptions &Flags) {
  119. auto FlagNames = getFrameProcSymFlagNames();
  120. for (const auto &E : FlagNames) {
  121. io.bitSetCase(Flags, E.Name.str().c_str(),
  122. static_cast<FrameProcedureOptions>(E.Value));
  123. }
  124. }
  125. void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
  126. auto CpuNames = getCPUTypeNames();
  127. for (const auto &E : CpuNames) {
  128. io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
  129. }
  130. }
  131. void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
  132. const auto *Header = static_cast<COFF::header *>(io.getContext());
  133. assert(Header && "The IO context is not initialized");
  134. std::optional<CPUType> CpuType;
  135. ArrayRef<EnumEntry<uint16_t>> RegNames;
  136. switch (Header->Machine) {
  137. case COFF::IMAGE_FILE_MACHINE_I386:
  138. CpuType = CPUType::Pentium3;
  139. break;
  140. case COFF::IMAGE_FILE_MACHINE_AMD64:
  141. CpuType = CPUType::X64;
  142. break;
  143. case COFF::IMAGE_FILE_MACHINE_ARMNT:
  144. CpuType = CPUType::ARMNT;
  145. break;
  146. case COFF::IMAGE_FILE_MACHINE_ARM64:
  147. case COFF::IMAGE_FILE_MACHINE_ARM64EC:
  148. CpuType = CPUType::ARM64;
  149. break;
  150. }
  151. if (CpuType)
  152. RegNames = getRegisterNames(*CpuType);
  153. for (const auto &E : RegNames) {
  154. io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
  155. }
  156. io.enumFallback<Hex16>(Reg);
  157. }
  158. void ScalarEnumerationTraits<TrampolineType>::enumeration(
  159. IO &io, TrampolineType &Tramp) {
  160. auto TrampNames = getTrampolineNames();
  161. for (const auto &E : TrampNames) {
  162. io.enumCase(Tramp, E.Name.str().c_str(),
  163. static_cast<TrampolineType>(E.Value));
  164. }
  165. }
  166. void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
  167. ThunkOrdinal &Ord) {
  168. auto ThunkNames = getThunkOrdinalNames();
  169. for (const auto &E : ThunkNames) {
  170. io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
  171. }
  172. }
  173. void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
  174. IO &io, FrameCookieKind &FC) {
  175. auto ThunkNames = getFrameCookieKindNames();
  176. for (const auto &E : ThunkNames) {
  177. io.enumCase(FC, E.Name.str().c_str(),
  178. static_cast<FrameCookieKind>(E.Value));
  179. }
  180. }
  181. namespace llvm {
  182. namespace yaml {
  183. template <> struct MappingTraits<LocalVariableAddrRange> {
  184. static void mapping(IO &io, LocalVariableAddrRange &Range) {
  185. io.mapRequired("OffsetStart", Range.OffsetStart);
  186. io.mapRequired("ISectStart", Range.ISectStart);
  187. io.mapRequired("Range", Range.Range);
  188. }
  189. };
  190. template <> struct MappingTraits<LocalVariableAddrGap> {
  191. static void mapping(IO &io, LocalVariableAddrGap &Gap) {
  192. io.mapRequired("GapStartOffset", Gap.GapStartOffset);
  193. io.mapRequired("Range", Gap.Range);
  194. }
  195. };
  196. } // namespace yaml
  197. } // namespace llvm
  198. namespace llvm {
  199. namespace CodeViewYAML {
  200. namespace detail {
  201. struct SymbolRecordBase {
  202. codeview::SymbolKind Kind;
  203. explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
  204. virtual ~SymbolRecordBase() = default;
  205. virtual void map(yaml::IO &io) = 0;
  206. virtual codeview::CVSymbol
  207. toCodeViewSymbol(BumpPtrAllocator &Allocator,
  208. CodeViewContainer Container) const = 0;
  209. virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
  210. };
  211. template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
  212. explicit SymbolRecordImpl(codeview::SymbolKind K)
  213. : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
  214. void map(yaml::IO &io) override;
  215. codeview::CVSymbol
  216. toCodeViewSymbol(BumpPtrAllocator &Allocator,
  217. CodeViewContainer Container) const override {
  218. return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
  219. }
  220. Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
  221. return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
  222. }
  223. mutable T Symbol;
  224. };
  225. struct UnknownSymbolRecord : public SymbolRecordBase {
  226. explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
  227. void map(yaml::IO &io) override;
  228. CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
  229. CodeViewContainer Container) const override {
  230. RecordPrefix Prefix;
  231. uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
  232. Prefix.RecordKind = Kind;
  233. Prefix.RecordLen = TotalLen - 2;
  234. uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
  235. ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
  236. ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
  237. return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
  238. }
  239. Error fromCodeViewSymbol(CVSymbol CVS) override {
  240. this->Kind = CVS.kind();
  241. Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
  242. return Error::success();
  243. }
  244. std::vector<uint8_t> Data;
  245. };
  246. template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
  247. void UnknownSymbolRecord::map(yaml::IO &io) {
  248. yaml::BinaryRef Binary;
  249. if (io.outputting())
  250. Binary = yaml::BinaryRef(Data);
  251. io.mapRequired("Data", Binary);
  252. if (!io.outputting()) {
  253. std::string Str;
  254. raw_string_ostream OS(Str);
  255. Binary.writeAsBinary(OS);
  256. OS.flush();
  257. Data.assign(Str.begin(), Str.end());
  258. }
  259. }
  260. template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
  261. IO.mapRequired("Parent", Symbol.Parent);
  262. IO.mapRequired("End", Symbol.End);
  263. IO.mapRequired("Next", Symbol.Next);
  264. IO.mapRequired("Off", Symbol.Offset);
  265. IO.mapRequired("Seg", Symbol.Segment);
  266. IO.mapRequired("Len", Symbol.Length);
  267. IO.mapRequired("Ordinal", Symbol.Thunk);
  268. }
  269. template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
  270. IO.mapRequired("Type", Symbol.Type);
  271. IO.mapRequired("Size", Symbol.Size);
  272. IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
  273. IO.mapRequired("TargetOff", Symbol.TargetOffset);
  274. IO.mapRequired("ThunkSection", Symbol.ThunkSection);
  275. IO.mapRequired("TargetSection", Symbol.TargetSection);
  276. }
  277. template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
  278. IO.mapRequired("SectionNumber", Symbol.SectionNumber);
  279. IO.mapRequired("Alignment", Symbol.Alignment);
  280. IO.mapRequired("Rva", Symbol.Rva);
  281. IO.mapRequired("Length", Symbol.Length);
  282. IO.mapRequired("Characteristics", Symbol.Characteristics);
  283. IO.mapRequired("Name", Symbol.Name);
  284. }
  285. template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
  286. IO.mapRequired("Size", Symbol.Size);
  287. IO.mapRequired("Characteristics", Symbol.Characteristics);
  288. IO.mapRequired("Offset", Symbol.Offset);
  289. IO.mapRequired("Segment", Symbol.Segment);
  290. IO.mapRequired("Name", Symbol.Name);
  291. }
  292. template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
  293. IO.mapRequired("Ordinal", Symbol.Ordinal);
  294. IO.mapRequired("Flags", Symbol.Flags);
  295. IO.mapRequired("Name", Symbol.Name);
  296. }
  297. template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
  298. IO.mapOptional("PtrParent", Symbol.Parent, 0U);
  299. IO.mapOptional("PtrEnd", Symbol.End, 0U);
  300. IO.mapOptional("PtrNext", Symbol.Next, 0U);
  301. IO.mapRequired("CodeSize", Symbol.CodeSize);
  302. IO.mapRequired("DbgStart", Symbol.DbgStart);
  303. IO.mapRequired("DbgEnd", Symbol.DbgEnd);
  304. IO.mapRequired("FunctionType", Symbol.FunctionType);
  305. IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  306. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  307. IO.mapRequired("Flags", Symbol.Flags);
  308. IO.mapRequired("DisplayName", Symbol.Name);
  309. }
  310. template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
  311. IO.mapRequired("Type", Symbol.Index);
  312. IO.mapRequired("Seg", Symbol.Register);
  313. IO.mapRequired("Name", Symbol.Name);
  314. }
  315. template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
  316. IO.mapRequired("Flags", Symbol.Flags);
  317. IO.mapOptional("Offset", Symbol.Offset, 0U);
  318. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  319. IO.mapRequired("Name", Symbol.Name);
  320. }
  321. template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
  322. IO.mapRequired("SumName", Symbol.SumName);
  323. IO.mapRequired("SymOffset", Symbol.SymOffset);
  324. IO.mapRequired("Mod", Symbol.Module);
  325. IO.mapRequired("Name", Symbol.Name);
  326. }
  327. template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
  328. IO.mapRequired("Entries", Symbol.Fields);
  329. }
  330. template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
  331. IO.mapOptional("PtrParent", Symbol.Parent, 0U);
  332. IO.mapOptional("PtrEnd", Symbol.End, 0U);
  333. IO.mapRequired("Inlinee", Symbol.Inlinee);
  334. // TODO: The binary annotations
  335. }
  336. template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
  337. IO.mapRequired("Type", Symbol.Type);
  338. IO.mapRequired("Flags", Symbol.Flags);
  339. IO.mapRequired("VarName", Symbol.Name);
  340. }
  341. template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
  342. IO.mapRequired("Program", Symbol.Program);
  343. IO.mapRequired("Range", Symbol.Range);
  344. IO.mapRequired("Gaps", Symbol.Gaps);
  345. }
  346. template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
  347. IO.mapRequired("Program", Symbol.Program);
  348. IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
  349. IO.mapRequired("Range", Symbol.Range);
  350. IO.mapRequired("Gaps", Symbol.Gaps);
  351. }
  352. template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
  353. IO.mapRequired("Register", Symbol.Hdr.Register);
  354. IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
  355. IO.mapRequired("Range", Symbol.Range);
  356. IO.mapRequired("Gaps", Symbol.Gaps);
  357. }
  358. template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
  359. IO.mapRequired("Offset", Symbol.Hdr.Offset);
  360. IO.mapRequired("Range", Symbol.Range);
  361. IO.mapRequired("Gaps", Symbol.Gaps);
  362. }
  363. template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
  364. IO.mapRequired("Register", Symbol.Hdr.Register);
  365. IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
  366. IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
  367. IO.mapRequired("Range", Symbol.Range);
  368. IO.mapRequired("Gaps", Symbol.Gaps);
  369. }
  370. template <>
  371. void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
  372. IO.mapRequired("Register", Symbol.Offset);
  373. }
  374. template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
  375. IO.mapRequired("Register", Symbol.Hdr.Register);
  376. IO.mapRequired("Flags", Symbol.Hdr.Flags);
  377. IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
  378. IO.mapRequired("Range", Symbol.Range);
  379. IO.mapRequired("Gaps", Symbol.Gaps);
  380. }
  381. template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
  382. IO.mapOptional("PtrParent", Symbol.Parent, 0U);
  383. IO.mapOptional("PtrEnd", Symbol.End, 0U);
  384. IO.mapRequired("CodeSize", Symbol.CodeSize);
  385. IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  386. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  387. IO.mapRequired("BlockName", Symbol.Name);
  388. }
  389. template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
  390. IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  391. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  392. IO.mapRequired("Flags", Symbol.Flags);
  393. IO.mapRequired("Flags", Symbol.Flags);
  394. IO.mapRequired("DisplayName", Symbol.Name);
  395. }
  396. template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
  397. IO.mapRequired("Signature", Symbol.Signature);
  398. IO.mapRequired("ObjectName", Symbol.Name);
  399. }
  400. template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
  401. IO.mapRequired("Flags", Symbol.Flags);
  402. IO.mapRequired("Machine", Symbol.Machine);
  403. IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
  404. IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
  405. IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
  406. IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
  407. IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
  408. IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
  409. IO.mapRequired("Version", Symbol.Version);
  410. }
  411. template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
  412. IO.mapRequired("Flags", Symbol.Flags);
  413. IO.mapRequired("Machine", Symbol.Machine);
  414. IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
  415. IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
  416. IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
  417. IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
  418. IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
  419. IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
  420. IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
  421. IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
  422. IO.mapRequired("Version", Symbol.Version);
  423. }
  424. template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
  425. IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
  426. IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
  427. IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
  428. IO.mapRequired("BytesOfCalleeSavedRegisters",
  429. Symbol.BytesOfCalleeSavedRegisters);
  430. IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
  431. IO.mapRequired("SectionIdOfExceptionHandler",
  432. Symbol.SectionIdOfExceptionHandler);
  433. IO.mapRequired("Flags", Symbol.Flags);
  434. }
  435. template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
  436. IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  437. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  438. IO.mapRequired("Type", Symbol.Type);
  439. }
  440. template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
  441. IO.mapRequired("Index", Symbol.Index);
  442. IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
  443. IO.mapRequired("Flags", Symbol.Flags);
  444. IO.mapRequired("Name", Symbol.Name);
  445. }
  446. template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
  447. IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  448. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  449. IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
  450. IO.mapRequired("Type", Symbol.Type);
  451. }
  452. template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
  453. IO.mapRequired("Register", Symbol.Register);
  454. IO.mapRequired("CookieKind", Symbol.CookieKind);
  455. IO.mapRequired("Flags", Symbol.Flags);
  456. }
  457. template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
  458. IO.mapRequired("FuncID", Symbol.Indices);
  459. }
  460. template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
  461. IO.mapRequired("Type", Symbol.Type);
  462. IO.mapRequired("UDTName", Symbol.Name);
  463. }
  464. template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
  465. IO.mapRequired("BuildId", Symbol.BuildId);
  466. }
  467. template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
  468. IO.mapRequired("Offset", Symbol.Offset);
  469. IO.mapRequired("Type", Symbol.Type);
  470. IO.mapRequired("VarName", Symbol.Name);
  471. }
  472. template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
  473. IO.mapRequired("Offset", Symbol.Offset);
  474. IO.mapRequired("Type", Symbol.Type);
  475. IO.mapRequired("Register", Symbol.Register);
  476. IO.mapRequired("VarName", Symbol.Name);
  477. }
  478. template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
  479. IO.mapRequired("Type", Symbol.Type);
  480. IO.mapRequired("Value", Symbol.Value);
  481. IO.mapRequired("Name", Symbol.Name);
  482. }
  483. template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
  484. IO.mapRequired("Type", Symbol.Type);
  485. IO.mapOptional("Offset", Symbol.DataOffset, 0U);
  486. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  487. IO.mapRequired("DisplayName", Symbol.Name);
  488. }
  489. template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
  490. IO.mapRequired("Type", Symbol.Type);
  491. IO.mapOptional("Offset", Symbol.DataOffset, 0U);
  492. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  493. IO.mapRequired("DisplayName", Symbol.Name);
  494. }
  495. template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
  496. IO.mapRequired("Namespace", Symbol.Name);
  497. }
  498. template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
  499. IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
  500. IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
  501. IO.mapRequired("Strings", Symbol.Strings);
  502. }
  503. } // end namespace detail
  504. } // end namespace CodeViewYAML
  505. } // end namespace llvm
  506. CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
  507. BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
  508. return Symbol->toCodeViewSymbol(Allocator, Container);
  509. }
  510. namespace llvm {
  511. namespace yaml {
  512. template <> struct MappingTraits<SymbolRecordBase> {
  513. static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
  514. };
  515. } // end namespace yaml
  516. } // end namespace llvm
  517. template <typename SymbolType>
  518. static inline Expected<CodeViewYAML::SymbolRecord>
  519. fromCodeViewSymbolImpl(CVSymbol Symbol) {
  520. CodeViewYAML::SymbolRecord Result;
  521. auto Impl = std::make_shared<SymbolType>(Symbol.kind());
  522. if (auto EC = Impl->fromCodeViewSymbol(Symbol))
  523. return std::move(EC);
  524. Result.Symbol = Impl;
  525. return Result;
  526. }
  527. Expected<CodeViewYAML::SymbolRecord>
  528. CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
  529. #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
  530. case EnumName: \
  531. return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
  532. #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
  533. SYMBOL_RECORD(EnumName, EnumVal, ClassName)
  534. switch (Symbol.kind()) {
  535. #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  536. default:
  537. return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
  538. }
  539. return make_error<CodeViewError>(cv_error_code::corrupt_record);
  540. }
  541. template <typename ConcreteType>
  542. static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
  543. CodeViewYAML::SymbolRecord &Obj) {
  544. if (!IO.outputting())
  545. Obj.Symbol = std::make_shared<ConcreteType>(Kind);
  546. IO.mapRequired(Class, *Obj.Symbol);
  547. }
  548. void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
  549. IO &IO, CodeViewYAML::SymbolRecord &Obj) {
  550. SymbolKind Kind;
  551. if (IO.outputting())
  552. Kind = Obj.Symbol->Kind;
  553. IO.mapRequired("Kind", Kind);
  554. #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
  555. case EnumName: \
  556. mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
  557. Obj); \
  558. break;
  559. #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
  560. SYMBOL_RECORD(EnumName, EnumVal, ClassName)
  561. switch (Kind) {
  562. #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  563. default:
  564. mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
  565. }
  566. }