@@ -420,6 +420,281 @@ TEST_F(DWARFASTParserClangTests, TestPtrAuthParsing) {
420
420
ASSERT_EQ (type_as_string, " void (*__ptrauth(0,0,42))(...)" );
421
421
}
422
422
423
+ TEST_F (DWARFASTParserClangTests, TestVTablePtrAuthParsing) {
424
+ // Tests parsing dynamic structure types with explicit vtable pointer
425
+ // authentication
426
+
427
+ // This is Dwarf for the following C++ code:
428
+ // ```
429
+ // struct [[clang::ptrauth_vtable_pointer(process_dependent,
430
+ // address_discrimination,
431
+ // custom_discrimination, 42)]] A {
432
+ // virtual void foo() {}
433
+ // };
434
+ // A a;
435
+ // ```
436
+
437
+ const char *yamldata = R"(
438
+ --- !ELF
439
+ FileHeader:
440
+ Class: ELFCLASS64
441
+ Data: ELFDATA2LSB
442
+ Type: ET_EXEC
443
+ Machine: EM_AARCH64
444
+ DWARF:
445
+ debug_str:
446
+ - a
447
+ - A
448
+ - _vptr$A
449
+ - foo
450
+ - __vtbl_ptr_type
451
+ - int
452
+ debug_abbrev:
453
+ - ID: 0
454
+ Table:
455
+ - Code: 0x1
456
+ Tag: DW_TAG_compile_unit
457
+ Children: DW_CHILDREN_yes
458
+ Attributes:
459
+ - Attribute: DW_AT_language
460
+ Form: DW_FORM_data2
461
+ - Code: 0x2
462
+ Tag: DW_TAG_variable
463
+ Children: DW_CHILDREN_no
464
+ Attributes:
465
+ - Attribute: DW_AT_name
466
+ Form: DW_FORM_strp
467
+ - Attribute: DW_AT_type
468
+ Form: DW_FORM_ref4
469
+ - Attribute: DW_AT_external
470
+ Form: DW_FORM_flag_present
471
+ - Code: 0x3
472
+ Tag: DW_TAG_structure_type
473
+ Children: DW_CHILDREN_yes
474
+ Attributes:
475
+ - Attribute: DW_AT_containing_type
476
+ Form: DW_FORM_ref4
477
+ - Attribute: DW_AT_name
478
+ Form: DW_FORM_strp
479
+ - Code: 0x4
480
+ Tag: DW_TAG_member
481
+ Children: DW_CHILDREN_no
482
+ Attributes:
483
+ - Attribute: DW_AT_name
484
+ Form: DW_FORM_strp
485
+ - Attribute: DW_AT_type
486
+ Form: DW_FORM_ref4
487
+ - Attribute: DW_AT_artificial
488
+ Form: DW_FORM_flag_present
489
+ - Code: 0x5
490
+ Tag: DW_TAG_subprogram
491
+ Children: DW_CHILDREN_yes
492
+ Attributes:
493
+ - Attribute: DW_AT_name
494
+ Form: DW_FORM_strp
495
+ - Attribute: DW_AT_virtuality
496
+ Form: DW_FORM_data1
497
+ - Attribute: DW_AT_containing_type
498
+ Form: DW_FORM_ref4
499
+ - Code: 0x6
500
+ Tag: DW_TAG_formal_parameter
501
+ Children: DW_CHILDREN_no
502
+ Attributes:
503
+ - Attribute: DW_AT_type
504
+ Form: DW_FORM_ref4
505
+ - Attribute: DW_AT_artificial
506
+ Form: DW_FORM_flag_present
507
+ - Code: 0x7
508
+ Tag: DW_TAG_LLVM_ptrauth_type
509
+ Children: DW_CHILDREN_no
510
+ Attributes:
511
+ - Attribute: DW_AT_type
512
+ Form: DW_FORM_ref4
513
+ - Attribute: DW_AT_LLVM_ptrauth_key
514
+ Form: DW_FORM_data1
515
+ - Attribute: DW_AT_LLVM_ptrauth_extra_discriminator
516
+ Form: DW_FORM_data2
517
+ - Attribute: DW_AT_LLVM_ptrauth_address_discriminated
518
+ Form: DW_FORM_flag_present
519
+ - Code: 0x8
520
+ Tag: DW_TAG_pointer_type
521
+ Children: DW_CHILDREN_no
522
+ Attributes:
523
+ - Attribute: DW_AT_type
524
+ Form: DW_FORM_ref4
525
+ - Code: 0x9
526
+ Tag: DW_TAG_pointer_type
527
+ Children: DW_CHILDREN_no
528
+ Attributes:
529
+ - Attribute: DW_AT_type
530
+ Form: DW_FORM_ref4
531
+ - Attribute: DW_AT_name
532
+ Form: DW_FORM_strp
533
+ - Code: 0xA
534
+ Tag: DW_TAG_subroutine_type
535
+ Children: DW_CHILDREN_no
536
+ Attributes:
537
+ - Attribute: DW_AT_type
538
+ Form: DW_FORM_ref4
539
+ - Code: 0xB
540
+ Tag: DW_TAG_base_type
541
+ Children: DW_CHILDREN_no
542
+ Attributes:
543
+ - Attribute: DW_AT_name
544
+ Form: DW_FORM_strp
545
+ - Attribute: DW_AT_encoding
546
+ Form: DW_FORM_data1
547
+ - Attribute: DW_AT_byte_size
548
+ Form: DW_FORM_data1
549
+ - Code: 0xC
550
+ Tag: DW_TAG_pointer_type
551
+ Children: DW_CHILDREN_no
552
+ Attributes:
553
+ - Attribute: DW_AT_type
554
+ Form: DW_FORM_ref4
555
+
556
+ debug_info:
557
+ - Version: 5
558
+ UnitType: DW_UT_compile
559
+ AddrSize: 8
560
+ Entries:
561
+ # 0x0c: DW_TAG_compile_unit
562
+ # DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus_11)
563
+ - AbbrCode: 0x1
564
+ Values:
565
+ - Value: 0x1A
566
+
567
+ # 0x0f: DW_TAG_variable
568
+ # DW_AT_name [DW_FORM_strp] (\"a\")
569
+ # DW_AT_type [DW_FORM_ref4] (0x00000018 \"A\")
570
+ # DW_AT_external [DW_FORM_flag_present] (true)
571
+ - AbbrCode: 0x2
572
+ Values:
573
+ - Value: 0x00
574
+ - Value: 0x18
575
+
576
+ # 0x18: DW_TAG_structure_type
577
+ # DW_AT_containing_type [DW_FORM_ref4] (0x00000018 \"A\")
578
+ # DW_AT_name [DW_FORM_strp] (\"A\")
579
+ - AbbrCode: 0x3
580
+ Values:
581
+ - Value: 0x18
582
+ - Value: 0x02
583
+
584
+ # 0x21: DW_TAG_member
585
+ # DW_AT_name [DW_FORM_strp] (\"_vptr$A\")
586
+ # DW_AT_type [DW_FORM_ref4] (0x0000002f)
587
+ # DW_AT_artificial [DW_FORM_flag_present] (true)
588
+ - AbbrCode: 0x4
589
+ Values:
590
+ - Value: 0x04
591
+ - Value: 0x3B
592
+
593
+ # 0x2a: DW_TAG_subprogram
594
+ # DW_AT_name [DW_FORM_strp] (\"foo\")
595
+ # DW_AT_virtuality [DW_FORM_data1] (DW_VIRTUALITY_virtual)
596
+ # DW_AT_containing_type [DW_FORM_ref4] (0x00000018 \"A\")
597
+ - AbbrCode: 0x5
598
+ Values:
599
+ - Value: 0x0C
600
+ - Value: 0x01
601
+ - Value: 0x18
602
+
603
+ # 0x34: DW_TAG_formal_parameter
604
+ # DW_AT_type [DW_FORM_ref4] (0x0000005d \"A *\")
605
+ # DW_AT_artificial [DW_FORM_flag_present] (true)
606
+ - AbbrCode: 0x6
607
+ Values:
608
+ - Value: 0x5D
609
+
610
+ - AbbrCode: 0x0 # end of child tags of 0x2a
611
+ - AbbrCode: 0x0 # end of child tags of 0x18
612
+
613
+ # 0x3b: DW_TAG_LLVM_ptrauth_type
614
+ # DW_AT_type [DW_FORM_ref4] (0x00000043 \"int (**)()\")
615
+ # DW_AT_LLVM_ptrauth_key [DW_FORM_data1] (0x02)
616
+ # DW_AT_LLVM_ptrauth_extra_discriminator [DW_FORM_data2] (0x002a)
617
+ # DW_AT_LLVM_ptrauth_address_discriminated [DW_FORM_flag_present] (true)
618
+ - AbbrCode: 0x7
619
+ Values:
620
+ - Value: 0x43
621
+ - Value: 0x02
622
+ - Value: 0x2A
623
+
624
+ # 0x43: DW_TAG_pointer_type
625
+ # DW_AT_type [DW_FORM_ref4] (0x00000048 \"int (*)()\")
626
+ - AbbrCode: 0x8
627
+ Values:
628
+ - Value: 0x48
629
+
630
+ # 0x48: DW_TAG_pointer_type
631
+ # DW_AT_type [DW_FORM_ref4] (0x00000051 \"int ()\")
632
+ # DW_AT_name [DW_FORM_strp] (\"__vtbl_ptr_type\")
633
+ - AbbrCode: 0x9
634
+ Values:
635
+ - Value: 0x51
636
+ - Value: 0x10
637
+
638
+ # 0x51: DW_TAG_subroutine_type
639
+ # DW_AT_type [DW_FORM_ref4] (0x00000056 \"int\")
640
+ - AbbrCode: 0xA
641
+ Values:
642
+ - Value: 0x56
643
+
644
+ # 0x56: DW_TAG_base_type
645
+ # DW_AT_name [DW_FORM_strp] (\"int\")
646
+ # DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed)
647
+ # DW_AT_byte_size [DW_FORM_data1] (0x04)
648
+ - AbbrCode: 0xB
649
+ Values:
650
+ - Value: 0x20
651
+ - Value: 0x05
652
+ - Value: 0x04
653
+
654
+ # 0x5d: DW_TAG_pointer_type
655
+ # DW_AT_type [DW_FORM_ref4] (0x00000018 \"A\")
656
+ - AbbrCode: 0xC
657
+ Values:
658
+ - Value: 0x18
659
+
660
+ - AbbrCode: 0x0 # end of child tags of 0x0c
661
+ ...
662
+ )" ;
663
+ YAMLModuleTester t (yamldata);
664
+
665
+ DWARFUnit *unit = t.GetDwarfUnit ();
666
+ ASSERT_NE (unit, nullptr );
667
+ const DWARFDebugInfoEntry *cu_entry = unit->DIE ().GetDIE ();
668
+ ASSERT_EQ (cu_entry->Tag (), DW_TAG_compile_unit);
669
+ DWARFDIE cu_die (unit, cu_entry);
670
+
671
+ auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>(" ast" );
672
+ auto &ast_ctx = *holder->GetAST ();
673
+ DWARFASTParserClangStub ast_parser (ast_ctx);
674
+
675
+ DWARFDIE struct_object = cu_die.GetFirstChild ();
676
+ ASSERT_EQ (struct_object.Tag (), DW_TAG_variable);
677
+ DWARFDIE structure_type =
678
+ struct_object.GetAttributeValueAsReferenceDIE (DW_AT_type);
679
+ ASSERT_EQ (structure_type.Tag (), DW_TAG_structure_type);
680
+
681
+ SymbolContext sc;
682
+ bool new_type = false ;
683
+ lldb::TypeSP type =
684
+ ast_parser.ParseTypeFromDWARF (sc, structure_type, &new_type);
685
+ clang::RecordDecl *record_decl =
686
+ TypeSystemClang::GetAsRecordDecl (type->GetForwardCompilerType ());
687
+ auto *attr = record_decl->getAttr <clang::VTablePointerAuthenticationAttr>();
688
+ ASSERT_NE (attr, nullptr );
689
+ ASSERT_EQ (attr->getKey (),
690
+ clang::VTablePointerAuthenticationAttr::ProcessDependent);
691
+ ASSERT_EQ (attr->getAddressDiscrimination (),
692
+ clang::VTablePointerAuthenticationAttr::AddressDiscrimination);
693
+ ASSERT_EQ (attr->getExtraDiscrimination (),
694
+ clang::VTablePointerAuthenticationAttr::CustomDiscrimination);
695
+ ASSERT_EQ (attr->getCustomDiscriminationValue (), 42 );
696
+ }
697
+
423
698
struct ExtractIntFromFormValueTest : public testing ::Test {
424
699
SubsystemRAII<FileSystem, HostInfo> subsystems;
425
700
clang_utils::TypeSystemClangHolder holder;
0 commit comments