From patchwork Thu Mar 15 11:21:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: vlad.ivanov@lab-systems.ru X-Patchwork-Id: 26316 Received: (qmail 73263 invoked by alias); 15 Mar 2018 11:22:34 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 72895 invoked by uid 89); 15 Mar 2018 11:22:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW, URIBL_SBL autolearn=ham version=3.3.2 spammy=D*ru, Hx-languages-length:4503 X-HELO: forward106o.mail.yandex.net Received: from forward106o.mail.yandex.net (HELO forward106o.mail.yandex.net) (37.140.190.187) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 15 Mar 2018 11:22:31 +0000 Received: from mxback11j.mail.yandex.net (mxback11j.mail.yandex.net [IPv6:2a02:6b8:0:1619::84]) by forward106o.mail.yandex.net (Yandex) with ESMTP id 1C492780CDB for ; Thu, 15 Mar 2018 14:22:26 +0300 (MSK) Received: from smtp1p.mail.yandex.net (smtp1p.mail.yandex.net [2a02:6b8:0:1472:2741:0:8b6:6]) by mxback11j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id cGEQw6PESI-MPA0ZPBU; Thu, 15 Mar 2018 14:22:26 +0300 Received: by smtp1p.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id vD8sJe5BjR-MPZipNQq; Thu, 15 Mar 2018 14:22:25 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) From: vlad.ivanov@lab-systems.ru To: gdb-patches@sourceware.org Cc: Vlad Ivanov Subject: [PATCH] gdbarch: Add pc_signed field and use it when adjusting BP addresses Date: Thu, 15 Mar 2018 07:21:11 -0400 Message-Id: <20180315112111.15247-1-vlad.ivanov@lab-systems.ru> From: Vlad Ivanov MIPS targets use signed PC values. Since commit a0de8c21 single-stepping on these targets didn't work due to the addition of `address_significant` in adjust_breakpoint_address. This commit adds a new field to gdbarch struct which indicates the signedness of the program counter. This field is set to 1 for MIPS by default. * gdbarch.c: Add pc_signed field and access functions. * gdbarch.h: Add pc_signed access functions declarations. * mips-tdep.c (mips_gdbarch_init): Set PC to signed by default. * breakpoint.c (adjust_breakpoint_address): Check for PC signedness when calling `address_significant`. --- gdb/breakpoint.c | 5 ++++- gdb/gdbarch.c | 20 ++++++++++++++++++++ gdb/gdbarch.h | 4 ++++ gdb/mips-tdep.c | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 454fda7684..247ec34857 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -6999,7 +6999,10 @@ adjust_breakpoint_address (struct gdbarch *gdbarch, adjusted_bpaddr = gdbarch_adjust_breakpoint_address (gdbarch, bpaddr); } - adjusted_bpaddr = address_significant (gdbarch, adjusted_bpaddr); + /* Don't cut out "insignificant" address bits on targets with + signed PC. */ + if (!gdbarch_pc_signed (gdbarch)) + adjusted_bpaddr = address_significant (gdbarch, adjusted_bpaddr); /* An adjusted breakpoint address can significantly alter a user's expectations. Print a warning if an adjustment diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index b8703e5a55..4d464c28f7 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -191,6 +191,7 @@ struct gdbarch int addr_bit; int dwarf2_addr_size; int char_signed; + int pc_signed; gdbarch_read_pc_ftype *read_pc; gdbarch_write_pc_ftype *write_pc; gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer; @@ -397,6 +398,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->floatformat_for_type = default_floatformat_for_type; gdbarch->ptr_bit = gdbarch->int_bit; gdbarch->char_signed = -1; + gdbarch->pc_signed = -1; gdbarch->virtual_frame_pointer = legacy_virtual_frame_pointer; gdbarch->num_regs = -1; gdbarch->sp_regnum = -1; @@ -550,6 +552,8 @@ verify_gdbarch (struct gdbarch *gdbarch) gdbarch->dwarf2_addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; if (gdbarch->char_signed == -1) gdbarch->char_signed = 1; + if (gdbarch->pc_signed == -1) + gdbarch->pc_signed = 0; /* Skip verify of read_pc, has predicate. */ /* Skip verify of write_pc, has predicate. */ /* Skip verify of virtual_frame_pointer, invalid_p == 0 */ @@ -1810,6 +1814,22 @@ set_gdbarch_wchar_signed (struct gdbarch *gdbarch, gdbarch->wchar_signed = wchar_signed; } +int +gdbarch_pc_signed (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->pc_signed != -1); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_signed called\n"); + return gdbarch->pc_signed; +} + +void +set_gdbarch_pc_signed (struct gdbarch *gdbarch, int pc_signed) +{ + gdbarch->pc_signed = pc_signed; +} + const struct floatformat ** gdbarch_floatformat_for_type (struct gdbarch *gdbarch, const char *name, int length) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 5cb131de1d..7af40154e0 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -194,6 +194,10 @@ extern void set_gdbarch_wchar_bit (struct gdbarch *gdbarch, int wchar_bit); extern int gdbarch_wchar_signed (struct gdbarch *gdbarch); extern void set_gdbarch_wchar_signed (struct gdbarch *gdbarch, int wchar_signed); +/* One if PC values are signed, zero if unsigned. */ +extern int gdbarch_pc_signed (struct gdbarch *gdbarch); +extern void set_gdbarch_pc_signed (struct gdbarch *gdbarch, int pc_signed); + /* Returns the floating-point format to be used for values of length LENGTH. NAME, if non-NULL, is the type name, which may be used to distinguish different target formats of the same length. */ diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index f9f84c4d48..6389bdbb95 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -8685,6 +8685,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Add/remove bits from an address. The MIPS needs be careful to ensure that all 32 bit addresses are sign extended to 64 bits. */ set_gdbarch_addr_bits_remove (gdbarch, mips_addr_bits_remove); + set_gdbarch_pc_signed(gdbarch, 1); /* Unwind the frame. */ set_gdbarch_unwind_pc (gdbarch, mips_unwind_pc);