From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by sourceware.org (Postfix) with ESMTPS id B37EB384800E for ; Fri, 4 Jun 2021 15:44:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B37EB384800E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wr1-x431.google.com with SMTP id a11so7888859wrt.13 for ; Fri, 04 Jun 2021 08:44:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=2/6tEukMIfLVKIcHJgzUYH5fHdya3HbIGrGbi8BiPHI=; b=RugKLaiWR3U86nK7qH7ECakKsPJgUhvz/9R1HsRCLQUKeFLnoqhgqRfXGKpstvwN67 Lnp1q4h0Q5JduSdeNyRTk4E97XglAqAAkuGi8erzWUXzgGZzjWd17cccTDbunhZIjNiH faDU42836KsjOsfoEs8ttoJnf5DRCcijEMWjYr2ccK2apIJrIt4c9DWCOd2TAPx25EI6 U7uUnjoJNAjpj4UTu9LaQfIIbM83ijeaGz6s0Lp1+qBQesdqONPobRzx8eWbB0AM1V9L 7qtjoRppd+9tTs88RkWYX6TJTXui6v53uK55x7HU8/tRTokgiO5TnhFjLTYG+yQevro7 BJcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=2/6tEukMIfLVKIcHJgzUYH5fHdya3HbIGrGbi8BiPHI=; b=ivuzLITff4kByhlbjG4lVIx8NPD9f2gloC6AvdDen+ClmtJTyghVcsjybGUbKo73yJ L6aWl4Qa1RG1DMZlzXNPvRbhKkYyWc+LOfJXvnAGax2u8gI2iw1I+PTRgpMmcxUOEu2V ctCPM1y1A/6yBT7o8u5V68bYypOiH5PfaMPdPLK9TaEt9bkXatPET0+3b3JeDjbkfjMW mIcC0zfFVtSYNvizcdG+7kuT9yj13bdBCBwlBY0gCEpAdnSUjm7S7V+DcbKynaB57aw2 67AG5cVUm7gPDA2GN447NQqK9j+IhARNE4xndVFuVP5BmqNbHj70e6B4kkh5RjxW9VQG giKQ== X-Gm-Message-State: AOAM531ifiAty1pLPtXZCQDa31maQniHmwNrLChn9XoeoYsZUqV7527U p6JzFXSQt7ko5/q71416adRgYnMrJzVmww== X-Google-Smtp-Source: ABdhPJxRujJnDstDYpddlTqUd9yDk9DZTUZ7Xs5ChVhCe9TePl5wktobl3Eg9vNUJ5xBU0758cLt2A== X-Received: by 2002:a5d:6dae:: with SMTP id u14mr4715604wrs.148.1622821480518; Fri, 04 Jun 2021 08:44:40 -0700 (PDT) Received: from localhost (host109-151-46-70.range109-151.btcentralplus.com. [109.151.46.70]) by smtp.gmail.com with ESMTPSA id 62sm7831342wrm.1.2021.06.04.08.44.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Jun 2021 08:44:40 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Subject: [PATCH] gdb: handle case where type alignment is unknown Date: Fri, 4 Jun 2021 16:44:37 +0100 Message-Id: <20210604154437.381782-1-andrew.burgess@embecosm.com> X-Mailer: git-send-email 2.25.4 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Fri, 04 Jun 2021 15:44:52 -0000 It was spotted that if type_align returned 0 then it was possible to trigger a divide by zero exception within GDB. It turns out this will only happen in an edge case where GDB is unable to figure out the alignment of a field within a structure. The attached test generates some non-standard, probably broken, DWARF, that triggers this condition, and then fixes this issue by throwing an exception when this case occurs. gdb/ChangeLog: PR gdb/27847 * amd64-tdep.c (amd64_has_unaligned_fields): Move call to type_align, and spot case where the alignment is unknown. gdb/testsuite/ChangeLog: PR gdb/27847 * gdb.dwarf2/dw2-weird-type-len.c: New file. * gdb.dwarf2/dw2-weird-type-len.exp: New file. --- gdb/ChangeLog | 6 + gdb/amd64-tdep.c | 5 +- gdb/testsuite/ChangeLog | 6 + gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.c | 45 ++++++++ .../gdb.dwarf2/dw2-weird-type-len.exp | 107 ++++++++++++++++++ 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.c create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 91305ddeb44..3afac3c7e60 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -554,7 +554,6 @@ amd64_has_unaligned_fields (struct type *type) { struct type *subtype = check_typedef (type->field (i).type ()); int bitpos = TYPE_FIELD_BITPOS (type, i); - int align = type_align(subtype); /* Ignore static fields, empty fields (for example nested empty structures), and bitfields (these are handled by @@ -568,6 +567,10 @@ amd64_has_unaligned_fields (struct type *type) if (bitpos % 8 != 0) return true; + int align = type_align (subtype); + if (align == 0) + error (_("could not determine alignment of type")); + int bytepos = bitpos / 8; if (bytepos % align != 0) return true; diff --git a/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.c b/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.c new file mode 100644 index 00000000000..192fc565b11 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.c @@ -0,0 +1,45 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 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 . */ + +struct foo_t +{ + int field : 24; +}; + +struct bar_t +{ + struct foo_t f; +}; + +struct bar_t +get_bar () +{ + asm ("get_bar_label: .globl get_bar_label"); + struct bar_t b; + + b.f.field = 0; + + return b; +} + +int +main () +{ + asm ("main_label: .globl main_label"); + struct bar_t b = get_bar (); + return b.f.field; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp b/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp new file mode 100644 index 00000000000..d57bb86c988 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp @@ -0,0 +1,107 @@ +# Copyright 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 x86-64 targets. It checks for a bug +# that existed in amd64-tdep.c, and depends on an error being produced +# from within that file. +if {![istarget x86_64-*] || ![is_lp64_target]} { + return 0 +} + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile .c -dw.S + +# Make some DWARF for the test. +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global srcfile + + get_func_info main + get_func_info get_bar + + cu {} { + DW_TAG_compile_unit { + {DW_AT_language @DW_LANG_C} + {DW_AT_name $srcfile} + {DW_AT_comp_dir /tmp} + } { + declare_labels integer_label foo_t_label bar_t_label + + foo_t_label: DW_TAG_structure_type { + {name foo_t} + {byte_size 3 DW_FORM_sdata} + } { + member { + {name field} + {type :$integer_label} + {data_member_location 0 DW_FORM_sdata} + } + } + + integer_label: DW_TAG_base_type { + {DW_AT_byte_size 3 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name integer} + } + + bar_t_label: DW_TAG_structure_type { + {name bar_t} + {byte_size 3 DW_FORM_sdata} + } { + member { + {name f} + {type :$foo_t_label} + {data_member_location 0 DW_FORM_sdata} + } + } + + DW_TAG_subprogram { + {name main} + {low_pc $main_start addr} + {high_pc $main_len data8} + {DW_AT_type :$integer_label} + } + + DW_TAG_subprogram { + {name get_bar} + {low_pc $get_bar_start addr} + {high_pc $get_bar_len data8} + {DW_AT_type :$bar_t_label} + } + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +# At one point this would trigger a divide by zero inside GDB. Now we +# just get an error message. +gdb_test "print get_bar ()" "could not determine alignment of type" + +# Check GDB is still running. +gdb_test "p 1 + 2" " = 3" -- 2.25.4