272 lines
10 KiB
C++
272 lines
10 KiB
C++
|
//===- llvm/unittest/DebugInfo/DWARFDebugArangeSetTest.cpp-----------------===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
|
||
|
#include "llvm/Testing/Support/Error.h"
|
||
|
#include "gtest/gtest.h"
|
||
|
|
||
|
using namespace llvm;
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
struct WarningHandler {
|
||
|
~WarningHandler() { EXPECT_THAT_ERROR(std::move(Err), Succeeded()); }
|
||
|
|
||
|
void operator()(Error E) { Err = joinErrors(std::move(Err), std::move(E)); }
|
||
|
|
||
|
Error getWarning() { return std::move(Err); }
|
||
|
|
||
|
Error Err = Error::success();
|
||
|
};
|
||
|
|
||
|
template <size_t SecSize>
|
||
|
void ExpectExtractError(const char (&SecDataRaw)[SecSize],
|
||
|
const char *ErrorMessage) {
|
||
|
DWARFDataExtractor Extractor(StringRef(SecDataRaw, SecSize - 1),
|
||
|
/* IsLittleEndian = */ true,
|
||
|
/* AddressSize = */ 4);
|
||
|
DWARFDebugArangeSet Set;
|
||
|
uint64_t Offset = 0;
|
||
|
WarningHandler Warnings;
|
||
|
Error E = Set.extract(Extractor, &Offset, Warnings);
|
||
|
ASSERT_TRUE(E.operator bool());
|
||
|
EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str());
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, LengthExceedsSectionSize) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x15\x00\x00\x00" // The length exceeds the section boundaries
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
"\x00\x00\x00\x00" // Padding
|
||
|
"\x00\x00\x00\x00" // Termination tuple
|
||
|
"\x00\x00\x00\x00";
|
||
|
ExpectExtractError(
|
||
|
DebugArangesSecRaw,
|
||
|
"the length of address range table at offset 0x0 exceeds section size");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, LengthExceedsSectionSizeDWARF64) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\xff\xff\xff\xff" // DWARF64 mark
|
||
|
"\x15\x00\x00\x00\x00\x00\x00\x00" // The length exceeds the section
|
||
|
// boundaries
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
// No padding
|
||
|
"\x00\x00\x00\x00" // Termination tuple
|
||
|
"\x00\x00\x00\x00";
|
||
|
ExpectExtractError(
|
||
|
DebugArangesSecRaw,
|
||
|
"the length of address range table at offset 0x0 exceeds section size");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, UnsupportedAddressSize) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x0c\x00\x00\x00" // Length
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x02" // Address Size (not supported)
|
||
|
"\x00" // Segment Selector Size
|
||
|
// No padding
|
||
|
"\x00\x00\x00\x00"; // Termination tuple
|
||
|
ExpectExtractError(
|
||
|
DebugArangesSecRaw,
|
||
|
"address range table at offset 0x0 has unsupported address size: 2 "
|
||
|
"(4 and 8 supported)");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, UnsupportedSegmentSelectorSize) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x14\x00\x00\x00" // Length
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x04" // Segment Selector Size (not supported)
|
||
|
// No padding
|
||
|
"\x00\x00\x00\x00" // Termination tuple
|
||
|
"\x00\x00\x00\x00"
|
||
|
"\x00\x00\x00\x00";
|
||
|
ExpectExtractError(
|
||
|
DebugArangesSecRaw,
|
||
|
"non-zero segment selector size in address range table at offset 0x0 "
|
||
|
"is not supported");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, NoTerminationEntry) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x14\x00\x00\x00" // Length
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
"\x00\x00\x00\x00" // Padding
|
||
|
"\x00\x00\x00\x00" // Entry: Address
|
||
|
"\x01\x00\x00\x00" // Length
|
||
|
; // No termination tuple
|
||
|
ExpectExtractError(
|
||
|
DebugArangesSecRaw,
|
||
|
"address range table at offset 0x0 is not terminated by null entry");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, ReservedUnitLength) {
|
||
|
// Note: 12 is the minimum length to pass the basic check for the size of
|
||
|
// the section. 1 will be automatically subtracted in ExpectExtractError().
|
||
|
static const char DebugArangesSecRaw[12 + 1] =
|
||
|
"\xf0\xff\xff\xff"; // Reserved unit length value
|
||
|
ExpectExtractError(DebugArangesSecRaw,
|
||
|
"parsing address ranges table at offset 0x0: unsupported "
|
||
|
"reserved unit length of value 0xfffffff0");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, SectionTooShort) {
|
||
|
// Note: 1 will be automatically subtracted in ExpectExtractError().
|
||
|
static const char DebugArangesSecRaw[11 + 1] = {0};
|
||
|
ExpectExtractError(DebugArangesSecRaw,
|
||
|
"parsing address ranges table at offset 0x0: unexpected "
|
||
|
"end of data at offset 0xb while reading [0xb, 0xc)");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, SectionTooShortDWARF64) {
|
||
|
// Note: 1 will be automatically subtracted in ExpectExtractError().
|
||
|
static const char DebugArangesSecRaw[23 + 1] =
|
||
|
"\xff\xff\xff\xff"; // DWARF64 mark
|
||
|
ExpectExtractError(DebugArangesSecRaw,
|
||
|
"parsing address ranges table at offset 0x0: unexpected "
|
||
|
"end of data at offset 0x17 while reading [0x17, 0x18)");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, NoSpaceForEntries) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x0c\x00\x00\x00" // Length
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
"\x00\x00\x00\x00" // Padding
|
||
|
; // No entries
|
||
|
ExpectExtractError(
|
||
|
DebugArangesSecRaw,
|
||
|
"address range table at offset 0x0 has an insufficient length "
|
||
|
"to contain any entries");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, UnevenLength) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x1b\x00\x00\x00" // Length (not a multiple of tuple size)
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
"\x00\x00\x00\x00" // Padding
|
||
|
"\x00\x00\x00\x00" // Entry: Address
|
||
|
"\x01\x00\x00\x00" // Length
|
||
|
"\x00\x00\x00\x00" // Termination tuple
|
||
|
"\x00\x00\x00\x00";
|
||
|
ExpectExtractError(
|
||
|
DebugArangesSecRaw,
|
||
|
"address range table at offset 0x0 has length that is not a multiple "
|
||
|
"of the tuple size");
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, ZeroAddressEntry) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x1c\x00\x00\x00" // Length
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
"\x00\x00\x00\x00" // Padding
|
||
|
"\x00\x00\x00\x00" // Entry1: Address
|
||
|
"\x01\x00\x00\x00" // Length
|
||
|
"\x00\x00\x00\x00" // Termination tuple
|
||
|
"\x00\x00\x00\x00";
|
||
|
DWARFDataExtractor Extractor(
|
||
|
StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
|
||
|
/*IsLittleEndian=*/true,
|
||
|
/*AddressSize=*/4);
|
||
|
DWARFDebugArangeSet Set;
|
||
|
uint64_t Offset = 0;
|
||
|
ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),
|
||
|
Succeeded());
|
||
|
auto Range = Set.descriptors();
|
||
|
auto Iter = Range.begin();
|
||
|
ASSERT_EQ(std::distance(Iter, Range.end()), 1);
|
||
|
EXPECT_EQ(Iter->Address, 0u);
|
||
|
EXPECT_EQ(Iter->Length, 1u);
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangeSet, ZeroLengthEntry) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x1c\x00\x00\x00" // Length
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
"\x00\x00\x00\x00" // Padding
|
||
|
"\x01\x00\x00\x00" // Entry1: Address
|
||
|
"\x00\x00\x00\x00" // Length
|
||
|
"\x00\x00\x00\x00" // Termination tuple
|
||
|
"\x00\x00\x00\x00";
|
||
|
DWARFDataExtractor Extractor(
|
||
|
StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
|
||
|
/*IsLittleEndian=*/true,
|
||
|
/*AddressSize=*/4);
|
||
|
DWARFDebugArangeSet Set;
|
||
|
uint64_t Offset = 0;
|
||
|
ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),
|
||
|
Succeeded());
|
||
|
auto Range = Set.descriptors();
|
||
|
auto Iter = Range.begin();
|
||
|
ASSERT_EQ(std::distance(Iter, Range.end()), 1);
|
||
|
EXPECT_EQ(Iter->Address, 1u);
|
||
|
EXPECT_EQ(Iter->Length, 0u);
|
||
|
}
|
||
|
|
||
|
TEST(DWARFDebugArangesSet, PrematureTerminator) {
|
||
|
static const char DebugArangesSecRaw[] =
|
||
|
"\x24\x00\x00\x00" // Length
|
||
|
"\x02\x00" // Version
|
||
|
"\x00\x00\x00\x00" // Debug Info Offset
|
||
|
"\x04" // Address Size
|
||
|
"\x00" // Segment Selector Size
|
||
|
"\x00\x00\x00\x00" // Padding
|
||
|
"\x00\x00\x00\x00" // Entry1: Premature
|
||
|
"\x00\x00\x00\x00" // terminator
|
||
|
"\x01\x00\x00\x00" // Entry2: Address
|
||
|
"\x01\x00\x00\x00" // Length
|
||
|
"\x00\x00\x00\x00" // Termination tuple
|
||
|
"\x00\x00\x00\x00";
|
||
|
DWARFDataExtractor Extractor(
|
||
|
StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
|
||
|
/*IsLittleEndian=*/true,
|
||
|
/*AddressSize=*/4);
|
||
|
DWARFDebugArangeSet Set;
|
||
|
uint64_t Offset = 0;
|
||
|
WarningHandler Warnings;
|
||
|
ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, Warnings), Succeeded());
|
||
|
auto Range = Set.descriptors();
|
||
|
auto Iter = Range.begin();
|
||
|
ASSERT_EQ(std::distance(Iter, Range.end()), 2);
|
||
|
EXPECT_EQ(Iter->Address, 0u);
|
||
|
EXPECT_EQ(Iter->Length, 0u);
|
||
|
++Iter;
|
||
|
EXPECT_EQ(Iter->Address, 1u);
|
||
|
EXPECT_EQ(Iter->Length, 1u);
|
||
|
EXPECT_THAT_ERROR(
|
||
|
Warnings.getWarning(),
|
||
|
FailedWithMessage("address range table at offset 0x0 has a premature "
|
||
|
"terminator entry at offset 0x10"));
|
||
|
}
|
||
|
|
||
|
} // end anonymous namespace
|