llvm.org GIT mirror llvm / 13ca51e
Revert "[dwarfdump] Add DWARF verifiers for address ranges" This reverts commit r313250. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313253 91177308-0d34-0410-b5e6-96231b3b80d8 Jonas Devlieghere 2 years ago
5 changed file(s) with 9 addition(s) and 882 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 }
5227 };
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 }
5828
5929 /// DWARFAddressRangesVector - represents a set of absolute address ranges.
6030 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
314310 class DWARFDie::iterator : public iterator_facade_base
315311 std::forward_iterator_tag,
316312 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"
1513
1614 #include
1715 #include
3129
3230 /// A class that verifies DWARF debug information given a DWARF Context.
3331 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:
8932 raw_ostream &OS;
9033 DWARFContext &DCtx;
9134 DIDumpOptions DumpOpts;
14083 /// - cases in which lowPC >= highPC
14184 ///
14285 /// \returns Number of errors that occured during verification.
143 unsigned verifyDieRanges(const DWARFDie &Die, DieRangeInfo &ParentRI);
86 unsigned verifyDieRanges(const DWARFDie &Die);
14487
14588 /// Verifies the attribute's DWARF attribute and its value.
14689 ///
252195 bool handleAccelTables();
253196 };
254197
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
260198 } // end namespace llvm
261199
262200 #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 }
10225
10326 bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
10427 uint32_t *Offset, unsigned UnitIndex,
17093 auto Die = Unit.getDIEAtIndex(I);
17194 if (Die.getTag() == DW_TAG_null)
17295 continue;
96 NumUnitErrors += verifyDieRanges(Die);
17397 for (auto AttrValue : Die.attributes()) {
17498 NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
17599 NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
176100 }
177101 }
178
179 DieRangeInfo RI;
180 DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
181 NumUnitErrors += verifyDieRanges(Die, RI);
182102 return NumUnitErrors == 0;
183103 }
184104
289209 return (isHeaderChainValid && NumDebugInfoErrors == 0);
290210 }
291211
292 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
293 DieRangeInfo &ParentRI) {
294 unsigned NumErrors = 0;
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()) {
212 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die) {
213 unsigned NumErrors = 0;
214 for (auto Range : Die.getAddressRanges()) {
215 if (Range.LowPC >= Range.HighPC) {
306216 ++NumErrors;
307217 OS << format("error: Invalid address range [0x%08" PRIx64
308218 " - 0x%08" PRIx64 "].\n",
309219 Range.LowPC, Range.HighPC);
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
220 }
221 }
353222 return NumErrors;
354223 }
355224
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"
2322 #include "llvm/MC/MCContext.h"
2423 #include "llvm/MC/MCSectionELF.h"
2524 #include "llvm/MC/MCStreamer.h"
16721671 EXPECT_TRUE(Str.str().contains(Error));
16731672 }
16741673
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
16811674 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) {
16821675 // Create a single compile unit with a single function that has a DW_AT_type
1683 // that is CU relative. The CU offset is not valid because it is larger than
1676 // that is CU relative. The CU offset is not valid becuase it is larger than
16841677 // the compile unit itself.
16851678
16861679 const char *yamldata = R"(
23532346 EXPECT_TRUE(Errors == 1);
23542347 }
23552348
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
29952349 } // end anonymous namespace