CodeViewYAMLSymbols.cpp 23 KB

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