From 3dfa60d4a19d16dba03b0c5058b85fc317249002 Mon Sep 17 00:00:00 2001 From: Luis Machado Date: Wed, 6 May 2020 13:41:48 -0300 Subject: [PATCH] [Morello] Capability address_class support and testcase Handle the new address class type for Morello, which modifies regular pointers and makes them 16 bytes in size. gdb/ChangeLog: 2020-10-20 Luis Machado * aarch64-tdep.c (aarch64_address_class_type_flags) (aarch64_address_class_type_flags_to_name) (aarch64_address_class_name_to_type_flags): New functions. (aarch64_gdbarch_init): Register address class hooks. gdb/testsuite/ChangeLog: 2020-10-20 Luis Machado * gdb.dwarf2/dw2-capability.exp: New test. --- gdb/aarch64-tdep.c | 59 ++++++++ gdb/testsuite/gdb.dwarf2/dw2-capability.exp | 152 ++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-capability.exp diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index a9a4f538a71..f9cce1db8b0 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3441,6 +3441,54 @@ aarch64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) return streq (inst.opcode->name, "ret"); } +/* Implementation of `address_class_type_flags' gdbarch method. + + This method maps DW_AT_address_class attributes to a + type_instance_flag_value. */ + +static type_instance_flags +aarch64_address_class_type_flags (int byte_size, int dwarf2_addr_class) +{ + /* The value 1 of the DW_AT_address_class attribute corresponds to the + __capability qualifier, meaning a capability for Morello. */ + + if (dwarf2_addr_class == 1) + return TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1; + return 0; +} + +/* Implementation of `address_class_type_flags_to_name' gdbarch method. + + Convert a type_instance_flag_value to an address space qualifier. */ + +static const char* +aarch64_address_class_type_flags_to_name (struct gdbarch *gdbarch, + type_instance_flags type_flags) +{ + if (type_flags & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1) + return "__capability"; + else + return NULL; +} + +/* Implementation of `address_class_name_to_type_flags' gdbarch method. + + Convert an address space qualifier to a type_instance_flag_value. */ + +static bool +aarch64_address_class_name_to_type_flags (struct gdbarch *gdbarch, + const char* name, + type_instance_flags *type_flags_ptr) +{ + if (strcmp (name, "__capability") == 0) + { + *type_flags_ptr = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1; + return true; + } + else + return false; +} + /* Initialize the current architecture based on INFO. If possible, re-use an architecture from ARCHES, which is a list of architectures already created during this debugging session. @@ -3753,6 +3801,17 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) register_aarch64_ravenscar_ops (gdbarch); + /* Set address class hooks for capabilities. */ + if (feature_capability) + { + set_gdbarch_address_class_type_flags + (gdbarch, aarch64_address_class_type_flags); + set_gdbarch_address_class_name_to_type_flags + (gdbarch, aarch64_address_class_name_to_type_flags); + set_gdbarch_address_class_type_flags_to_name + (gdbarch, aarch64_address_class_type_flags_to_name); + } + return gdbarch; } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-capability.exp b/gdb/testsuite/gdb.dwarf2/dw2-capability.exp new file mode 100644 index 00000000000..5d60bd5ec0c --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-capability.exp @@ -0,0 +1,152 @@ +# Copyright 2018-2020 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile main.c capability-dw.S + +# Make some DWARF for the test. + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global srcdir subdir srcfile + + cu {} { + DW_TAG_compile_unit { + {DW_AT_language @DW_LANG_C_plus_plus} + {DW_AT_name dw2-capability.c} + {DW_AT_comp_dir /tmp} + } { + declare_labels itype cap_type ptr_type \ + intcap_type intcap_ptr_type uintcap_type uintcap_ptr_type \ + var_a_label var_b_label var_c_label \ + var_d_label var_e_label var_f_label var_g_label + + intcap_type: DW_TAG_base_type { + {DW_AT_byte_size 16 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_CHERI_signed_intcap} + {DW_AT_name __intcap_t} + {DW_AT_alignment 16 DW_FORM_sdata} + } + + uintcap_type: DW_TAG_base_type { + {DW_AT_byte_size 16 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_CHERI_unsigned_intcap} + {DW_AT_name __uintcap_t} + {DW_AT_alignment 16 DW_FORM_sdata} + } + + itype: DW_TAG_base_type { + {DW_AT_byte_size 4 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name int} + {DW_AT_alignment 4 DW_FORM_sdata} + } + + cap_type: DW_TAG_pointer_type { + {DW_AT_byte_size 16 DW_FORM_sdata} + {DW_AT_type :$itype} + {DW_AT_alignment 16 DW_FORM_sdata} + {DW_AT_address_class 1 DW_FORM_sdata} + } + + intcap_ptr_type: DW_TAG_pointer_type { + {DW_AT_byte_size 16 DW_FORM_sdata} + {DW_AT_type :$intcap_type} + {DW_AT_alignment 16 DW_FORM_sdata} + {DW_AT_address_class 1 DW_FORM_sdata} + } + + uintcap_ptr_type: DW_TAG_pointer_type { + {DW_AT_byte_size 16 DW_FORM_sdata} + {DW_AT_type :$uintcap_type} + {DW_AT_alignment 16 DW_FORM_sdata} + {DW_AT_address_class 1 DW_FORM_sdata} + } + + ptr_type: DW_TAG_pointer_type { + {DW_AT_byte_size 8 DW_FORM_sdata} + {DW_AT_type :$itype} + {DW_AT_alignment 8 DW_FORM_sdata} + {DW_AT_address_class 0 DW_FORM_sdata} + } + + var_a_label: DW_TAG_variable { + {DW_AT_name "var_a"} + {DW_AT_type :${cap_type}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_const_value 0xdeadbeef DW_FORM_sdata} + } + + var_b_label: DW_TAG_variable { + {DW_AT_name "var_b"} + {DW_AT_type :${ptr_type}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_const_value 0xdeadbeef DW_FORM_sdata} + } + + var_c_label: DW_TAG_variable { + {DW_AT_name "var_c"} + {DW_AT_type :${itype}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_const_value 0xdeadbeef DW_FORM_sdata} + } + + var_d_label: DW_TAG_variable { + {DW_AT_name "var_d"} + {DW_AT_type :${intcap_type}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_const_value 0xdeadbeef DW_FORM_sdata} + } + + var_e_label: DW_TAG_variable { + {DW_AT_name "var_e"} + {DW_AT_type :${uintcap_type}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_const_value 0xdeadbeef DW_FORM_sdata} + } + + var_f_label: DW_TAG_variable { + {DW_AT_name "var_f"} + {DW_AT_type :${intcap_ptr_type}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_const_value 0xdeadbeef DW_FORM_sdata} + } + + var_g_label: DW_TAG_variable { + {DW_AT_name "var_g"} + {DW_AT_type :${uintcap_ptr_type}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_const_value 0xdeadbeef DW_FORM_sdata} + } + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test_no_output "set lang c++" +gdb_interact -- 2.47.2