mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[DWARF] Use DWARFDataExtractor::getInitialLength to parse debug_names
Summary: In this patch I've done a slightly bigger rewrite to also remove the hardcoded header lengths. Reviewers: jhenderson, dblaikie, ikudrin Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75119
This commit is contained in:
parent
16b078b185
commit
b424382a42
@ -377,56 +377,36 @@ void DWARFDebugNames::Header::dump(ScopedPrinter &W) const {
|
||||
|
||||
Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
|
||||
uint64_t *Offset) {
|
||||
uint64_t StartingOffset = *Offset;
|
||||
// Check that we can read the unit length field.
|
||||
if (!AS.isValidOffsetForDataOfSize(StartingOffset, 4))
|
||||
auto HeaderError = [Offset = *Offset](Error E) {
|
||||
return createStringError(errc::illegal_byte_sequence,
|
||||
"Section too small: cannot read header.");
|
||||
UnitLength = AS.getU32(Offset);
|
||||
if (UnitLength >= dwarf::DW_LENGTH_lo_reserved &&
|
||||
UnitLength != dwarf::DW_LENGTH_DWARF64)
|
||||
return createStringError(errc::illegal_byte_sequence,
|
||||
"Unsupported reserved unit length value");
|
||||
Format = (UnitLength == dwarf::DW_LENGTH_DWARF64) ? dwarf::DWARF64
|
||||
: dwarf::DWARF32;
|
||||
"parsing .debug_names header at 0x%" PRIx64 ": %s",
|
||||
Offset, toString(std::move(E)).c_str());
|
||||
};
|
||||
|
||||
// These fields are the same for 32-bit and 64-bit DWARF formats.
|
||||
constexpr unsigned CommonHeaderSize = 2 + // Version
|
||||
2 + // Padding
|
||||
4 + // CU count
|
||||
4 + // Local TU count
|
||||
4 + // Foreign TU count
|
||||
4 + // Bucket count
|
||||
4 + // Name count
|
||||
4 + // Abbreviations table size
|
||||
4; // Augmentation string size
|
||||
// Check that we can read the fixed-size part.
|
||||
if (!AS.isValidOffsetForDataOfSize(
|
||||
StartingOffset,
|
||||
CommonHeaderSize + dwarf::getUnitLengthFieldByteSize(Format)))
|
||||
return createStringError(errc::illegal_byte_sequence,
|
||||
"Section too small: cannot read header.");
|
||||
if (Format == dwarf::DWARF64)
|
||||
UnitLength = AS.getU64(Offset);
|
||||
Version = AS.getU16(Offset);
|
||||
// Skip padding
|
||||
*Offset += 2;
|
||||
CompUnitCount = AS.getU32(Offset);
|
||||
LocalTypeUnitCount = AS.getU32(Offset);
|
||||
ForeignTypeUnitCount = AS.getU32(Offset);
|
||||
BucketCount = AS.getU32(Offset);
|
||||
NameCount = AS.getU32(Offset);
|
||||
AbbrevTableSize = AS.getU32(Offset);
|
||||
AugmentationStringSize = alignTo(AS.getU32(Offset), 4);
|
||||
DataExtractor::Cursor C(*Offset);
|
||||
std::tie(UnitLength, Format) = AS.getInitialLength(C);
|
||||
|
||||
if (!AS.isValidOffsetForDataOfSize(*Offset, AugmentationStringSize))
|
||||
return createStringError(
|
||||
errc::illegal_byte_sequence,
|
||||
"Section too small: cannot read header augmentation.");
|
||||
Version = AS.getU16(C);
|
||||
AS.skip(C, 2); // padding
|
||||
CompUnitCount = AS.getU32(C);
|
||||
LocalTypeUnitCount = AS.getU32(C);
|
||||
ForeignTypeUnitCount = AS.getU32(C);
|
||||
BucketCount = AS.getU32(C);
|
||||
NameCount = AS.getU32(C);
|
||||
AbbrevTableSize = AS.getU32(C);
|
||||
AugmentationStringSize = alignTo(AS.getU32(C), 4);
|
||||
|
||||
if (!C)
|
||||
return HeaderError(C.takeError());
|
||||
|
||||
if (!AS.isValidOffsetForDataOfSize(C.tell(), AugmentationStringSize))
|
||||
return HeaderError(createStringError(errc::illegal_byte_sequence,
|
||||
"cannot read header augmentation"));
|
||||
AugmentationString.resize(AugmentationStringSize);
|
||||
AS.getU8(Offset, reinterpret_cast<uint8_t *>(AugmentationString.data()),
|
||||
AS.getU8(C, reinterpret_cast<uint8_t *>(AugmentationString.data()),
|
||||
AugmentationStringSize);
|
||||
return Error::success();
|
||||
*Offset = C.tell();
|
||||
return C.takeError();
|
||||
}
|
||||
|
||||
void DWARFDebugNames::Abbrev::dump(ScopedPrinter &W) const {
|
||||
|
@ -1,7 +1,7 @@
|
||||
# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
|
||||
# RUN: not llvm-dwarfdump -verify - | FileCheck %s
|
||||
|
||||
# CHECK: Section too small: cannot read header.
|
||||
# CHECK: parsing .debug_names header at 0x0: unexpected end of data at offset 0x20
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Lstring_producer:
|
||||
|
@ -1,7 +1,7 @@
|
||||
# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
|
||||
# RUN: not llvm-dwarfdump -verify - | FileCheck %s
|
||||
|
||||
# CHECK: Section too small: cannot read header augmentation.
|
||||
# CHECK: parsing .debug_names header at 0x0: cannot read header augmentation
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Lstring_producer:
|
||||
|
@ -8,45 +8,42 @@
|
||||
|
||||
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/Testing/Support/Error.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
void ExpectDebugNamesExtractError(StringRef NamesSecData, StringRef StrSecData,
|
||||
const char *ErrorMessage) {
|
||||
DWARFSection NamesDWARFSection;
|
||||
NamesDWARFSection.Data = NamesSecData;
|
||||
StringMap<std::unique_ptr<MemoryBuffer>> Sections;
|
||||
auto Context = DWARFContext::create(Sections, /* AddrSize = */ 4,
|
||||
/* isLittleEndian = */ true);
|
||||
DWARFDataExtractor NamesExtractor(Context->getDWARFObj(), NamesDWARFSection,
|
||||
/* isLittleEndian = */ true,
|
||||
/* AddrSize = */ 4);
|
||||
static Error ExtractDebugNames(StringRef NamesSecData, StringRef StrSecData) {
|
||||
DWARFDataExtractor NamesExtractor(NamesSecData,
|
||||
/*isLittleEndian=*/true,
|
||||
/*AddrSize=*/4);
|
||||
DataExtractor StrExtractor(StrSecData,
|
||||
/* isLittleEndian = */ true,
|
||||
/* AddrSize = */ 4);
|
||||
/*isLittleEndian=*/true,
|
||||
/*AddrSize=*/4);
|
||||
DWARFDebugNames Table(NamesExtractor, StrExtractor);
|
||||
Error E = Table.extract();
|
||||
ASSERT_TRUE(E.operator bool());
|
||||
EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str());
|
||||
return Table.extract();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(DWARFDebugNames, ReservedUnitLength) {
|
||||
static const char NamesSecData[64] =
|
||||
"\xf0\xff\xff\xff"; // Reserved unit length value
|
||||
ExpectDebugNamesExtractError(StringRef(NamesSecData, sizeof(NamesSecData)),
|
||||
StringRef(),
|
||||
"Unsupported reserved unit length value");
|
||||
EXPECT_THAT_ERROR(
|
||||
ExtractDebugNames(StringRef(NamesSecData, sizeof(NamesSecData)),
|
||||
StringRef()),
|
||||
FailedWithMessage("parsing .debug_names header at 0x0: unsupported "
|
||||
"reserved unit length of value 0xfffffff0"));
|
||||
}
|
||||
|
||||
TEST(DWARFDebugNames, TooSmallForDWARF64) {
|
||||
// DWARF64 header takes at least 44 bytes.
|
||||
static const char NamesSecData[43] = "\xff\xff\xff\xff"; // DWARF64 mark
|
||||
ExpectDebugNamesExtractError(
|
||||
StringRef(NamesSecData, sizeof(NamesSecData)), StringRef(),
|
||||
"Section too small: cannot read header.");
|
||||
EXPECT_THAT_ERROR(
|
||||
ExtractDebugNames(StringRef(NamesSecData, sizeof(NamesSecData)),
|
||||
StringRef()),
|
||||
FailedWithMessage("parsing .debug_names header at 0x0: unexpected end of "
|
||||
"data at offset 0x28"));
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user