DebugInlineeLinesSubsection.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //===- DebugInlineeLinesSubsection.cpp ------------------------------------===//
  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. #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
  9. #include "llvm/ADT/ArrayRef.h"
  10. #include "llvm/DebugInfo/CodeView/CodeView.h"
  11. #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
  12. #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
  13. #include "llvm/Support/BinaryStreamReader.h"
  14. #include "llvm/Support/BinaryStreamWriter.h"
  15. #include "llvm/Support/Endian.h"
  16. #include "llvm/Support/Error.h"
  17. #include <cassert>
  18. #include <cstdint>
  19. using namespace llvm;
  20. using namespace llvm::codeview;
  21. Error VarStreamArrayExtractor<InlineeSourceLine>::
  22. operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) {
  23. BinaryStreamReader Reader(Stream);
  24. if (auto EC = Reader.readObject(Item.Header))
  25. return EC;
  26. if (HasExtraFiles) {
  27. uint32_t ExtraFileCount;
  28. if (auto EC = Reader.readInteger(ExtraFileCount))
  29. return EC;
  30. if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
  31. return EC;
  32. }
  33. Len = Reader.getOffset();
  34. return Error::success();
  35. }
  36. DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
  37. : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
  38. Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
  39. if (auto EC = Reader.readEnum(Signature))
  40. return EC;
  41. Lines.getExtractor().HasExtraFiles = hasExtraFiles();
  42. if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining()))
  43. return EC;
  44. assert(Reader.bytesRemaining() == 0);
  45. return Error::success();
  46. }
  47. bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
  48. return Signature == InlineeLinesSignature::ExtraFiles;
  49. }
  50. DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
  51. DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
  52. : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
  53. HasExtraFiles(HasExtraFiles) {}
  54. uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
  55. // 4 bytes for the signature
  56. uint32_t Size = sizeof(InlineeLinesSignature);
  57. // one header for each entry.
  58. Size += Entries.size() * sizeof(InlineeSourceLineHeader);
  59. if (HasExtraFiles) {
  60. // If extra files are enabled, one count for each entry.
  61. Size += Entries.size() * sizeof(uint32_t);
  62. // And one file id for each file.
  63. Size += ExtraFileCount * sizeof(uint32_t);
  64. }
  65. assert(Size % 4 == 0);
  66. return Size;
  67. }
  68. Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
  69. InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
  70. if (HasExtraFiles)
  71. Sig = InlineeLinesSignature::ExtraFiles;
  72. if (auto EC = Writer.writeEnum(Sig))
  73. return EC;
  74. for (const auto &E : Entries) {
  75. if (auto EC = Writer.writeObject(E.Header))
  76. return EC;
  77. if (!HasExtraFiles)
  78. continue;
  79. if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
  80. return EC;
  81. if (auto EC = Writer.writeArray(ArrayRef(E.ExtraFiles)))
  82. return EC;
  83. }
  84. return Error::success();
  85. }
  86. void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
  87. uint32_t Offset = Checksums.mapChecksumOffset(FileName);
  88. auto &Entry = Entries.back();
  89. Entry.ExtraFiles.push_back(ulittle32_t(Offset));
  90. ++ExtraFileCount;
  91. }
  92. void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
  93. StringRef FileName,
  94. uint32_t SourceLine) {
  95. uint32_t Offset = Checksums.mapChecksumOffset(FileName);
  96. Entries.emplace_back();
  97. auto &Entry = Entries.back();
  98. Entry.Header.FileID = Offset;
  99. Entry.Header.SourceLineNum = SourceLine;
  100. Entry.Header.Inlinee = FuncId;
  101. }