MSFCommon.cpp 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //===- MSFCommon.cpp - Common types and functions for MSF files -----------===//
  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/MSF/MSFCommon.h"
  9. #include "llvm/DebugInfo/MSF/MSFError.h"
  10. #include "llvm/Support/Endian.h"
  11. #include "llvm/Support/Error.h"
  12. #include <cstdint>
  13. #include <cstring>
  14. using namespace llvm;
  15. using namespace llvm::msf;
  16. Error llvm::msf::validateSuperBlock(const SuperBlock &SB) {
  17. // Check the magic bytes.
  18. if (std::memcmp(SB.MagicBytes, Magic, sizeof(Magic)) != 0)
  19. return make_error<MSFError>(msf_error_code::invalid_format,
  20. "MSF magic header doesn't match");
  21. if (!isValidBlockSize(SB.BlockSize))
  22. return make_error<MSFError>(msf_error_code::invalid_format,
  23. "Unsupported block size.");
  24. // We don't support directories whose sizes aren't a multiple of four bytes.
  25. if (SB.NumDirectoryBytes % sizeof(support::ulittle32_t) != 0)
  26. return make_error<MSFError>(msf_error_code::invalid_format,
  27. "Directory size is not multiple of 4.");
  28. // The number of blocks which comprise the directory is a simple function of
  29. // the number of bytes it contains.
  30. uint64_t NumDirectoryBlocks =
  31. bytesToBlocks(SB.NumDirectoryBytes, SB.BlockSize);
  32. // The directory, as we understand it, is a block which consists of a list of
  33. // block numbers. It is unclear what would happen if the number of blocks
  34. // couldn't fit on a single block.
  35. if (NumDirectoryBlocks > SB.BlockSize / sizeof(support::ulittle32_t))
  36. return make_error<MSFError>(msf_error_code::invalid_format,
  37. "Too many directory blocks.");
  38. if (SB.BlockMapAddr == 0)
  39. return make_error<MSFError>(msf_error_code::invalid_format,
  40. "Block 0 is reserved");
  41. if (SB.BlockMapAddr >= SB.NumBlocks)
  42. return make_error<MSFError>(msf_error_code::invalid_format,
  43. "Block map address is invalid.");
  44. if (SB.FreeBlockMapBlock != 1 && SB.FreeBlockMapBlock != 2)
  45. return make_error<MSFError>(
  46. msf_error_code::invalid_format,
  47. "The free block map isn't at block 1 or block 2.");
  48. return Error::success();
  49. }
  50. MSFStreamLayout llvm::msf::getFpmStreamLayout(const MSFLayout &Msf,
  51. bool IncludeUnusedFpmData,
  52. bool AltFpm) {
  53. MSFStreamLayout FL;
  54. uint32_t NumFpmIntervals =
  55. getNumFpmIntervals(Msf, IncludeUnusedFpmData, AltFpm);
  56. uint32_t FpmBlock = AltFpm ? Msf.alternateFpmBlock() : Msf.mainFpmBlock();
  57. for (uint32_t I = 0; I < NumFpmIntervals; ++I) {
  58. FL.Blocks.push_back(support::ulittle32_t(FpmBlock));
  59. FpmBlock += msf::getFpmIntervalLength(Msf);
  60. }
  61. if (IncludeUnusedFpmData)
  62. FL.Length = NumFpmIntervals * Msf.SB->BlockSize;
  63. else
  64. FL.Length = divideCeil(Msf.SB->NumBlocks, 8);
  65. return FL;
  66. }