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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" 10 #include "llvm/Testing/Support/Error.h" 11 #include "gtest/gtest.h" 12 13 using namespace llvm; 14 15 namespace { 16 17 struct WarningHandler { 18 ~WarningHandler() { EXPECT_THAT_ERROR(std::move(Err), Succeeded()); } 19 20 void operator()(Error E) { Err = joinErrors(std::move(Err), std::move(E)); } 21 22 Error getWarning() { return std::move(Err); } 23 24 Error Err = Error::success(); 25 }; 26 27 template <size_t SecSize> 28 void ExpectExtractError(const char (&SecDataRaw)[SecSize], 29 const char *ErrorMessage) { 30 DWARFDataExtractor Extractor(StringRef(SecDataRaw, SecSize - 1), 31 /* IsLittleEndian = */ true, 32 /* AddressSize = */ 4); 33 DWARFDebugArangeSet Set; 34 uint64_t Offset = 0; 35 WarningHandler Warnings; 36 Error E = Set.extract(Extractor, &Offset, Warnings); 37 ASSERT_TRUE(E.operator bool()); 38 EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str()); 39 } 40 41 TEST(DWARFDebugArangeSet, LengthExceedsSectionSize) { 42 static const char DebugArangesSecRaw[] = 43 "\x15\x00\x00\x00" // The length exceeds the section boundaries 44 "\x02\x00" // Version 45 "\x00\x00\x00\x00" // Debug Info Offset 46 "\x04" // Address Size 47 "\x00" // Segment Selector Size 48 "\x00\x00\x00\x00" // Padding 49 "\x00\x00\x00\x00" // Termination tuple 50 "\x00\x00\x00\x00"; 51 ExpectExtractError( 52 DebugArangesSecRaw, 53 "the length of address range table at offset 0x0 exceeds section size"); 54 } 55 56 TEST(DWARFDebugArangeSet, LengthExceedsSectionSizeDWARF64) { 57 static const char DebugArangesSecRaw[] = 58 "\xff\xff\xff\xff" // DWARF64 mark 59 "\x15\x00\x00\x00\x00\x00\x00\x00" // The length exceeds the section 60 // boundaries 61 "\x02\x00" // Version 62 "\x00\x00\x00\x00\x00\x00\x00\x00" // Debug Info Offset 63 "\x04" // Address Size 64 "\x00" // Segment Selector Size 65 // No padding 66 "\x00\x00\x00\x00" // Termination tuple 67 "\x00\x00\x00\x00"; 68 ExpectExtractError( 69 DebugArangesSecRaw, 70 "the length of address range table at offset 0x0 exceeds section size"); 71 } 72 73 TEST(DWARFDebugArangeSet, UnsupportedAddressSize) { 74 static const char DebugArangesSecRaw[] = 75 "\x0c\x00\x00\x00" // Length 76 "\x02\x00" // Version 77 "\x00\x00\x00\x00" // Debug Info Offset 78 "\x03" // Address Size (not supported) 79 "\x00" // Segment Selector Size 80 // No padding 81 "\x00\x00\x00\x00"; // Termination tuple 82 ExpectExtractError( 83 DebugArangesSecRaw, 84 "address range table at offset 0x0 has unsupported address size: 3 " 85 "(supported are 2, 4, 8)"); 86 } 87 88 TEST(DWARFDebugArangeSet, UnsupportedSegmentSelectorSize) { 89 static const char DebugArangesSecRaw[] = 90 "\x14\x00\x00\x00" // Length 91 "\x02\x00" // Version 92 "\x00\x00\x00\x00" // Debug Info Offset 93 "\x04" // Address Size 94 "\x04" // Segment Selector Size (not supported) 95 // No padding 96 "\x00\x00\x00\x00" // Termination tuple 97 "\x00\x00\x00\x00" 98 "\x00\x00\x00\x00"; 99 ExpectExtractError( 100 DebugArangesSecRaw, 101 "non-zero segment selector size in address range table at offset 0x0 " 102 "is not supported"); 103 } 104 105 TEST(DWARFDebugArangeSet, NoTerminationEntry) { 106 static const char DebugArangesSecRaw[] = 107 "\x14\x00\x00\x00" // Length 108 "\x02\x00" // Version 109 "\x00\x00\x00\x00" // Debug Info Offset 110 "\x04" // Address Size 111 "\x00" // Segment Selector Size 112 "\x00\x00\x00\x00" // Padding 113 "\x00\x00\x00\x00" // Entry: Address 114 "\x01\x00\x00\x00" // Length 115 ; // No termination tuple 116 ExpectExtractError( 117 DebugArangesSecRaw, 118 "address range table at offset 0x0 is not terminated by null entry"); 119 } 120 121 TEST(DWARFDebugArangeSet, ReservedUnitLength) { 122 // Note: 12 is the minimum length to pass the basic check for the size of 123 // the section. 1 will be automatically subtracted in ExpectExtractError(). 124 static const char DebugArangesSecRaw[12 + 1] = 125 "\xf0\xff\xff\xff"; // Reserved unit length value 126 ExpectExtractError(DebugArangesSecRaw, 127 "parsing address ranges table at offset 0x0: unsupported " 128 "reserved unit length of value 0xfffffff0"); 129 } 130 131 TEST(DWARFDebugArangeSet, SectionTooShort) { 132 // Note: 1 will be automatically subtracted in ExpectExtractError(). 133 static const char DebugArangesSecRaw[11 + 1] = {0}; 134 ExpectExtractError(DebugArangesSecRaw, 135 "parsing address ranges table at offset 0x0: unexpected " 136 "end of data at offset 0xb while reading [0xb, 0xc)"); 137 } 138 139 TEST(DWARFDebugArangeSet, SectionTooShortDWARF64) { 140 // Note: 1 will be automatically subtracted in ExpectExtractError(). 141 static const char DebugArangesSecRaw[23 + 1] = 142 "\xff\xff\xff\xff"; // DWARF64 mark 143 ExpectExtractError(DebugArangesSecRaw, 144 "parsing address ranges table at offset 0x0: unexpected " 145 "end of data at offset 0x17 while reading [0x17, 0x18)"); 146 } 147 148 TEST(DWARFDebugArangeSet, NoSpaceForEntries) { 149 static const char DebugArangesSecRaw[] = 150 "\x0c\x00\x00\x00" // Length 151 "\x02\x00" // Version 152 "\x00\x00\x00\x00" // Debug Info Offset 153 "\x04" // Address Size 154 "\x00" // Segment Selector Size 155 "\x00\x00\x00\x00" // Padding 156 ; // No entries 157 ExpectExtractError( 158 DebugArangesSecRaw, 159 "address range table at offset 0x0 has an insufficient length " 160 "to contain any entries"); 161 } 162 163 TEST(DWARFDebugArangeSet, UnevenLength) { 164 static const char DebugArangesSecRaw[] = 165 "\x1b\x00\x00\x00" // Length (not a multiple of tuple size) 166 "\x02\x00" // Version 167 "\x00\x00\x00\x00" // Debug Info Offset 168 "\x04" // Address Size 169 "\x00" // Segment Selector Size 170 "\x00\x00\x00\x00" // Padding 171 "\x00\x00\x00\x00" // Entry: Address 172 "\x01\x00\x00\x00" // Length 173 "\x00\x00\x00\x00" // Termination tuple 174 "\x00\x00\x00\x00"; 175 ExpectExtractError( 176 DebugArangesSecRaw, 177 "address range table at offset 0x0 has length that is not a multiple " 178 "of the tuple size"); 179 } 180 181 TEST(DWARFDebugArangeSet, ZeroAddressEntry) { 182 static const char DebugArangesSecRaw[] = 183 "\x1c\x00\x00\x00" // Length 184 "\x02\x00" // Version 185 "\x00\x00\x00\x00" // Debug Info Offset 186 "\x04" // Address Size 187 "\x00" // Segment Selector Size 188 "\x00\x00\x00\x00" // Padding 189 "\x00\x00\x00\x00" // Entry1: Address 190 "\x01\x00\x00\x00" // Length 191 "\x00\x00\x00\x00" // Termination tuple 192 "\x00\x00\x00\x00"; 193 DWARFDataExtractor Extractor( 194 StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1), 195 /*IsLittleEndian=*/true, 196 /*AddressSize=*/4); 197 DWARFDebugArangeSet Set; 198 uint64_t Offset = 0; 199 ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()), 200 Succeeded()); 201 auto Range = Set.descriptors(); 202 auto Iter = Range.begin(); 203 ASSERT_EQ(std::distance(Iter, Range.end()), 1); 204 EXPECT_EQ(Iter->Address, 0u); 205 EXPECT_EQ(Iter->Length, 1u); 206 } 207 208 TEST(DWARFDebugArangeSet, ZeroLengthEntry) { 209 static const char DebugArangesSecRaw[] = 210 "\x1c\x00\x00\x00" // Length 211 "\x02\x00" // Version 212 "\x00\x00\x00\x00" // Debug Info Offset 213 "\x04" // Address Size 214 "\x00" // Segment Selector Size 215 "\x00\x00\x00\x00" // Padding 216 "\x01\x00\x00\x00" // Entry1: Address 217 "\x00\x00\x00\x00" // Length 218 "\x00\x00\x00\x00" // Termination tuple 219 "\x00\x00\x00\x00"; 220 DWARFDataExtractor Extractor( 221 StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1), 222 /*IsLittleEndian=*/true, 223 /*AddressSize=*/4); 224 DWARFDebugArangeSet Set; 225 uint64_t Offset = 0; 226 ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()), 227 Succeeded()); 228 auto Range = Set.descriptors(); 229 auto Iter = Range.begin(); 230 ASSERT_EQ(std::distance(Iter, Range.end()), 1); 231 EXPECT_EQ(Iter->Address, 1u); 232 EXPECT_EQ(Iter->Length, 0u); 233 } 234 235 TEST(DWARFDebugArangesSet, PrematureTerminator) { 236 static const char DebugArangesSecRaw[] = 237 "\x24\x00\x00\x00" // Length 238 "\x02\x00" // Version 239 "\x00\x00\x00\x00" // Debug Info Offset 240 "\x04" // Address Size 241 "\x00" // Segment Selector Size 242 "\x00\x00\x00\x00" // Padding 243 "\x00\x00\x00\x00" // Entry1: Premature 244 "\x00\x00\x00\x00" // terminator 245 "\x01\x00\x00\x00" // Entry2: Address 246 "\x01\x00\x00\x00" // Length 247 "\x00\x00\x00\x00" // Termination tuple 248 "\x00\x00\x00\x00"; 249 DWARFDataExtractor Extractor( 250 StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1), 251 /*IsLittleEndian=*/true, 252 /*AddressSize=*/4); 253 DWARFDebugArangeSet Set; 254 uint64_t Offset = 0; 255 WarningHandler Warnings; 256 ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, Warnings), Succeeded()); 257 auto Range = Set.descriptors(); 258 auto Iter = Range.begin(); 259 ASSERT_EQ(std::distance(Iter, Range.end()), 2); 260 EXPECT_EQ(Iter->Address, 0u); 261 EXPECT_EQ(Iter->Length, 0u); 262 ++Iter; 263 EXPECT_EQ(Iter->Address, 1u); 264 EXPECT_EQ(Iter->Length, 1u); 265 EXPECT_THAT_ERROR( 266 Warnings.getWarning(), 267 FailedWithMessage("address range table at offset 0x0 has a premature " 268 "terminator entry at offset 0x10")); 269 } 270 271 } // end anonymous namespace 272