diff options
-rw-r--r-- | gdb/arch-utils.c | 7 | ||||
-rw-r--r-- | gdb/arch-utils.h | 1 | ||||
-rw-r--r-- | gdb/gdbarch-components.py | 8 | ||||
-rw-r--r-- | gdb/gdbarch-gen.h | 4 | ||||
-rw-r--r-- | gdb/gdbarch.c | 22 | ||||
-rw-r--r-- | gdb/valops.c | 8 |
6 files changed, 49 insertions, 1 deletions
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 5218bfc..ade68bd 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -192,6 +192,13 @@ convert_from_func_ptr_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr, return addr; } +CORE_ADDR +convert_from_addr_func_ptr_identity (struct gdbarch *gdbarch, CORE_ADDR addr, + struct target_ops *targ) +{ + return addr; +} + int no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg) { diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index f6229f4..58fbff6 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -90,6 +90,7 @@ extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs); extern CORE_ADDR core_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr); extern gdbarch_convert_from_func_ptr_addr_ftype convert_from_func_ptr_addr_identity; +extern gdbarch_convert_from_addr_func_ptr_ftype convert_from_addr_func_ptr_identity; /* No-op conversion of reg to regnum. */ diff --git a/gdb/gdbarch-components.py b/gdb/gdbarch-components.py index b2c7b78..e9051db 100644 --- a/gdb/gdbarch-components.py +++ b/gdb/gdbarch-components.py @@ -1121,6 +1121,14 @@ Method( ) Method( + type="CORE_ADDR", + name="convert_from_addr_func_ptr", + params=[("CORE_ADDR", "addr"), ("struct target_ops *", "targ")], + predefault="convert_from_addr_func_ptr_identity", + invalid=False, +) + +Method( comment=""" On some machines there are bits in addresses which are not really part of the address, but are used by the kernel, the hardware, etc. diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index e0d7a08..be83db1 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -601,6 +601,10 @@ typedef CORE_ADDR (gdbarch_convert_from_func_ptr_addr_ftype) (struct gdbarch *gd extern CORE_ADDR gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ); extern void set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr); +typedef CORE_ADDR (gdbarch_convert_from_addr_func_ptr_ftype) (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ); +extern CORE_ADDR gdbarch_convert_from_addr_func_ptr (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ); +extern void set_gdbarch_convert_from_addr_func_ptr (struct gdbarch *gdbarch, gdbarch_convert_from_addr_func_ptr_ftype *convert_from_addr_func_ptr); + /* On some machines there are bits in addresses which are not really part of the address, but are used by the kernel, the hardware, etc. for special purposes. gdbarch_addr_bits_remove takes out any such bits so diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 9d929da..8519be9 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -141,6 +141,7 @@ struct gdbarch gdbarch_stabs_argument_has_addr_ftype *stabs_argument_has_addr = default_stabs_argument_has_addr; int frame_red_zone_size = 0; gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity; + gdbarch_convert_from_addr_func_ptr_ftype *convert_from_addr_func_ptr = convert_from_addr_func_ptr_identity; gdbarch_addr_bits_remove_ftype *addr_bits_remove = core_addr_identity; int significant_addr_bit = 0; gdbarch_memtag_to_string_ftype *memtag_to_string = default_memtag_to_string; @@ -397,6 +398,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of stabs_argument_has_addr, invalid_p == 0 */ /* Skip verify of frame_red_zone_size, invalid_p == 0 */ /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */ + /* Skip verify of convert_from_addr_func_ptr, invalid_p == 0 */ /* Skip verify of addr_bits_remove, invalid_p == 0 */ /* Skip verify of significant_addr_bit, invalid_p == 0 */ /* Skip verify of memtag_to_string, invalid_p == 0 */ @@ -877,6 +879,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: convert_from_func_ptr_addr = <%s>\n", host_address_to_string (gdbarch->convert_from_func_ptr_addr)); gdb_printf (file, + "gdbarch_dump: convert_from_addr_func_ptr = <%s>\n", + host_address_to_string (gdbarch->convert_from_addr_func_ptr)); + gdb_printf (file, "gdbarch_dump: addr_bits_remove = <%s>\n", host_address_to_string (gdbarch->addr_bits_remove)); gdb_printf (file, @@ -3062,6 +3067,23 @@ set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, } CORE_ADDR +gdbarch_convert_from_addr_func_ptr (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->convert_from_addr_func_ptr != NULL); + if (gdbarch_debug >= 2) + gdb_printf (gdb_stdlog, "gdbarch_convert_from_addr_func_ptr called\n"); + return gdbarch->convert_from_addr_func_ptr (gdbarch, addr, targ); +} + +void +set_gdbarch_convert_from_addr_func_ptr (struct gdbarch *gdbarch, + gdbarch_convert_from_addr_func_ptr_ftype convert_from_addr_func_ptr) +{ + gdbarch->convert_from_addr_func_ptr = convert_from_addr_func_ptr; +} + +CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr) { gdb_assert (gdbarch != NULL); diff --git a/gdb/valops.c b/gdb/valops.c index e90c394..f14fd41 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1527,12 +1527,18 @@ struct value * value_coerce_function (struct value *arg1) { struct value *retval; + CORE_ADDR addr; if (VALUE_LVAL (arg1) != lval_memory) error (_("Attempt to take address of value not located in memory.")); + addr = value_address (arg1); + addr = gdbarch_convert_from_addr_func_ptr (target_gdbarch, + addr, + ¤t_target); + retval = value_from_pointer (lookup_pointer_type (value_type (arg1)), - value_address (arg1)); + addr); return retval; } |