DebugStringTableSubsection.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //===- DebugStringTableSubsection.cpp - CodeView String Table -------------===//
  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/DebugStringTableSubsection.h"
  9. #include "llvm/ADT/StringRef.h"
  10. #include "llvm/DebugInfo/CodeView/CodeView.h"
  11. #include "llvm/Support/BinaryStreamReader.h"
  12. #include "llvm/Support/BinaryStreamWriter.h"
  13. #include "llvm/Support/Error.h"
  14. #include <algorithm>
  15. #include <cassert>
  16. #include <cstdint>
  17. using namespace llvm;
  18. using namespace llvm::codeview;
  19. DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
  20. : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
  21. Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
  22. Stream = Contents;
  23. return Error::success();
  24. }
  25. Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {
  26. return Reader.readStreamRef(Stream);
  27. }
  28. Expected<StringRef>
  29. DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
  30. BinaryStreamReader Reader(Stream);
  31. Reader.setOffset(Offset);
  32. StringRef Result;
  33. if (auto EC = Reader.readCString(Result))
  34. return std::move(EC);
  35. return Result;
  36. }
  37. DebugStringTableSubsection::DebugStringTableSubsection()
  38. : DebugSubsection(DebugSubsectionKind::StringTable) {}
  39. uint32_t DebugStringTableSubsection::insert(StringRef S) {
  40. auto P = StringToId.insert({S, StringSize});
  41. // If a given string didn't exist in the string table, we want to increment
  42. // the string table size and insert it into the reverse lookup.
  43. if (P.second) {
  44. IdToString.insert({P.first->getValue(), P.first->getKey()});
  45. StringSize += S.size() + 1; // +1 for '\0'
  46. }
  47. return P.first->second;
  48. }
  49. uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
  50. return StringSize;
  51. }
  52. Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
  53. uint32_t Begin = Writer.getOffset();
  54. uint32_t End = Begin + StringSize;
  55. // Write a null string at the beginning.
  56. if (auto EC = Writer.writeCString(StringRef()))
  57. return EC;
  58. for (auto &Pair : StringToId) {
  59. StringRef S = Pair.getKey();
  60. uint32_t Offset = Begin + Pair.getValue();
  61. Writer.setOffset(Offset);
  62. if (auto EC = Writer.writeCString(S))
  63. return EC;
  64. assert(Writer.getOffset() <= End);
  65. }
  66. Writer.setOffset(End);
  67. assert((End - Begin) == StringSize);
  68. return Error::success();
  69. }
  70. uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }
  71. std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const {
  72. std::vector<uint32_t> Result;
  73. Result.reserve(IdToString.size());
  74. for (const auto &Entry : IdToString)
  75. Result.push_back(Entry.first);
  76. llvm::sort(Result);
  77. return Result;
  78. }
  79. uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {
  80. auto Iter = StringToId.find(S);
  81. assert(Iter != StringToId.end());
  82. return Iter->second;
  83. }
  84. StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const {
  85. auto Iter = IdToString.find(Id);
  86. assert(Iter != IdToString.end());
  87. return Iter->second;
  88. }