[PDB] Error on too large stream directories
We hit this in Chromium builds where the PDB file was just under 4GB, but the stream directory was actually too large to be correctly represented. llvm-pdbutil would error about this in llvm::msf::validateSuperBlock, but lld should not write such PDB files in the first place. Differential revision: https://reviews.llvm.org/D144385
This commit is contained in:
parent
c6f64c5d88
commit
724b58f766
|
@ -31,6 +31,7 @@
|
|||
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
|
||||
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
|
||||
#include "llvm/DebugInfo/MSF/MSFCommon.h"
|
||||
#include "llvm/DebugInfo/MSF/MSFError.h"
|
||||
#include "llvm/DebugInfo/PDB/GenericError.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
|
||||
|
@ -1687,6 +1688,12 @@ void PDBLinker::commit(codeview::GUID *guid) {
|
|||
// the user can see the output of /time and /summary, which is very helpful
|
||||
// when trying to figure out why a PDB file is too large.
|
||||
if (Error e = builder.commit(ctx.config.pdbPath, guid)) {
|
||||
e = handleErrors(std::move(e),
|
||||
[](const llvm::msf::MSFError &me) {
|
||||
error(me.message());
|
||||
if (me.isPageOverflow())
|
||||
error("try setting a larger /pdbpagesize");
|
||||
});
|
||||
checkError(std::move(e));
|
||||
error("failed to write PDB file " + Twine(ctx.config.pdbPath));
|
||||
}
|
||||
|
|
|
@ -16,14 +16,15 @@ namespace msf {
|
|||
enum class msf_error_code {
|
||||
unspecified = 1,
|
||||
insufficient_buffer,
|
||||
not_writable,
|
||||
no_stream,
|
||||
invalid_format,
|
||||
block_in_use,
|
||||
size_overflow_4096,
|
||||
size_overflow_8192,
|
||||
size_overflow_16384,
|
||||
size_overflow_32768,
|
||||
not_writable,
|
||||
no_stream,
|
||||
invalid_format,
|
||||
block_in_use
|
||||
stream_directory_overflow,
|
||||
};
|
||||
} // namespace msf
|
||||
} // namespace llvm
|
||||
|
@ -46,6 +47,25 @@ class MSFError : public ErrorInfo<MSFError, StringError> {
|
|||
public:
|
||||
using ErrorInfo<MSFError, StringError>::ErrorInfo; // inherit constructors
|
||||
MSFError(const Twine &S) : ErrorInfo(S, msf_error_code::unspecified) {}
|
||||
|
||||
bool isPageOverflow() const {
|
||||
switch (static_cast<msf_error_code>(convertToErrorCode().value())) {
|
||||
case msf_error_code::unspecified:
|
||||
case msf_error_code::insufficient_buffer:
|
||||
case msf_error_code::not_writable:
|
||||
case msf_error_code::no_stream:
|
||||
case msf_error_code::invalid_format:
|
||||
case msf_error_code::block_in_use:
|
||||
return false;
|
||||
case msf_error_code::size_overflow_4096:
|
||||
case msf_error_code::size_overflow_8192:
|
||||
case msf_error_code::size_overflow_16384:
|
||||
case msf_error_code::size_overflow_32768:
|
||||
case msf_error_code::stream_directory_overflow:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static char ID;
|
||||
};
|
||||
} // namespace msf
|
||||
|
|
|
@ -364,6 +364,18 @@ Expected<FileBufferByteStream> MSFBuilder::commit(StringRef Path,
|
|||
FileSize, Layout.SB->BlockSize));
|
||||
}
|
||||
|
||||
uint64_t NumDirectoryBlocks =
|
||||
bytesToBlocks(Layout.SB->NumDirectoryBytes, Layout.SB->BlockSize);
|
||||
uint64_t DirectoryBlockMapSize =
|
||||
NumDirectoryBlocks * sizeof(support::ulittle32_t);
|
||||
if (DirectoryBlockMapSize > Layout.SB->BlockSize) {
|
||||
return make_error<MSFError>(msf_error_code::stream_directory_overflow,
|
||||
formatv("The directory block map ({0} bytes) "
|
||||
"doesn't fit in a block ({1} bytes)",
|
||||
DirectoryBlockMapSize,
|
||||
Layout.SB->BlockSize));
|
||||
}
|
||||
|
||||
auto OutFileOrError = FileOutputBuffer::create(Path, FileSize);
|
||||
if (auto EC = OutFileOrError.takeError())
|
||||
return std::move(EC);
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
return "The data is in an unexpected format.";
|
||||
case msf_error_code::block_in_use:
|
||||
return "The block is already in use.";
|
||||
case msf_error_code::stream_directory_overflow:
|
||||
return "PDB stream directory too large.";
|
||||
}
|
||||
llvm_unreachable("Unrecognized msf_error_code");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user