Header.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //===- Header.cpp -----------------------------------------------*- 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. #include "llvm/DebugInfo/GSYM/Header.h"
  9. #include "llvm/DebugInfo/GSYM/FileWriter.h"
  10. #include "llvm/Support/DataExtractor.h"
  11. #include "llvm/Support/Format.h"
  12. #include "llvm/Support/raw_ostream.h"
  13. #define HEX8(v) llvm::format_hex(v, 4)
  14. #define HEX16(v) llvm::format_hex(v, 6)
  15. #define HEX32(v) llvm::format_hex(v, 10)
  16. #define HEX64(v) llvm::format_hex(v, 18)
  17. using namespace llvm;
  18. using namespace gsym;
  19. raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const Header &H) {
  20. OS << "Header:\n";
  21. OS << " Magic = " << HEX32(H.Magic) << "\n";
  22. OS << " Version = " << HEX16(H.Version) << '\n';
  23. OS << " AddrOffSize = " << HEX8(H.AddrOffSize) << '\n';
  24. OS << " UUIDSize = " << HEX8(H.UUIDSize) << '\n';
  25. OS << " BaseAddress = " << HEX64(H.BaseAddress) << '\n';
  26. OS << " NumAddresses = " << HEX32(H.NumAddresses) << '\n';
  27. OS << " StrtabOffset = " << HEX32(H.StrtabOffset) << '\n';
  28. OS << " StrtabSize = " << HEX32(H.StrtabSize) << '\n';
  29. OS << " UUID = ";
  30. for (uint8_t I = 0; I < H.UUIDSize; ++I)
  31. OS << format_hex_no_prefix(H.UUID[I], 2);
  32. OS << '\n';
  33. return OS;
  34. }
  35. /// Check the header and detect any errors.
  36. llvm::Error Header::checkForError() const {
  37. if (Magic != GSYM_MAGIC)
  38. return createStringError(std::errc::invalid_argument,
  39. "invalid GSYM magic 0x%8.8x", Magic);
  40. if (Version != GSYM_VERSION)
  41. return createStringError(std::errc::invalid_argument,
  42. "unsupported GSYM version %u", Version);
  43. switch (AddrOffSize) {
  44. case 1: break;
  45. case 2: break;
  46. case 4: break;
  47. case 8: break;
  48. default:
  49. return createStringError(std::errc::invalid_argument,
  50. "invalid address offset size %u",
  51. AddrOffSize);
  52. }
  53. if (UUIDSize > GSYM_MAX_UUID_SIZE)
  54. return createStringError(std::errc::invalid_argument,
  55. "invalid UUID size %u", UUIDSize);
  56. return Error::success();
  57. }
  58. llvm::Expected<Header> Header::decode(DataExtractor &Data) {
  59. uint64_t Offset = 0;
  60. // The header is stored as a single blob of data that has a fixed byte size.
  61. if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Header)))
  62. return createStringError(std::errc::invalid_argument,
  63. "not enough data for a gsym::Header");
  64. Header H;
  65. H.Magic = Data.getU32(&Offset);
  66. H.Version = Data.getU16(&Offset);
  67. H.AddrOffSize = Data.getU8(&Offset);
  68. H.UUIDSize = Data.getU8(&Offset);
  69. H.BaseAddress = Data.getU64(&Offset);
  70. H.NumAddresses = Data.getU32(&Offset);
  71. H.StrtabOffset = Data.getU32(&Offset);
  72. H.StrtabSize = Data.getU32(&Offset);
  73. Data.getU8(&Offset, H.UUID, GSYM_MAX_UUID_SIZE);
  74. if (llvm::Error Err = H.checkForError())
  75. return std::move(Err);
  76. return H;
  77. }
  78. llvm::Error Header::encode(FileWriter &O) const {
  79. // Users must verify the Header is valid prior to calling this funtion.
  80. if (llvm::Error Err = checkForError())
  81. return Err;
  82. O.writeU32(Magic);
  83. O.writeU16(Version);
  84. O.writeU8(AddrOffSize);
  85. O.writeU8(UUIDSize);
  86. O.writeU64(BaseAddress);
  87. O.writeU32(NumAddresses);
  88. O.writeU32(StrtabOffset);
  89. O.writeU32(StrtabSize);
  90. O.writeData(llvm::ArrayRef<uint8_t>(UUID));
  91. return Error::success();
  92. }
  93. bool llvm::gsym::operator==(const Header &LHS, const Header &RHS) {
  94. return LHS.Magic == RHS.Magic && LHS.Version == RHS.Version &&
  95. LHS.AddrOffSize == RHS.AddrOffSize && LHS.UUIDSize == RHS.UUIDSize &&
  96. LHS.BaseAddress == RHS.BaseAddress &&
  97. LHS.NumAddresses == RHS.NumAddresses &&
  98. LHS.StrtabOffset == RHS.StrtabOffset &&
  99. LHS.StrtabSize == RHS.StrtabSize &&
  100. memcmp(LHS.UUID, RHS.UUID, LHS.UUIDSize) == 0;
  101. }