1
0
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:
Pavel Labath 2020-02-25 15:40:49 +01:00
parent 16b078b185
commit b424382a42
4 changed files with 47 additions and 70 deletions

View File

@ -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 {

View File

@ -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:

View File

@ -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:

View File

@ -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