llvm.org GIT mirror llvm / 2e42fb2
[dwarfdump] Add DWARF verifiers for address ranges This patch started as an attempt to rebase Greg's differential (D32821). The result is both quite similar and different at the same time. It adds the following checks: - Verify that all address ranges in a DIE are valid. - Verify that no ranges within the DIE overlap. - Verify that no ranges overlap with the ranges of a sibling. - Verify that children are completely contained in its (direct) parent's address range. (unless both are subprograms) Differential revision: https://reviews.llvm.org/D37696 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313250 91177308-0d34-0410-b5e6-96231b3b80d8 Jonas Devlieghere 2 years ago
5 changed file(s) with 881 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
2424 uint64_t LowPC;
2525 uint64_t HighPC;
2626 uint64_t SectionIndex;
27
28 DWARFAddressRange() = default;
29
30 /// Used for unit testing.
31 DWARFAddressRange(uint64_t LowPC, uint64_t HighPC, uint64_t SectionIndex = 0)
32 : LowPC(LowPC), HighPC(HighPC), SectionIndex(SectionIndex) {}
33
34 /// Returns true if LowPC is smaller or equal to HighPC. This accounts for
35 /// dead-stripped ranges.
36 bool valid() const { return LowPC <= HighPC; }
37
38 /// Returns true if [LowPC, HighPC) intersects with [RHS.LowPC, RHS.HighPC).
39 bool intersects(const DWARFAddressRange &RHS) const {
40 // Empty ranges can't intersect.
41 if (LowPC == HighPC || RHS.LowPC == RHS.HighPC)
42 return false;
43 return (LowPC < RHS.HighPC) && (HighPC > RHS.LowPC);
44 }
45
46 /// Returns true if [LowPC, HighPC) fully contains [RHS.LowPC, RHS.HighPC).
47 bool contains(const DWARFAddressRange &RHS) const {
48 if (LowPC <= RHS.LowPC && RHS.LowPC <= HighPC)
49 return LowPC <= RHS.HighPC && RHS.HighPC <= HighPC;
50 return false;
51 }
2752 };
53
54 static inline bool operator<(const DWARFAddressRange &LHS,
55 const DWARFAddressRange &RHS) {
56 return std::tie(LHS.LowPC, LHS.HighPC) < std::tie(RHS.LowPC, RHS.HighPC);
57 }
2858
2959 /// DWARFAddressRangesVector - represents a set of absolute address ranges.
3060 using DWARFAddressRangesVector = std::vector;
307307 return !(LHS == RHS);
308308 }
309309
310 inline bool operator<(const DWARFDie &LHS, const DWARFDie &RHS) {
311 return LHS.getOffset() < RHS.getOffset();
312 }
313
310314 class DWARFDie::iterator : public iterator_facade_base
311315 std::forward_iterator_tag,
312316 const DWARFDie> {
1010 #define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
1111
1212 #include "llvm/DebugInfo/DIContext.h"
13 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
1315
1416 #include
1517 #include
2931
3032 /// A class that verifies DWARF debug information given a DWARF Context.
3133 class DWARFVerifier {
34 public:
35 /// A class that keeps the address range information for a single DIE.
36 struct DieRangeInfo {
37 DWARFDie Die;
38
39 /// Sorted DWARFAddressRanges.
40 std::vector Ranges;
41
42 /// Sorted DWARFAddressRangeInfo.
43 std::set Children;
44
45 DieRangeInfo() = default;
46 DieRangeInfo(DWARFDie Die) : Die(Die) {}
47
48 /// Used for unit testing.
49 DieRangeInfo(std::vector Ranges)
50 : Ranges(std::move(Ranges)) {}
51
52 typedef std::vector::const_iterator
53 address_range_iterator;
54 typedef std::set::const_iterator die_range_info_iterator;
55
56 /// Inserts the address range. If the range overlaps with an existing
57 /// range, the range is *not* added and an iterator to the overlapping
58 /// range is returned.
59 ///
60 /// This is used for finding overlapping ranges within the same DIE.
61 address_range_iterator insert(const DWARFAddressRange &R);
62
63 /// Finds an address range in the sorted vector of ranges.
64 address_range_iterator findRange(const DWARFAddressRange &R) const {
65 const auto Begin = Ranges.cbegin();
66 const auto End = Ranges.cend();
67 auto Iter = std::upper_bound(Begin, End, R);
68 if (Iter != Begin)
69 --Iter;
70 return Iter;
71 }
72
73 /// Inserts the address range info. If any of its ranges overlaps with a
74 /// range in an existing range info, the range info is *not* added and an
75 /// iterator to the overlapping range info.
76 ///
77 /// This is used for finding overlapping children of the same DIE.
78 die_range_info_iterator insert(const DieRangeInfo &RI);
79
80 /// Return true if ranges in this object contains all ranges within RHS.
81 bool contains(const DieRangeInfo &RHS) const;
82
83 /// Return true if any range in this object intersects with any range in
84 /// RHS.
85 bool intersects(const DieRangeInfo &RHS) const;
86 };
87
88 private:
3289 raw_ostream &OS;
3390 DWARFContext &DCtx;
3491 DIDumpOptions DumpOpts;
83140 /// - cases in which lowPC >= highPC
84141 ///
85142 /// \returns Number of errors that occured during verification.
86 unsigned verifyDieRanges(const DWARFDie &Die);
143 unsigned verifyDieRanges(const DWARFDie &Die, DieRangeInfo &ParentRI);
87144
88145 /// Verifies the attribute's DWARF attribute and its value.
89146 ///
195252 bool handleAccelTables();
196253 };
197254
255 static inline bool operator<(const DWARFVerifier::DieRangeInfo &LHS,
256 const DWARFVerifier::DieRangeInfo &RHS) {
257 return std::tie(LHS.Ranges, LHS.Die) < std::tie(RHS.Ranges, RHS.Die);
258 }
259
198260 } // end namespace llvm
199261
200262 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
2222 using namespace llvm;
2323 using namespace dwarf;
2424 using namespace object;
25
26 DWARFVerifier::DieRangeInfo::address_range_iterator
27 DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
28 const auto Begin = Ranges.cbegin();
29 const auto End = Ranges.cend();
30 auto Pos = std::lower_bound(Begin, End, R);
31
32 if (Pos != End) {
33 if (Pos->intersects(R))
34 return Pos;
35 if (Pos != Begin) {
36 auto Iter = Pos - 1;
37 if (Iter->intersects(R))
38 return Iter;
39 }
40 }
41
42 Ranges.insert(Pos, R);
43 return Ranges.cend();
44 }
45
46 DWARFVerifier::DieRangeInfo::die_range_info_iterator
47 DWARFVerifier::DieRangeInfo::insert(const DieRangeInfo &RI) {
48 const auto End = Children.end();
49 auto Iter = Children.begin();
50 while (Iter != End) {
51 if (Iter->intersects(RI))
52 return Iter;
53 ++Iter;
54 }
55 Children.insert(RI);
56 return Children.cend();
57 }
58
59 bool DWARFVerifier::DieRangeInfo::contains(const DieRangeInfo &RHS) const {
60 // Both list of ranges are sorted so we can make this fast.
61
62 if (Ranges.empty() || RHS.Ranges.empty())
63 return false;
64
65 // Since the ranges are sorted we can advance where we start searching with
66 // this object's ranges as we traverse RHS.Ranges.
67 const auto End = Ranges.cend();
68 auto Iter = findRange(RHS.Ranges.front());
69
70 // Now linearly walk the ranges in this object and see if they contain each
71 // ranges from RHS.Ranges.
72 for (const auto &R : RHS.Ranges) {
73 while (Iter != End) {
74 if (Iter->contains(R))
75 break;
76 ++Iter;
77 }
78 if (Iter == End)
79 return false;
80 }
81 return true;
82 }
83
84 bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
85 if (Ranges.empty() || RHS.Ranges.empty())
86 return false;
87
88 const auto End = Ranges.end();
89 auto Iter = findRange(RHS.Ranges.front());
90 for (const auto &R : RHS.Ranges) {
91 if (R.HighPC <= Iter->LowPC)
92 continue;
93 while (Iter != End) {
94 if (Iter->intersects(R))
95 return true;
96 ++Iter;
97 }
98 }
99
100 return false;
101 }
25102
26103 bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
27104 uint32_t *Offset, unsigned UnitIndex,
93170 auto Die = Unit.getDIEAtIndex(I);
94171 if (Die.getTag() == DW_TAG_null)
95172 continue;
96 NumUnitErrors += verifyDieRanges(Die);
97173 for (auto AttrValue : Die.attributes()) {
98174 NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
99175 NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
100176 }
101177 }
178
179 DieRangeInfo RI;
180 DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
181 NumUnitErrors += verifyDieRanges(Die, RI);
102182 return NumUnitErrors == 0;
103183 }
104184
209289 return (isHeaderChainValid && NumDebugInfoErrors == 0);
210290 }
211291
212 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die) {
292 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
293 DieRangeInfo &ParentRI) {
213294 unsigned NumErrors = 0;
214 for (auto Range : Die.getAddressRanges()) {
215 if (Range.LowPC >= Range.HighPC) {
295
296 if (!Die.isValid())
297 return NumErrors;
298
299 DWARFAddressRangesVector Ranges = Die.getAddressRanges();
300
301 // Build RI for this DIE and check that ranges within this DIE do not
302 // overlap.
303 DieRangeInfo RI(Die);
304 for (auto Range : Ranges) {
305 if (!Range.valid()) {
216306 ++NumErrors;
217307 OS << format("error: Invalid address range [0x%08" PRIx64
218308 " - 0x%08" PRIx64 "].\n",
219309 Range.LowPC, Range.HighPC);
220 }
221 }
310 continue;
311 }
312
313 // Verify that ranges don't intersect.
314 const auto IntersectingRange = RI.insert(Range);
315 if (IntersectingRange != RI.Ranges.cend()) {
316 ++NumErrors;
317 OS << format("error: DIE has overlapping address ranges: [0x%08" PRIx64
318 " - 0x%08" PRIx64 "] and [0x%08" PRIx64 " - 0x%08" PRIx64
319 "].\n",
320 Range.LowPC, Range.HighPC, IntersectingRange->LowPC,
321 IntersectingRange->HighPC);
322 break;
323 }
324 }
325
326 // Verify that children don't intersect.
327 const auto IntersectingChild = ParentRI.insert(RI);
328 if (IntersectingChild != ParentRI.Children.cend()) {
329 ++NumErrors;
330 OS << "error: DIEs have overlapping address ranges:";
331 Die.dump(OS, 0);
332 IntersectingChild->Die.dump(OS, 0);
333 OS << "\n";
334 }
335
336 // Verify that ranges are contained within their parent.
337 bool ShouldBeContained = !Ranges.empty() && !ParentRI.Ranges.empty() &&
338 !(Die.getTag() == DW_TAG_subprogram &&
339 ParentRI.Die.getTag() == DW_TAG_subprogram);
340 if (ShouldBeContained && !ParentRI.contains(RI)) {
341 ++NumErrors;
342 OS << "error: DIE address ranges are not "
343 "contained in its parent's ranges:";
344 Die.dump(OS, 0);
345 ParentRI.Die.dump(OS, 0);
346 OS << "\n";
347 }
348
349 // Recursively check children.
350 for (DWARFDie Child : Die)
351 NumErrors += verifyDieRanges(Child, RI);
352
222353 return NumErrors;
223354 }
224355
1919 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
2020 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
2121 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
22 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
2223 #include "llvm/MC/MCContext.h"
2324 #include "llvm/MC/MCSectionELF.h"
2425 #include "llvm/MC/MCStreamer.h"
16711672 EXPECT_TRUE(Str.str().contains(Error));
16721673 }
16731674
1675 void VerifySuccess(DWARFContext &DwarfContext) {
1676 SmallString<1024> Str;
1677 raw_svector_ostream Strm(Str);
1678 EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All));
1679 }
1680
16741681 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) {
16751682 // Create a single compile unit with a single function that has a DW_AT_type
1676 // that is CU relative. The CU offset is not valid becuase it is larger than
1683 // that is CU relative. The CU offset is not valid because it is larger than
16771684 // the compile unit itself.
16781685
16791686 const char *yamldata = R"(
23462353 EXPECT_TRUE(Errors == 1);
23472354 }
23482355
2356 TEST(DWARFDebugInfo, TestDwarfVerifyCURangesIncomplete) {
2357 // Create a single compile unit with a single function. The compile
2358 // unit has a DW_AT_ranges attribute that doesn't fully contain the
2359 // address range of the function. The verification should fail due to
2360 // the CU ranges not containing all of the address ranges of all of the
2361 // functions.
2362 StringRef yamldata = R"(
2363 debug_str:
2364 - ''
2365 - /tmp/main.c
2366 debug_abbrev:
2367 - Code: 0x00000001
2368 Tag: DW_TAG_compile_unit
2369 Children: DW_CHILDREN_yes
2370 Attributes:
2371 - Attribute: DW_AT_low_pc
2372 Form: DW_FORM_addr
2373 - Attribute: DW_AT_high_pc
2374 Form: DW_FORM_addr
2375 - Attribute: DW_AT_name
2376 Form: DW_FORM_strp
2377 - Code: 0x00000002
2378 Tag: DW_TAG_subprogram
2379 Children: DW_CHILDREN_no
2380 Attributes:
2381 - Attribute: DW_AT_low_pc
2382 Form: DW_FORM_addr
2383 - Attribute: DW_AT_high_pc
2384 Form: DW_FORM_addr
2385 debug_info:
2386 - Length:
2387 TotalLength: 46
2388 Version: 4
2389 AbbrOffset: 0
2390 AddrSize: 8
2391 Entries:
2392 - AbbrCode: 0x00000001
2393 Values:
2394 - Value: 0x0000000000001000
2395 - Value: 0x0000000000001500
2396 - Value: 0x0000000000000001
2397 - AbbrCode: 0x00000002
2398 Values:
2399 - Value: 0x0000000000001000
2400 - Value: 0x0000000000002000
2401 - AbbrCode: 0x00000000
2402 Values:
2403 )";
2404 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2405 ASSERT_TRUE((bool)ErrOrSections);
2406 std::unique_ptr DwarfContext =
2407 DWARFContext::create(*ErrOrSections, 8);
2408 VerifyError(*DwarfContext, "error: DIE address ranges are not "
2409 "contained in its parent's ranges:");
2410 }
2411
2412 TEST(DWARFDebugInfo, TestDwarfVerifyLexicalBlockRanges) {
2413 // Create a single compile unit with a single function that has a lexical
2414 // block whose address range is not contained in the function address range.
2415 StringRef yamldata = R"(
2416 debug_str:
2417 - ''
2418 - /tmp/main.c
2419 - main
2420 debug_abbrev:
2421 - Code: 0x00000001
2422 Tag: DW_TAG_compile_unit
2423 Children: DW_CHILDREN_yes
2424 Attributes:
2425 - Attribute: DW_AT_name
2426 Form: DW_FORM_strp
2427 - Code: 0x00000002
2428 Tag: DW_TAG_subprogram
2429 Children: DW_CHILDREN_yes
2430 Attributes:
2431 - Attribute: DW_AT_name
2432 Form: DW_FORM_strp
2433 - Attribute: DW_AT_low_pc
2434 Form: DW_FORM_addr
2435 - Attribute: DW_AT_high_pc
2436 Form: DW_FORM_addr
2437 - Code: 0x00000003
2438 Tag: DW_TAG_lexical_block
2439 Children: DW_CHILDREN_no
2440 Attributes:
2441 - Attribute: DW_AT_low_pc
2442 Form: DW_FORM_addr
2443 - Attribute: DW_AT_high_pc
2444 Form: DW_FORM_addr
2445 debug_info:
2446 - Length:
2447 TotalLength: 52
2448 Version: 4
2449 AbbrOffset: 0
2450 AddrSize: 8
2451 Entries:
2452 - AbbrCode: 0x00000001
2453 Values:
2454 - Value: 0x0000000000000001
2455 - AbbrCode: 0x00000002
2456 Values:
2457 - Value: 0x000000000000000D
2458 - Value: 0x0000000000001000
2459 - Value: 0x0000000000002000
2460 - AbbrCode: 0x00000003
2461 Values:
2462 - Value: 0x0000000000001000
2463 - Value: 0x0000000000002001
2464 - AbbrCode: 0x00000000
2465 Values:
2466 - AbbrCode: 0x00000000
2467 Values:
2468 )";
2469 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2470 ASSERT_TRUE((bool)ErrOrSections);
2471 std::unique_ptr DwarfContext =
2472 DWARFContext::create(*ErrOrSections, 8);
2473 VerifyError(*DwarfContext, "error: DIE address ranges are not "
2474 "contained in its parent's ranges:");
2475 }
2476
2477 TEST(DWARFDebugInfo, TestDwarfVerifyOverlappingFunctionRanges) {
2478 // Create a single compile unit with a two functions that have overlapping
2479 // address ranges.
2480 StringRef yamldata = R"(
2481 debug_str:
2482 - ''
2483 - /tmp/main.c
2484 - main
2485 - foo
2486 debug_abbrev:
2487 - Code: 0x00000001
2488 Tag: DW_TAG_compile_unit
2489 Children: DW_CHILDREN_yes
2490 Attributes:
2491 - Attribute: DW_AT_name
2492 Form: DW_FORM_strp
2493 - Code: 0x00000002
2494 Tag: DW_TAG_subprogram
2495 Children: DW_CHILDREN_no
2496 Attributes:
2497 - Attribute: DW_AT_name
2498 Form: DW_FORM_strp
2499 - Attribute: DW_AT_low_pc
2500 Form: DW_FORM_addr
2501 - Attribute: DW_AT_high_pc
2502 Form: DW_FORM_addr
2503 debug_info:
2504 - Length:
2505 TotalLength: 55
2506 Version: 4
2507 AbbrOffset: 0
2508 AddrSize: 8
2509 Entries:
2510 - AbbrCode: 0x00000001
2511 Values:
2512 - Value: 0x0000000000000001
2513 - AbbrCode: 0x00000002
2514 Values:
2515 - Value: 0x000000000000000D
2516 - Value: 0x0000000000001000
2517 - Value: 0x0000000000002000
2518 - AbbrCode: 0x00000002
2519 Values:
2520 - Value: 0x0000000000000012
2521 - Value: 0x0000000000001FFF
2522 - Value: 0x0000000000002000
2523 - AbbrCode: 0x00000000
2524 Values:
2525 )";
2526 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2527 ASSERT_TRUE((bool)ErrOrSections);
2528 std::unique_ptr DwarfContext =
2529 DWARFContext::create(*ErrOrSections, 8);
2530 VerifyError(*DwarfContext, "error: DIEs have overlapping address ranges:");
2531 }
2532
2533 TEST(DWARFDebugInfo, TestDwarfVerifyOverlappingLexicalBlockRanges) {
2534 // Create a single compile unit with a one function that has two lexical
2535 // blocks with overlapping address ranges.
2536 StringRef yamldata = R"(
2537 debug_str:
2538 - ''
2539 - /tmp/main.c
2540 - main
2541 debug_abbrev:
2542 - Code: 0x00000001
2543 Tag: DW_TAG_compile_unit
2544 Children: DW_CHILDREN_yes
2545 Attributes:
2546 - Attribute: DW_AT_low_pc
2547 Form: DW_FORM_addr
2548 - Attribute: DW_AT_high_pc
2549 Form: DW_FORM_addr
2550 - Attribute: DW_AT_name
2551 Form: DW_FORM_strp
2552 - Code: 0x00000002
2553 Tag: DW_TAG_subprogram
2554 Children: DW_CHILDREN_yes
2555 Attributes:
2556 - Attribute: DW_AT_name
2557 Form: DW_FORM_strp
2558 - Attribute: DW_AT_low_pc
2559 Form: DW_FORM_addr
2560 - Attribute: DW_AT_high_pc
2561 Form: DW_FORM_addr
2562 - Code: 0x00000003
2563 Tag: DW_TAG_lexical_block
2564 Children: DW_CHILDREN_no
2565 Attributes:
2566 - Attribute: DW_AT_low_pc
2567 Form: DW_FORM_addr
2568 - Attribute: DW_AT_high_pc
2569 Form: DW_FORM_addr
2570 debug_info:
2571 - Length:
2572 TotalLength: 85
2573 Version: 4
2574 AbbrOffset: 0
2575 AddrSize: 8
2576 Entries:
2577 - AbbrCode: 0x00000001
2578 Values:
2579 - Value: 0x0000000000001000
2580 - Value: 0x0000000000002000
2581 - Value: 0x0000000000000001
2582 - AbbrCode: 0x00000002
2583 Values:
2584 - Value: 0x000000000000000D
2585 - Value: 0x0000000000001000
2586 - Value: 0x0000000000002000
2587 - AbbrCode: 0x00000003
2588 Values:
2589 - Value: 0x0000000000001100
2590 - Value: 0x0000000000001300
2591 - AbbrCode: 0x00000003
2592 Values:
2593 - Value: 0x00000000000012FF
2594 - Value: 0x0000000000001300
2595 - AbbrCode: 0x00000000
2596 Values:
2597 - AbbrCode: 0x00000000
2598 Values:
2599 )";
2600 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2601 ASSERT_TRUE((bool)ErrOrSections);
2602 std::unique_ptr DwarfContext =
2603 DWARFContext::create(*ErrOrSections, 8);
2604 VerifyError(*DwarfContext, "error: DIEs have overlapping address ranges:");
2605 }
2606
2607 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidDIERange) {
2608 // Create a single compile unit with a single function that has an invalid
2609 // address range where the high PC is smaller than the low PC.
2610 StringRef yamldata = R"(
2611 debug_str:
2612 - ''
2613 - /tmp/main.c
2614 - main
2615 debug_abbrev:
2616 - Code: 0x00000001
2617 Tag: DW_TAG_compile_unit
2618 Children: DW_CHILDREN_yes
2619 Attributes:
2620 - Attribute: DW_AT_name
2621 Form: DW_FORM_strp
2622 - Code: 0x00000002
2623 Tag: DW_TAG_subprogram
2624 Children: DW_CHILDREN_no
2625 Attributes:
2626 - Attribute: DW_AT_name
2627 Form: DW_FORM_strp
2628 - Attribute: DW_AT_low_pc
2629 Form: DW_FORM_addr
2630 - Attribute: DW_AT_high_pc
2631 Form: DW_FORM_addr
2632 debug_info:
2633 - Length:
2634 TotalLength: 34
2635 Version: 4
2636 AbbrOffset: 0
2637 AddrSize: 8
2638 Entries:
2639 - AbbrCode: 0x00000001
2640 Values:
2641 - Value: 0x0000000000000001
2642 - AbbrCode: 0x00000002
2643 Values:
2644 - Value: 0x000000000000000D
2645 - Value: 0x0000000000001000
2646 - Value: 0x0000000000000900
2647 - AbbrCode: 0x00000000
2648 Values:
2649 )";
2650 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2651 ASSERT_TRUE((bool)ErrOrSections);
2652 std::unique_ptr DwarfContext =
2653 DWARFContext::create(*ErrOrSections, 8);
2654 VerifyError(*DwarfContext, "error: Invalid address range");
2655 }
2656
2657 TEST(DWARFDebugInfo, TestDwarfVerifyElidedDoesntFail) {
2658 // Create a single compile unit with two functions: one that has a valid range
2659 // and one whose low and high PC are the same. When the low and high PC are
2660 // the same, this indicates the function was dead code stripped. We want to
2661 // ensure that verification succeeds.
2662 StringRef yamldata = R"(
2663 debug_str:
2664 - ''
2665 - /tmp/main.c
2666 - main
2667 - elided
2668 debug_abbrev:
2669 - Code: 0x00000001
2670 Tag: DW_TAG_compile_unit
2671 Children: DW_CHILDREN_yes
2672 Attributes:
2673 - Attribute: DW_AT_low_pc
2674 Form: DW_FORM_addr
2675 - Attribute: DW_AT_high_pc
2676 Form: DW_FORM_addr
2677 - Attribute: DW_AT_name
2678 Form: DW_FORM_strp
2679 - Code: 0x00000002
2680 Tag: DW_TAG_subprogram
2681 Children: DW_CHILDREN_no
2682 Attributes:
2683 - Attribute: DW_AT_name
2684 Form: DW_FORM_strp
2685 - Attribute: DW_AT_low_pc
2686 Form: DW_FORM_addr
2687 - Attribute: DW_AT_high_pc
2688 Form: DW_FORM_addr
2689 debug_info:
2690 - Length:
2691 TotalLength: 71
2692 Version: 4
2693 AbbrOffset: 0
2694 AddrSize: 8
2695 Entries:
2696 - AbbrCode: 0x00000001
2697 Values:
2698 - Value: 0x0000000000001000
2699 - Value: 0x0000000000002000
2700 - Value: 0x0000000000000001
2701 - AbbrCode: 0x00000002
2702 Values:
2703 - Value: 0x000000000000000D
2704 - Value: 0x0000000000001000
2705 - Value: 0x0000000000002000
2706 - AbbrCode: 0x00000002
2707 Values:
2708 - Value: 0x0000000000000012
2709 - Value: 0x0000000000002000
2710 - Value: 0x0000000000002000
2711 - AbbrCode: 0x00000000
2712 Values:
2713 )";
2714 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2715 ASSERT_TRUE((bool)ErrOrSections);
2716 std::unique_ptr DwarfContext =
2717 DWARFContext::create(*ErrOrSections, 8);
2718 VerifySuccess(*DwarfContext);
2719 }
2720
2721 TEST(DWARFDebugInfo, TestDwarfVerifyNestedFunctions) {
2722 // Create a single compile unit with a nested function which is not contained
2723 // in its parent. Although LLVM doesn't generate this, it is valid accoridng
2724 // to the DWARF standard.
2725 StringRef yamldata = R"(
2726 debug_str:
2727 - ''
2728 - /tmp/main.c
2729 - main
2730 - nested
2731 debug_abbrev:
2732 - Code: 0x00000001
2733 Tag: DW_TAG_compile_unit
2734 Children: DW_CHILDREN_yes
2735 Attributes:
2736 - Attribute: DW_AT_low_pc
2737 Form: DW_FORM_addr
2738 - Attribute: DW_AT_high_pc
2739 Form: DW_FORM_addr
2740 - Attribute: DW_AT_name
2741 Form: DW_FORM_strp
2742 - Code: 0x00000002
2743 Tag: DW_TAG_subprogram
2744 Children: DW_CHILDREN_yes
2745 Attributes:
2746 - Attribute: DW_AT_name
2747 Form: DW_FORM_strp
2748 - Attribute: DW_AT_low_pc
2749 Form: DW_FORM_addr
2750 - Attribute: DW_AT_high_pc
2751 Form: DW_FORM_addr
2752 debug_info:
2753 - Length:
2754 TotalLength: 73
2755 Version: 4
2756 AbbrOffset: 0
2757 AddrSize: 8
2758 Entries:
2759 - AbbrCode: 0x00000001
2760 Values:
2761 - Value: 0x0000000000001000
2762 - Value: 0x0000000000002000
2763 - Value: 0x0000000000000001
2764 - AbbrCode: 0x00000002
2765 Values:
2766 - Value: 0x000000000000000D
2767 - Value: 0x0000000000001000
2768 - Value: 0x0000000000001500
2769 - AbbrCode: 0x00000002
2770 Values:
2771 - Value: 0x0000000000000012
2772 - Value: 0x0000000000001500
2773 - Value: 0x0000000000002000
2774 - AbbrCode: 0x00000000
2775 Values:
2776 - AbbrCode: 0x00000000
2777 Values:
2778 - AbbrCode: 0x00000000
2779 Values:
2780 )";
2781 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
2782 ASSERT_TRUE((bool)ErrOrSections);
2783 std::unique_ptr DwarfContext =
2784 DWARFContext::create(*ErrOrSections, 8);
2785 VerifySuccess(*DwarfContext);
2786 }
2787
2788 TEST(DWARFDebugInfo, TestDwarfRangesContains) {
2789 DWARFAddressRange R(0x10, 0x20);
2790
2791 //----------------------------------------------------------------------
2792 // Test ranges that start before R...
2793 //----------------------------------------------------------------------
2794 // Other range ends before start of R
2795 ASSERT_FALSE(R.contains({0x0f, 0x10}));
2796 // Other range end address is start of a R
2797 ASSERT_FALSE(R.contains({0x0f, 0x11}));
2798 // Other range end address is at and of R
2799 ASSERT_FALSE(R.contains({0x0f, 0x20}));
2800 // Other range end address is past end of R
2801 ASSERT_FALSE(R.contains({0x0f, 0x40}));
2802
2803 //----------------------------------------------------------------------
2804 // Test ranges that start at R's start address
2805 //----------------------------------------------------------------------
2806 // Ensure empty ranges matches
2807 ASSERT_TRUE(R.contains({0x10, 0x10}));
2808 // 1 byte of Range
2809 ASSERT_TRUE(R.contains({0x10, 0x11}));
2810 // same as Range
2811 ASSERT_TRUE(R.contains({0x10, 0x20}));
2812 // 1 byte past Range
2813 ASSERT_FALSE(R.contains({0x10, 0x21}));
2814
2815 //----------------------------------------------------------------------
2816 // Test ranges that start inside Range
2817 //----------------------------------------------------------------------
2818 // empty in range
2819 ASSERT_TRUE(R.contains({0x11, 0x11}));
2820 // all in Range
2821 ASSERT_TRUE(R.contains({0x11, 0x1f}));
2822 // ends at end of Range
2823 ASSERT_TRUE(R.contains({0x11, 0x20}));
2824 // ends past Range
2825 ASSERT_FALSE(R.contains({0x11, 0x21}));
2826
2827 //----------------------------------------------------------------------
2828 // Test ranges that start at last bytes of Range
2829 //----------------------------------------------------------------------
2830 // ends at end of Range
2831 ASSERT_TRUE(R.contains({0x1f, 0x20}));
2832 // ends past Range
2833 ASSERT_FALSE(R.contains({0x1f, 0x21}));
2834
2835 //----------------------------------------------------------------------
2836 // Test ranges that start after Range
2837 //----------------------------------------------------------------------
2838 // empty considered in Range
2839 ASSERT_TRUE(R.contains({0x20, 0x20}));
2840 // valid past Range
2841 ASSERT_FALSE(R.contains({0x20, 0x21}));
2842 }
2843
2844 TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) {
2845 DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}});
2846
2847 ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}}));
2848 ASSERT_FALSE(Ranges.contains({{{0x20, 0x30}}}));
2849 ASSERT_FALSE(Ranges.contains({{{0x40, 0x41}}}));
2850 ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}}));
2851 ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}}));
2852 ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}}));
2853 ASSERT_TRUE(Ranges.contains({{{0x30, 0x40}}}));
2854 ASSERT_TRUE(Ranges.contains({{{0x31, 0x32}}}));
2855 ASSERT_TRUE(Ranges.contains({{{0x3f, 0x40}}}));
2856 ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}, {0x30, 0x40}}}));
2857 ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x31, 0x32}}}));
2858 ASSERT_TRUE(Ranges.contains(
2859 {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x33}}}));
2860 ASSERT_FALSE(Ranges.contains({{{0x11, 0x12},
2861 {0x12, 0x13},
2862 {0x20, 0x21},
2863 {0x31, 0x32},
2864 {0x32, 0x33}}}));
2865 ASSERT_FALSE(Ranges.contains(
2866 {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x41}}}));
2867 }
2868
2869 namespace {
2870
2871 void AssertRangesIntersect(const DWARFAddressRange &LHS,
2872 const DWARFAddressRange &RHS) {
2873 ASSERT_TRUE(LHS.intersects(RHS));
2874 ASSERT_TRUE(RHS.intersects(LHS));
2875 }
2876 void AssertRangesDontIntersect(const DWARFAddressRange &LHS,
2877 const DWARFAddressRange &RHS) {
2878 ASSERT_FALSE(LHS.intersects(RHS));
2879 ASSERT_FALSE(RHS.intersects(LHS));
2880 }
2881
2882 void AssertRangesIntersect(const DWARFVerifier::DieRangeInfo &LHS,
2883 const DWARFAddressRangesVector &Ranges) {
2884 DWARFVerifier::DieRangeInfo RHS(Ranges);
2885 ASSERT_TRUE(LHS.intersects(RHS));
2886 ASSERT_TRUE(RHS.intersects(LHS));
2887 }
2888
2889 void AssertRangesDontIntersect(const DWARFVerifier::DieRangeInfo &LHS,
2890 const DWARFAddressRangesVector &Ranges) {
2891 DWARFVerifier::DieRangeInfo RHS(Ranges);
2892 ASSERT_FALSE(LHS.intersects(RHS));
2893 ASSERT_FALSE(RHS.intersects(LHS));
2894 }
2895
2896 } // namespace
2897 TEST(DWARFDebugInfo, TestDwarfRangesIntersect) {
2898 DWARFAddressRange R(0x10, 0x20);
2899
2900 //----------------------------------------------------------------------
2901 // Test ranges that start before R...
2902 //----------------------------------------------------------------------
2903 // Other range ends before start of R
2904 AssertRangesDontIntersect(R, {0x00, 0x10});
2905 // Other range end address is start of a R
2906 AssertRangesIntersect(R, {0x00, 0x11});
2907 // Other range end address is in R
2908 AssertRangesIntersect(R, {0x00, 0x15});
2909 // Other range end address is at and of R
2910 AssertRangesIntersect(R, {0x00, 0x20});
2911 // Other range end address is past end of R
2912 AssertRangesIntersect(R, {0x00, 0x40});
2913
2914 //----------------------------------------------------------------------
2915 // Test ranges that start at R's start address
2916 //----------------------------------------------------------------------
2917 // Ensure empty ranges doesn't match
2918 AssertRangesDontIntersect(R, {0x10, 0x10});
2919 // 1 byte of Range
2920 AssertRangesIntersect(R, {0x10, 0x11});
2921 // same as Range
2922 AssertRangesIntersect(R, {0x10, 0x20});
2923 // 1 byte past Range
2924 AssertRangesIntersect(R, {0x10, 0x21});
2925
2926 //----------------------------------------------------------------------
2927 // Test ranges that start inside Range
2928 //----------------------------------------------------------------------
2929 // empty in range
2930 AssertRangesDontIntersect(R, {0x11, 0x11});
2931 // all in Range
2932 AssertRangesIntersect(R, {0x11, 0x1f});
2933 // ends at end of Range
2934 AssertRangesIntersect(R, {0x11, 0x20});
2935 // ends past Range
2936 AssertRangesIntersect(R, {0x11, 0x21});
2937
2938 //----------------------------------------------------------------------
2939 // Test ranges that start at last bytes of Range
2940 //----------------------------------------------------------------------
2941 // ends at end of Range
2942 AssertRangesIntersect(R, {0x1f, 0x20});
2943 // ends past Range
2944 AssertRangesIntersect(R, {0x1f, 0x21});
2945
2946 //----------------------------------------------------------------------
2947 // Test ranges that start after Range
2948 //----------------------------------------------------------------------
2949 // empty just past in Range
2950 AssertRangesDontIntersect(R, {0x20, 0x20});
2951 // valid past Range
2952 AssertRangesDontIntersect(R, {0x20, 0x21});
2953 }
2954
2955 TEST(DWARFDebugInfo, TestDWARFDieRangeInfoIntersects) {
2956
2957 DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}});
2958
2959 // Test empty range
2960 AssertRangesDontIntersect(Ranges, {});
2961 // Test range that appears before all ranges in Ranges
2962 AssertRangesDontIntersect(Ranges, {{0x00, 0x10}});
2963 // Test range that appears between ranges in Ranges
2964 AssertRangesDontIntersect(Ranges, {{0x20, 0x30}});
2965 // Test range that appears after ranges in Ranges
2966 AssertRangesDontIntersect(Ranges, {{0x40, 0x50}});
2967
2968 // Test range that start before first range
2969 AssertRangesIntersect(Ranges, {{0x00, 0x11}});
2970 // Test range that start at first range
2971 AssertRangesIntersect(Ranges, {{0x10, 0x11}});
2972 // Test range that start in first range
2973 AssertRangesIntersect(Ranges, {{0x11, 0x12}});
2974 // Test range that start at end of first range
2975 AssertRangesIntersect(Ranges, {{0x1f, 0x20}});
2976 // Test range that starts at end of first range
2977 AssertRangesDontIntersect(Ranges, {{0x20, 0x21}});
2978 // Test range that starts at end of first range
2979 AssertRangesIntersect(Ranges, {{0x20, 0x31}});
2980
2981 // Test range that start before second range and ends before second
2982 AssertRangesDontIntersect(Ranges, {{0x2f, 0x30}});
2983 // Test range that start before second range and ends in second
2984 AssertRangesIntersect(Ranges, {{0x2f, 0x31}});
2985 // Test range that start at second range
2986 AssertRangesIntersect(Ranges, {{0x30, 0x31}});
2987 // Test range that start in second range
2988 AssertRangesIntersect(Ranges, {{0x31, 0x32}});
2989 // Test range that start at end of second range
2990 AssertRangesIntersect(Ranges, {{0x3f, 0x40}});
2991 // Test range that starts at end of second range
2992 AssertRangesDontIntersect(Ranges, {{0x40, 0x41}});
2993 }
2994
23492995 } // end anonymous namespace