From 575673752cade1772f4a6ba2e38306e5ac9a91f6 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 4 Nov 2020 08:49:16 -0700 Subject: Synthesize array descriptors with -fgnat-encodings=minimal When -fgnat-encodings=minimal, the compiler will avoid the special GNAT-specific "encodings" format, and instead emit ordinary DWARF as much as possible. When emitting DWARF for thick pointers to arrays, the compiler emits something like: <1><11db>: Abbrev Number: 7 (DW_TAG_array_type) <11dc> DW_AT_name : (indirect string, offset: 0x1bb8): string <11e0> DW_AT_data_location: 2 byte block: 97 6 (DW_OP_push_object_address; DW_OP_deref) <11e3> DW_AT_type : <0x1173> <11e7> DW_AT_sibling : <0x1201> <2><11eb>: Abbrev Number: 8 (DW_TAG_subrange_type) <11ec> DW_AT_type : <0x1206> <11f0> DW_AT_lower_bound : 6 byte block: 97 23 8 6 94 4 (DW_OP_push_object_address; DW_OP_plus_uconst: 8; DW_OP_deref; DW_OP_deref_size: 4) <11f7> DW_AT_upper_bound : 8 byte block: 97 23 8 6 23 4 94 4 (DW_OP_push_object_address; DW_OP_plus_uconst: 8; DW_OP_deref; DW_OP_plus_uconst: 4; DW_OP_deref_size: 4) If you read between the lines, the "array" is actually a structure with two elements. One element is a pointer to the array data, and the other structure describes the bounds of the array. However, the compiler doesn't emit this explicitly, but instead hides it behind these location expressions. gdb can print such objects, but currently there is no way to construct one. So, this patch adds some code to the DWARF reader to recognize this construct, and then synthesize an array descriptor. This descriptor is then handled by the existing Ada code. Internally, we've modified GCC to emit the structure type explicitly (we will of course be sending this upstream). In this case, the array still has the DW_AT_data_location, though. This patch also modifies gdb to ignore the data location in this case -- this is preferred because the location only serves to confuse the Ada code that already knows where to find the data. In the future I hope to move some of this handling to the gdb core, so that Ada-specific hacks are not needed; however I have not yet done this. Because parallel types are not emitted with -fgnat-encodings=minimal, some changes to the Ada code were also required. The change ina ada-valprint.c was needed to avoid infinite recursion when trying to print a constrained packed array. And, there didn't seem to be any need for a recursive call here -- the value could simply be returned instead. Finally, gdb.ada/frame_arg_lang.exp no longer works in C mode, because we drop back to the structure approach now. As mentioned earlier, future work should probably fix this again; meanwhile, this doesn't seem to be a big problem, because it is what is currently done (users as a rule don't use -fgnat-encodings=minimal -- which is what I am ultimately trying to fix). Note that a couple of tests have an added KFAIL. Some -fgnat-encodings=minimal changes have landed in GNAT, and you need something very recent to pass all the tests. I'm using git gcc to accomplish this. gdb/ChangeLog 2020-11-04 Tom Tromey * dwarf2/read.c (recognize_bound_expression) (quirk_ada_thick_pointer): New functions. (read_array_type): Call quirk_ada_thick_pointer. (set_die_type): Add "skip_data_location" parameter. (quirk_ada_thick_pointer): New function. (process_structure_scope): Call quirk_ada_thick_pointer. * ada-lang.c (ada_is_unconstrained_packed_array_type) (decode_packed_array_bitsize): Handle thick pointers without parallel types. (ada_is_gnat_encoded_packed_array_type): Rename from ada_is_packed_array_type. (ada_is_constrained_packed_array_type): Update. * ada-valprint.c (ada_val_print_gnat_array): Remove. (ada_value_print_1): Use ada_get_decoded_value. gdb/testsuite/ChangeLog 2020-11-04 Tom Tromey * gdb.ada/O2_float_param.exp: Test different -fgnat-encodings values. * gdb.ada/access_to_unbounded_array.exp: Test different -fgnat-encodings values. * gdb.ada/big_packed_array.exp: Test different -fgnat-encodings values. * gdb.ada/arr_enum_idx_w_gap.exp: Test different -fgnat-encodings values. * gdb.ada/array_ptr_renaming.exp: Test different -fgnat-encodings values. * gdb.ada/array_of_variable_length.exp: Test different -fgnat-encodings values. * gdb.ada/arrayparam.exp: Test different -fgnat-encodings values. * gdb.ada/arrayptr.exp: Test different -fgnat-encodings values. * gdb.ada/frame_arg_lang.exp: Revert -fgnat-encodings=minimal change. * gdb.ada/mi_string_access.exp: Test different -fgnat-encodings values. * gdb.ada/mod_from_name.exp: Test different -fgnat-encodings values. * gdb.ada/out_of_line_in_inlined.exp: Test different -fgnat-encodings values. * gdb.ada/packed_array.exp: Test different -fgnat-encodings values. * gdb.ada/pckd_arr_ren.exp: Test different -fgnat-encodings values. * gdb.ada/unc_arr_ptr_in_var_rec.exp: Test different -fgnat-encodings values. * gdb.ada/variant_record_packed_array.exp: Test different -fgnat-encodings values. --- gdb/testsuite/gdb.ada/arrayptr.exp | 46 +++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'gdb/testsuite/gdb.ada/arrayptr.exp') diff --git a/gdb/testsuite/gdb.ada/arrayptr.exp b/gdb/testsuite/gdb.ada/arrayptr.exp index 94a5d876bd2..fa84a7a2ff1 100644 --- a/gdb/testsuite/gdb.ada/arrayptr.exp +++ b/gdb/testsuite/gdb.ada/arrayptr.exp @@ -19,36 +19,40 @@ if { [skip_ada_tests] } { return -1 } standard_ada_testfile foo -if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } { - return -1 -} +foreach_with_prefix scenario {all minimal} { + set flags [list debug additional_flags=-fgnat-encodings=$scenario] + + if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} { + return -1 + } -clean_restart ${testfile} + clean_restart ${testfile} -set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb] -if ![runto "foo.adb:$bp_location" ] then { - perror "Couldn't run ${testfile}" - return -} + set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb] + if ![runto "foo.adb:$bp_location" ] then { + perror "Couldn't run ${testfile}" + return + } -gdb_test "print string_p" \ - "= \\(foo\\.string_access\\) 0x\[0-9a-zA-Z\]+" + gdb_test "print string_p" \ + "= \\(foo\\.string_access\\) 0x\[0-9a-zA-Z\]+" -gdb_test "print string_p(3..4)" "= \"ll\"" + gdb_test "print string_p(3..4)" "= \"ll\"" -gdb_test "print null_string" "= \\(foo\\.string_access\\) 0x0" + gdb_test "print null_string" "= \\(foo\\.string_access\\) 0x0" -gdb_test "print arr_ptr" "= \\(access foo\\.little_array\\) 0x\[0-9a-zA-Z\]+" + gdb_test "print arr_ptr" "= \\(access foo\\.little_array\\) 0x\[0-9a-zA-Z\]+" -gdb_test "print arr_ptr(2)" "= 22" + gdb_test "print arr_ptr(2)" "= 22" -gdb_test "print arr_ptr(3..4)" "= \\(3 => 23, 24\\)" + gdb_test "print arr_ptr(3..4)" "= \\(3 => 23, 24\\)" -gdb_test "ptype string_access" "= access array \\(<>\\) of character" + gdb_test "ptype string_access" "= access array \\(<>\\) of character" -gdb_test "print pa_ptr.all" \ - " = \\(10, 20, 30, 40, 50, 60, 62, 63, -23, 42\\)" + gdb_test "print pa_ptr.all" \ + " = \\(10, 20, 30, 40, 50, 60, 62, 63, -23, 42\\)" -gdb_test "print pa_ptr(3)" " = 30" + gdb_test "print pa_ptr(3)" " = 30" -gdb_test "print pa_ptr.all(3)" " = 30" + gdb_test "print pa_ptr.all(3)" " = 30" +} -- cgit v1.2.1