[PATCH] gdbarch: Add pc_signed field and use it when adjusting BP addresses
vlad.ivanov@lab-systems.ru
vlad.ivanov@lab-systems.ru
Thu Mar 15 11:22:00 GMT 2018
From: Vlad Ivanov <vlad.ivanov@lab-systems.ru>
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);
--
2.14.3
More information about the Gdb-patches
mailing list