From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 97B393857C50 for ; Wed, 27 Apr 2022 12:29:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 97B393857C50 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-79-DOn3jjzJMQOK0uG4EpU-tQ-1; Wed, 27 Apr 2022 08:29:14 -0400 X-MC-Unique: DOn3jjzJMQOK0uG4EpU-tQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C208D85A5BC for ; Wed, 27 Apr 2022 12:29:13 +0000 (UTC) Received: from blarsen.com (ovpn-116-8.gru2.redhat.com [10.97.116.8]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D9F8A2026609; Wed, 27 Apr 2022 12:29:11 +0000 (UTC) From: Bruno Larsen To: gdb-patches@sourceware.org Subject: [PATCH v4 2/2] [gdb] Add Simple offset validation when calculating baseclass_offset Date: Wed, 27 Apr 2022 09:28:47 -0300 Message-Id: <20220427122847.233260-3-blarsen@redhat.com> In-Reply-To: <20220427122847.233260-1-blarsen@redhat.com> References: <20220427122847.233260-1-blarsen@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Apr 2022 12:29:17 -0000 Add a sinple validation to gnuv3_baseclass_offset when not dealing with virtual inheritance. The validation is simply checking if the offset is bigger than the size of the variable. An assert was also added to value_contents_copy_raw, in gdb/value.c, to ensure that no data from outside the src value is copied, and that we dont copy to outside the dst variable. A test case was added that has incorrect location expressions and tests that the addresses are correctly identified as invalid. --- gdb/gnu-v3-abi.c | 9 +- .../gdb.dwarf2/dw2-inheritance-locexpr-2.exp | 235 ++++++++++++++++++ 2 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inheritance-locexpr-2.exp diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index ae165afd8f2..6b3ae62a793 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -466,6 +466,8 @@ gnuv3_baseclass_offset (struct type *type, int index, To reuse code, we just fall-through in that case */ if (type->field (index).loc_kind () == FIELD_LOC_KIND_BITPOS){ cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8; + if (cur_base_offset >= TYPE_LENGTH (type)) + error (_("Incorrect offset of baseclass")); return TYPE_BASECLASS_BITPOS (type, index) / 8; } } @@ -491,7 +493,12 @@ gnuv3_baseclass_offset (struct type *type, int index, CORE_ADDR result; if (dwarf2_evaluate_property (&prop, nullptr, &addr_stack, &result, {addr_stack.addr})) - return (int) (result - addr_stack.addr); + { + if (!BASETYPE_VIA_VIRTUAL (type, index) && + (result - addr_stack.addr) >= TYPE_LENGTH (type)) + error (_("overly large offset in non-virtual member")); + return (int) (result - addr_stack.addr); + } } /* To access a virtual base, we need to use the vbase offset stored in diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inheritance-locexpr-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-inheritance-locexpr-2.exp new file mode 100644 index 00000000000..c9cdba252c1 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-inheritance-locexpr-2.exp @@ -0,0 +1,235 @@ +# Copyright 2018-2021 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 +} + +# We'll place the output of Dwarf::assemble in pr28030.S. +standard_testfile dw2-inheritance-locexpr.c .S + +# ${testfile} is now "pr28030". srcfile2 is "pr28030.S". +set executable ${testfile} +set asm_file [standard_output_file ${srcfile2}] + +# We need to know the size of integer and address types in order +# to write some of the debugging info we'd like to generate. +# +# For that, we ask GDB by debugging our pr28030 program. +# Any program would do, but since we already have pr28030 +# specifically for this testcase, might as well use that. +if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] { + return -1 +} +set long_size [get_sizeof "long" -1] +# gdb always assumes references are implemented as pointers. +set addr_size [get_sizeof "void *" -1] +set struct_A_size [get_sizeof "g_A" 4] +set struct_B_size [get_sizeof "g_B" 4] +set struct_C_size [get_sizeof "g_C" 4] + +# Create the DWARF. +Dwarf::assemble ${asm_file} { + global srcdir subdir srcfile srcfile2 + global long_size addr_size struct_A_size struct_B_size struct_C_size + declare_labels L + + cu {} { + DW_TAG_compile_unit { + {DW_AT_language @DW_LANG_C_plus_plus} + {name pr28030.c} + {stmt_list $L DW_FORM_sec_offset} + } { + declare_labels int_label class_A_label class_B_label class_C_label + + int_label: DW_TAG_base_type { + {DW_AT_byte_size ${long_size} DW_FORM_udata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name "int"} + } + + class_A_label: DW_TAG_class_type { + {DW_AT_name "A"} + {DW_AT_byte_size $struct_A_size DW_FORM_sdata} + } { + DW_TAG_member { + {DW_AT_name "a"} + {DW_AT_type :$int_label} + {DW_AT_data_member_location 0*$long_size DW_FORM_udata} + } + DW_TAG_member { + {DW_AT_name "x"} + {DW_AT_type :$int_label} + {DW_AT_data_member_location 1*$long_size DW_FORM_udata} + } + } + + class_B_label: DW_TAG_class_type { + {DW_AT_name "B"} + {DW_AT_byte_size $struct_B_size DW_FORM_sdata} + } { + DW_TAG_inheritance { + {DW_AT_type :$class_A_label} + {DW_AT_data_member_location { + DW_OP_constu 9000 + DW_OP_plus + DW_OP_stack_value } SPECIAL_expr} + {DW_AT_accessibility 1 DW_FORM_data1} + } + DW_TAG_member { + {DW_AT_name "b"} + {DW_AT_type :$int_label} + {DW_AT_data_member_location 2*$long_size DW_FORM_udata} + } + } + + class_C_label: DW_TAG_class_type { + {DW_AT_name "C"} + {DW_AT_byte_size $struct_C_size DW_FORM_sdata} + } { + DW_TAG_inheritance { + {DW_AT_type :$class_A_label} + {DW_AT_data_member_location { DW_OP_constu 9000 } SPECIAL_expr} + {DW_AT_accessibility 1 DW_FORM_data1} + } + DW_TAG_member { + {DW_AT_name "b"} + {DW_AT_type :$int_label} + {DW_AT_data_member_location 2*$long_size DW_FORM_udata} + } + } + + DW_TAG_variable { + {DW_AT_name "g_A"} + {DW_AT_type :$class_A_label} + {DW_AT_external 1 flag} + {DW_AT_location {DW_OP_addr [gdb_target_symbol "g_A"]} SPECIAL_expr} + } + + DW_TAG_variable { + {DW_AT_name "g_B"} + {DW_AT_type :$class_B_label} + {DW_AT_external 1 flag} + {DW_AT_location {DW_OP_addr [gdb_target_symbol "g_B"]} SPECIAL_expr} + } + + DW_TAG_variable { + {DW_AT_name "g_C"} + {DW_AT_type :$class_C_label} + {DW_AT_external 1 flag} + {DW_AT_location {DW_OP_addr [gdb_target_symbol "g_C"]} SPECIAL_expr} + } + + DW_TAG_subprogram { + {MACRO_AT_func { "foo" }} + {DW_AT_type :${class_B_label}} + {DW_AT_external 1 flag} + } + DW_TAG_subprogram { + {MACRO_AT_func { "bar" }} + {DW_AT_type :${class_C_label}} + {DW_AT_external 1 flag} + } + DW_TAG_subprogram { + {MACRO_AT_func { "main" }} + {DW_AT_type :${int_label}} + {DW_AT_external 1 DW_FORM_flag} + } + } + } + + lines {version 2} L { + include_dir "${srcdir}/${subdir}" + file_name "$srcfile" 1 + + lassign [function_range main [list ${srcdir}/${subdir}/$srcfile]] \ + main_start main_len + set main_end "$main_start + $main_len" + lassign [function_range foo [list ${srcdir}/${subdir}/$srcfile]] \ + foo_start foo_len + set foo_end "$foo_start + $foo_len" + lassign [function_range bar [list ${srcdir}/${subdir}/$srcfile]] \ + bar_start bar_len + set bar_end "$bar_start + $bar_len" + + # Generate a line table program. An attempt was made to make it + # reasonably accurate as it made debugging the test case easier. + program { + DW_LNE_set_address $main_start + line [gdb_get_line_number "main prologue"] + DW_LNS_copy + DW_LNE_set_address main_label + line [gdb_get_line_number "main foo call"] + DW_LNS_copy + DW_LNE_set_address main_bar_label + line [gdb_get_line_number "main bar call"] + DW_LNS_copy + DW_LNE_set_address main_label2 + line [gdb_get_line_number "main return"] + DW_LNS_copy + DW_LNE_set_address $main_end + line [expr [gdb_get_line_number "main end"] + 1] + DW_LNS_copy + DW_LNE_end_sequence + + DW_LNE_set_address $foo_start + line [gdb_get_line_number "foo prologue"] + DW_LNS_copy + DW_LNE_set_address foo_label + line [gdb_get_line_number "foo return"] + DW_LNS_copy + line [gdb_get_line_number "foo end"] + DW_LNS_copy + DW_LNE_set_address $foo_end + DW_LNS_advance_line 1 + DW_LNS_copy + DW_LNE_end_sequence + + DW_LNE_set_address $bar_start + line [gdb_get_line_number "bar prologue"] + DW_LNS_copy + DW_LNE_set_address bar_label + line [gdb_get_line_number "bar return"] + DW_LNS_copy + line [gdb_get_line_number "bar end"] + DW_LNS_copy + DW_LNE_set_address $bar_end + DW_LNS_advance_line 1 + DW_LNS_copy + DW_LNE_end_sequence + + } + } +} + +if [prepare_for_testing "failed to prepare" ${executable} [list ${asm_file} ${srcfile}] {}] { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test "step" "foo .. at .* foo end.*" "step into foo" +gdb_test "finish" "= { = , b = 7}" "finish out of foo" +gdb_test "step" "bar .. at .* bar end.*" "step into bar" +gdb_test "finish" "= { = , b = 10}" "finish out of bar" + +if ![runto_main] { + return -1 +} -- 2.31.1