From 875e1767977dcd0cb4d169a80e42533838f96dd3 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Fri, 15 Jun 2001 22:10:21 +0000 Subject: [PATCH] multi-arch ADDR_BITS_REMOVE. --- gdb/ChangeLog | 11 +++++++++++ gdb/arch-utils.c | 2 +- gdb/arch-utils.h | 4 ++-- gdb/config/mips/tm-mips.h | 5 ----- gdb/defs.h | 13 ------------- gdb/gdbarch.c | 37 ++++++++++++++++++++++++++++++++++++- gdb/gdbarch.h | 26 +++++++++++++++++++++++++- gdb/gdbarch.sh | 12 +++++++++++- gdb/mips-tdep.c | 6 +++++- 9 files changed, 91 insertions(+), 25 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 06699abe032..c6f3aa38c0c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2001-06-15 Andrew Cagney + + * arch-utils.c (core_addr_identity): New function. Rename + default_convert_from_func_ptr_addr. + * gdbarch.sh (CONVERT_FROM_FUNC_PTR_ADDR): Update. + (ADDR_BITS_REMOVE): Define. Default to core_addr_identity. + * defs.h (ADDR_BITS_REMOVE): Delete macro definition. + * config/mips/tm-mips.h (ADDR_BITS_REMOVE): Delete definition. + * mips-tdep.c (mips_addr_bits_remove): Make static. + (mips_gdbarch_init): Initialize addr_bits_remove. + 2001-06-15 Andrew Cagney From 2001-02-26 D.J. Barrow : diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 46970013eb2..3300ce5f8b7 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -222,7 +222,7 @@ default_register_sim_regno (int num) CORE_ADDR -default_convert_from_func_ptr_addr (CORE_ADDR addr) +core_addr_identity (CORE_ADDR addr) { return addr; } diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index d468da6a589..51ad1e41e82 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -93,9 +93,9 @@ extern int (*target_architecture_hook) (const struct bfd_arch_info *); extern int default_register_sim_regno (int reg_nr); -/* Default conversion of function pointer address - returns address. */ +/* Identity function on a CORE_ADDR. Just returns its parameter. */ -extern CORE_ADDR default_convert_from_func_ptr_addr (CORE_ADDR addr); +extern CORE_ADDR core_addr_identity (CORE_ADDR addr); /* No-op conversion of reg to regnum. */ diff --git a/gdb/config/mips/tm-mips.h b/gdb/config/mips/tm-mips.h index 447c9e79012..8c288602db0 100644 --- a/gdb/config/mips/tm-mips.h +++ b/gdb/config/mips/tm-mips.h @@ -55,11 +55,6 @@ struct value; #define DEFAULT_MIPS_TYPE "generic" -/* Remove useless bits from an instruction address. */ - -#define ADDR_BITS_REMOVE(addr) mips_addr_bits_remove(addr) -CORE_ADDR mips_addr_bits_remove (CORE_ADDR addr); - /* Remove useless bits from the stack pointer. */ #define TARGET_READ_SP() ADDR_BITS_REMOVE (read_register (SP_REGNUM)) diff --git a/gdb/defs.h b/gdb/defs.h index 56d8d7b4c80..03113d56614 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -1259,19 +1259,6 @@ extern char *floatformat_mantissa (const struct floatformat *, char *); extern DOUBLEST extract_floating (void *, int); extern void store_floating (void *, int, DOUBLEST); -/* 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. ADDR_BITS_REMOVE takes out any such bits - so we get a "real" address such as one would find in a symbol - table. This is used only for addresses of instructions, and even then - I'm not sure it's used in all contexts. It exists to deal with there - being a few stray bits in the PC which would mislead us, not as some sort - of generic thing to handle alignment or segmentation (it's possible it - should be in TARGET_READ_PC instead). */ -#if !defined (ADDR_BITS_REMOVE) -#define ADDR_BITS_REMOVE(addr) (addr) -#endif /* No ADDR_BITS_REMOVE. */ - /* From valops.c */ extern CORE_ADDR push_bytes (CORE_ADDR, char *, int); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 435b36cc450..fcfe9ac6599 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -247,6 +247,7 @@ struct gdbarch const struct floatformat * double_format; const struct floatformat * long_double_format; gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr; + gdbarch_addr_bits_remove_ftype *addr_bits_remove; gdbarch_software_single_step_ftype *software_single_step; }; @@ -382,6 +383,7 @@ struct gdbarch startup_gdbarch = 0, 0, 0, + 0, /* startup_gdbarch() */ }; @@ -474,7 +476,8 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->frame_args_skip = -1; gdbarch->frameless_function_invocation = generic_frameless_function_invocation_not; gdbarch->extra_stack_alignment_needed = 1; - gdbarch->convert_from_func_ptr_addr = default_convert_from_func_ptr_addr; + gdbarch->convert_from_func_ptr_addr = core_addr_identity; + gdbarch->addr_bits_remove = core_addr_identity; /* gdbarch_alloc() */ return gdbarch; @@ -769,6 +772,7 @@ verify_gdbarch (struct gdbarch *gdbarch) if (gdbarch->long_double_format == 0) gdbarch->long_double_format = &floatformat_unknown; /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */ + /* Skip verify of addr_bits_remove, invalid_p == 0 */ /* Skip verify of software_single_step, has predicate */ } @@ -1451,6 +1455,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "CONVERT_FROM_FUNC_PTR_ADDR(addr)", XSTRING (CONVERT_FROM_FUNC_PTR_ADDR (addr))); #endif +#ifdef ADDR_BITS_REMOVE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "ADDR_BITS_REMOVE(addr)", + XSTRING (ADDR_BITS_REMOVE (addr))); +#endif #if defined (SOFTWARE_SINGLE_STEP) && GDB_MULTI_ARCH /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, @@ -2183,6 +2193,13 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) (long) current_gdbarch->convert_from_func_ptr_addr /*CONVERT_FROM_FUNC_PTR_ADDR ()*/); #endif +#ifdef ADDR_BITS_REMOVE + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, + "gdbarch_dump: ADDR_BITS_REMOVE = 0x%08lx\n", + (long) current_gdbarch->addr_bits_remove + /*ADDR_BITS_REMOVE ()*/); +#endif #ifdef SOFTWARE_SINGLE_STEP if (GDB_MULTI_ARCH) fprintf_unfiltered (file, @@ -4279,6 +4296,24 @@ set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr; } +CORE_ADDR +gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + if (gdbarch->addr_bits_remove == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_addr_bits_remove invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_addr_bits_remove called\n"); + return gdbarch->addr_bits_remove (addr); +} + +void +set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, + gdbarch_addr_bits_remove_ftype addr_bits_remove) +{ + gdbarch->addr_bits_remove = addr_bits_remove; +} + int gdbarch_software_single_step_p (struct gdbarch *gdbarch) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 51cc4401af8..ddea0c0a101 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1513,7 +1513,7 @@ extern void set_gdbarch_long_double_format (struct gdbarch *gdbarch, const struc /* Default (function) for non- multi-arch platforms. */ #if (!GDB_MULTI_ARCH) && !defined (CONVERT_FROM_FUNC_PTR_ADDR) -#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (default_convert_from_func_ptr_addr (addr)) +#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (core_addr_identity (addr)) #endif typedef CORE_ADDR (gdbarch_convert_from_func_ptr_addr_ftype) (CORE_ADDR addr); @@ -1525,6 +1525,30 @@ extern void set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdb #endif #endif +/* 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. ADDR_BITS_REMOVE takes out any such bits so + we get a "real" address such as one would find in a symbol table. + This is used only for addresses of instructions, and even then I'm + not sure it's used in all contexts. It exists to deal with there + being a few stray bits in the PC which would mislead us, not as some + sort of generic thing to handle alignment or segmentation (it's + possible it should be in TARGET_READ_PC instead). */ + +/* Default (function) for non- multi-arch platforms. */ +#if (!GDB_MULTI_ARCH) && !defined (ADDR_BITS_REMOVE) +#define ADDR_BITS_REMOVE(addr) (core_addr_identity (addr)) +#endif + +typedef CORE_ADDR (gdbarch_addr_bits_remove_ftype) (CORE_ADDR addr); +extern CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr); +extern void set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch_addr_bits_remove_ftype *addr_bits_remove); +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDR_BITS_REMOVE) +#define ADDR_BITS_REMOVE(addr) (gdbarch_addr_bits_remove (current_gdbarch, addr)) +#endif +#endif + /* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if the target needs software single step. An ISA method to implement it. diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 5a91981ba11..1fb598a915a 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -513,7 +513,17 @@ v:2:PARM_BOUNDARY:int:parm_boundary v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch) v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch) v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::&floatformat_unknown -f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::default_convert_from_func_ptr_addr::0 +f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::core_addr_identity::0 +# 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. ADDR_BITS_REMOVE takes out any such bits so +# we get a "real" address such as one would find in a symbol table. +# This is used only for addresses of instructions, and even then I'm +# not sure it's used in all contexts. It exists to deal with there +# being a few stray bits in the PC which would mislead us, not as some +# sort of generic thing to handle alignment or segmentation (it's +# possible it should be in TARGET_READ_PC instead). +f:2:ADDR_BITS_REMOVE:CORE_ADDR:addr_bits_remove:CORE_ADDR addr:addr:::core_addr_identity::0 # FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if # the target needs software single step. An ISA method to implement it. # diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 4ecc92521eb..2d86b5e5e8b 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1340,7 +1340,7 @@ read_next_frame_reg (struct frame_info *fi, int regno) /* mips_addr_bits_remove - remove useless address bits */ -CORE_ADDR +static CORE_ADDR mips_addr_bits_remove (CORE_ADDR addr) { if (GDB_TARGET_IS_MIPS64) @@ -4123,6 +4123,10 @@ mips_gdbarch_init (struct gdbarch_info info, set_gdbarch_read_sp (gdbarch, generic_target_read_sp); set_gdbarch_write_sp (gdbarch, generic_target_write_sp); + /* 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); + /* Map debug register numbers onto internal register numbers. */ set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum); set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_ecoff_reg_to_regnum); -- 2.30.2