273 lines · cpp
1//===- llvm/unittest/DebugInfo/DWARFDebugArangeSetTest.cpp-----------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"10#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"11#include "llvm/Testing/Support/Error.h"12#include "gtest/gtest.h"13 14using namespace llvm;15 16namespace {17 18struct WarningHandler {19 ~WarningHandler() { EXPECT_THAT_ERROR(std::move(Err), Succeeded()); }20 21 void operator()(Error E) { Err = joinErrors(std::move(Err), std::move(E)); }22 23 Error getWarning() { return std::move(Err); }24 25 Error Err = Error::success();26};27 28template <size_t SecSize>29void ExpectExtractError(const char (&SecDataRaw)[SecSize],30 const char *ErrorMessage) {31 DWARFDataExtractor Extractor(StringRef(SecDataRaw, SecSize - 1),32 /* IsLittleEndian = */ true,33 /* AddressSize = */ 4);34 DWARFDebugArangeSet Set;35 uint64_t Offset = 0;36 WarningHandler Warnings;37 Error E = Set.extract(Extractor, &Offset, Warnings);38 ASSERT_TRUE(E.operator bool());39 EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str());40}41 42TEST(DWARFDebugArangeSet, LengthExceedsSectionSize) {43 static const char DebugArangesSecRaw[] =44 "\x15\x00\x00\x00" // The length exceeds the section boundaries45 "\x02\x00" // Version46 "\x00\x00\x00\x00" // Debug Info Offset47 "\x04" // Address Size48 "\x00" // Segment Selector Size49 "\x00\x00\x00\x00" // Padding50 "\x00\x00\x00\x00" // Termination tuple51 "\x00\x00\x00\x00";52 ExpectExtractError(53 DebugArangesSecRaw,54 "the length of address range table at offset 0x0 exceeds section size");55}56 57TEST(DWARFDebugArangeSet, LengthExceedsSectionSizeDWARF64) {58 static const char DebugArangesSecRaw[] =59 "\xff\xff\xff\xff" // DWARF64 mark60 "\x15\x00\x00\x00\x00\x00\x00\x00" // The length exceeds the section61 // boundaries62 "\x02\x00" // Version63 "\x00\x00\x00\x00\x00\x00\x00\x00" // Debug Info Offset64 "\x04" // Address Size65 "\x00" // Segment Selector Size66 // No padding67 "\x00\x00\x00\x00" // Termination tuple68 "\x00\x00\x00\x00";69 ExpectExtractError(70 DebugArangesSecRaw,71 "the length of address range table at offset 0x0 exceeds section size");72}73 74TEST(DWARFDebugArangeSet, UnsupportedAddressSize) {75 static const char DebugArangesSecRaw[] =76 "\x0c\x00\x00\x00" // Length77 "\x02\x00" // Version78 "\x00\x00\x00\x00" // Debug Info Offset79 "\x03" // Address Size (not supported)80 "\x00" // Segment Selector Size81 // No padding82 "\x00\x00\x00\x00"; // Termination tuple83 ExpectExtractError(84 DebugArangesSecRaw,85 "address range table at offset 0x0 has unsupported address size: 3 "86 "(supported are 2, 4, 8)");87}88 89TEST(DWARFDebugArangeSet, UnsupportedSegmentSelectorSize) {90 static const char DebugArangesSecRaw[] =91 "\x14\x00\x00\x00" // Length92 "\x02\x00" // Version93 "\x00\x00\x00\x00" // Debug Info Offset94 "\x04" // Address Size95 "\x04" // Segment Selector Size (not supported)96 // No padding97 "\x00\x00\x00\x00" // Termination tuple98 "\x00\x00\x00\x00"99 "\x00\x00\x00\x00";100 ExpectExtractError(101 DebugArangesSecRaw,102 "non-zero segment selector size in address range table at offset 0x0 "103 "is not supported");104}105 106TEST(DWARFDebugArangeSet, NoTerminationEntry) {107 static const char DebugArangesSecRaw[] =108 "\x14\x00\x00\x00" // Length109 "\x02\x00" // Version110 "\x00\x00\x00\x00" // Debug Info Offset111 "\x04" // Address Size112 "\x00" // Segment Selector Size113 "\x00\x00\x00\x00" // Padding114 "\x00\x00\x00\x00" // Entry: Address115 "\x01\x00\x00\x00" // Length116 ; // No termination tuple117 ExpectExtractError(118 DebugArangesSecRaw,119 "address range table at offset 0x0 is not terminated by null entry");120}121 122TEST(DWARFDebugArangeSet, ReservedUnitLength) {123 // Note: 12 is the minimum length to pass the basic check for the size of124 // the section. 1 will be automatically subtracted in ExpectExtractError().125 static const char DebugArangesSecRaw[12 + 1] =126 "\xf0\xff\xff\xff"; // Reserved unit length value127 ExpectExtractError(DebugArangesSecRaw,128 "parsing address ranges table at offset 0x0: unsupported "129 "reserved unit length of value 0xfffffff0");130}131 132TEST(DWARFDebugArangeSet, SectionTooShort) {133 // Note: 1 will be automatically subtracted in ExpectExtractError().134 static const char DebugArangesSecRaw[11 + 1] = {0};135 ExpectExtractError(DebugArangesSecRaw,136 "parsing address ranges table at offset 0x0: unexpected "137 "end of data at offset 0xb while reading [0xb, 0xc)");138}139 140TEST(DWARFDebugArangeSet, SectionTooShortDWARF64) {141 // Note: 1 will be automatically subtracted in ExpectExtractError().142 static const char DebugArangesSecRaw[23 + 1] =143 "\xff\xff\xff\xff"; // DWARF64 mark144 ExpectExtractError(DebugArangesSecRaw,145 "parsing address ranges table at offset 0x0: unexpected "146 "end of data at offset 0x17 while reading [0x17, 0x18)");147}148 149TEST(DWARFDebugArangeSet, NoSpaceForEntries) {150 static const char DebugArangesSecRaw[] =151 "\x0c\x00\x00\x00" // Length152 "\x02\x00" // Version153 "\x00\x00\x00\x00" // Debug Info Offset154 "\x04" // Address Size155 "\x00" // Segment Selector Size156 "\x00\x00\x00\x00" // Padding157 ; // No entries158 ExpectExtractError(159 DebugArangesSecRaw,160 "address range table at offset 0x0 has an insufficient length "161 "to contain any entries");162}163 164TEST(DWARFDebugArangeSet, UnevenLength) {165 static const char DebugArangesSecRaw[] =166 "\x1b\x00\x00\x00" // Length (not a multiple of tuple size)167 "\x02\x00" // Version168 "\x00\x00\x00\x00" // Debug Info Offset169 "\x04" // Address Size170 "\x00" // Segment Selector Size171 "\x00\x00\x00\x00" // Padding172 "\x00\x00\x00\x00" // Entry: Address173 "\x01\x00\x00\x00" // Length174 "\x00\x00\x00\x00" // Termination tuple175 "\x00\x00\x00\x00";176 ExpectExtractError(177 DebugArangesSecRaw,178 "address range table at offset 0x0 has length that is not a multiple "179 "of the tuple size");180}181 182TEST(DWARFDebugArangeSet, ZeroAddressEntry) {183 static const char DebugArangesSecRaw[] =184 "\x1c\x00\x00\x00" // Length185 "\x02\x00" // Version186 "\x00\x00\x00\x00" // Debug Info Offset187 "\x04" // Address Size188 "\x00" // Segment Selector Size189 "\x00\x00\x00\x00" // Padding190 "\x00\x00\x00\x00" // Entry1: Address191 "\x01\x00\x00\x00" // Length192 "\x00\x00\x00\x00" // Termination tuple193 "\x00\x00\x00\x00";194 DWARFDataExtractor Extractor(195 StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),196 /*IsLittleEndian=*/true,197 /*AddressSize=*/4);198 DWARFDebugArangeSet Set;199 uint64_t Offset = 0;200 ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),201 Succeeded());202 auto Range = Set.descriptors();203 auto Iter = Range.begin();204 ASSERT_EQ(std::distance(Iter, Range.end()), 1);205 EXPECT_EQ(Iter->Address, 0u);206 EXPECT_EQ(Iter->Length, 1u);207}208 209TEST(DWARFDebugArangeSet, ZeroLengthEntry) {210 static const char DebugArangesSecRaw[] =211 "\x1c\x00\x00\x00" // Length212 "\x02\x00" // Version213 "\x00\x00\x00\x00" // Debug Info Offset214 "\x04" // Address Size215 "\x00" // Segment Selector Size216 "\x00\x00\x00\x00" // Padding217 "\x01\x00\x00\x00" // Entry1: Address218 "\x00\x00\x00\x00" // Length219 "\x00\x00\x00\x00" // Termination tuple220 "\x00\x00\x00\x00";221 DWARFDataExtractor Extractor(222 StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),223 /*IsLittleEndian=*/true,224 /*AddressSize=*/4);225 DWARFDebugArangeSet Set;226 uint64_t Offset = 0;227 ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),228 Succeeded());229 auto Range = Set.descriptors();230 auto Iter = Range.begin();231 ASSERT_EQ(std::distance(Iter, Range.end()), 1);232 EXPECT_EQ(Iter->Address, 1u);233 EXPECT_EQ(Iter->Length, 0u);234}235 236TEST(DWARFDebugArangesSet, PrematureTerminator) {237 static const char DebugArangesSecRaw[] =238 "\x24\x00\x00\x00" // Length239 "\x02\x00" // Version240 "\x00\x00\x00\x00" // Debug Info Offset241 "\x04" // Address Size242 "\x00" // Segment Selector Size243 "\x00\x00\x00\x00" // Padding244 "\x00\x00\x00\x00" // Entry1: Premature245 "\x00\x00\x00\x00" // terminator246 "\x01\x00\x00\x00" // Entry2: Address247 "\x01\x00\x00\x00" // Length248 "\x00\x00\x00\x00" // Termination tuple249 "\x00\x00\x00\x00";250 DWARFDataExtractor Extractor(251 StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),252 /*IsLittleEndian=*/true,253 /*AddressSize=*/4);254 DWARFDebugArangeSet Set;255 uint64_t Offset = 0;256 WarningHandler Warnings;257 ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, Warnings), Succeeded());258 auto Range = Set.descriptors();259 auto Iter = Range.begin();260 ASSERT_EQ(std::distance(Iter, Range.end()), 2);261 EXPECT_EQ(Iter->Address, 0u);262 EXPECT_EQ(Iter->Length, 0u);263 ++Iter;264 EXPECT_EQ(Iter->Address, 1u);265 EXPECT_EQ(Iter->Length, 1u);266 EXPECT_THAT_ERROR(267 Warnings.getWarning(),268 FailedWithMessage("address range table at offset 0x0 has a premature "269 "terminator entry at offset 0x10"));270}271 272} // end anonymous namespace273