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