diff options
-rw-r--r-- | gdb/gdbserver/ChangeLog | 27 | ||||
-rw-r--r-- | gdb/gdbserver/linux-arm-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-bfin-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-cris-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-crisv32-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-ia64-low.c | 45 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 10 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.h | 8 | ||||
-rw-r--r-- | gdb/gdbserver/linux-m32r-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-m68k-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-mips-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-ppc-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-s390-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-sh-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-sparc-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-tic6x-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-low.c | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-xtensa-low.c | 1 |
18 files changed, 102 insertions, 2 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index c99505f..8627aa9 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,30 @@ +2012-03-28 Pedro Alves <palves@redhat.com> + + * linux-ia64-low.c (ia64_regmap): Map IA64_EC_REGNUM to PT_AR_EC. + (IA64_GR0_REGNUM, IA64_FR0_REGNUM) + (IA64_FR1_REGNUM): New defines. + (ia64_fetch_register): New. + (the_low_target): Install it. + * linux-low.h (struct linux_target_ops) <fetch_register>: New + field. + * linux-low.c (linux_fetch_registers): Try the + the_low_target.fetch_register hook first. + + * linux-arm-low.c (the_low_target): Adjust. + * linux-bfin-low.c (the_low_target): Adjust. + * linux-cris-low.c (the_low_target): Adjust. + * linux-crisv32-low.c (the_low_target): Adjust. + * linux-m32r-low.c (the_low_target): Adjust. + * linux-m68k-low.c (the_low_target): Adjust. + * linux-mips-low.c (the_low_target): Adjust. + * linux-ppc-low.c (the_low_target): Adjust. + * linux-s390-low.c (the_low_target): Adjust. + * linux-sh-low.c (the_low_target): Adjust. + * linux-sparc-low.c (the_low_target): Adjust. + * linux-tic6x-low.c (the_low_target): Adjust. + * linux-x86-low.c (the_low_target): Adjust. + * linux-xtensa-low.c (the_low_target): Adjust. + 2012-03-26 Pedro Alves <palves@redhat.com> * server.c (handle_qxfer_libraries): Don't bail early if diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index 01208ef..bf1792b 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -837,6 +837,7 @@ struct linux_target_ops the_low_target = { NULL, arm_cannot_fetch_register, arm_cannot_store_register, + NULL, /* fetch_register */ arm_get_pc, arm_set_pc, diff --git a/gdb/gdbserver/linux-bfin-low.c b/gdb/gdbserver/linux-bfin-low.c index b6fe58a..d5b0361 100644 --- a/gdb/gdbserver/linux-bfin-low.c +++ b/gdb/gdbserver/linux-bfin-low.c @@ -97,6 +97,7 @@ struct linux_target_ops the_low_target = { NULL, bfin_cannot_fetch_register, bfin_cannot_store_register, + NULL, /* fetch_register */ bfin_get_pc, bfin_set_pc, bfin_breakpoint, diff --git a/gdb/gdbserver/linux-cris-low.c b/gdb/gdbserver/linux-cris-low.c index a399789..0c92e62 100644 --- a/gdb/gdbserver/linux-cris-low.c +++ b/gdb/gdbserver/linux-cris-low.c @@ -115,6 +115,7 @@ struct linux_target_ops the_low_target = { NULL, cris_cannot_fetch_register, cris_cannot_store_register, + NULL, /* fetch_register */ cris_get_pc, cris_set_pc, (const unsigned char *) &cris_breakpoint, diff --git a/gdb/gdbserver/linux-crisv32-low.c b/gdb/gdbserver/linux-crisv32-low.c index e33372d..1cc4cd1 100644 --- a/gdb/gdbserver/linux-crisv32-low.c +++ b/gdb/gdbserver/linux-crisv32-low.c @@ -377,6 +377,7 @@ struct linux_target_ops the_low_target = { NULL, NULL, NULL, + NULL, /* fetch_register */ cris_get_pc, cris_set_pc, (const unsigned char *) &cris_breakpoint, diff --git a/gdb/gdbserver/linux-ia64-low.c b/gdb/gdbserver/linux-ia64-low.c index 8753190..c8fa603 100644 --- a/gdb/gdbserver/linux-ia64-low.c +++ b/gdb/gdbserver/linux-ia64-low.c @@ -256,7 +256,7 @@ static int ia64_regmap[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, PT_AR_PFS, PT_AR_LC, - -1, /* Not available: EC, the Epilog Count register */ + PT_AR_EC, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -278,6 +278,48 @@ ia64_cannot_fetch_register (int regno) return 0; } +/* GDB register numbers. */ +#define IA64_GR0_REGNUM 0 +#define IA64_FR0_REGNUM 128 +#define IA64_FR1_REGNUM 129 + +static int +ia64_fetch_register (struct regcache *regcache, int regnum) +{ + /* r0 cannot be fetched but is always zero. */ + if (regnum == IA64_GR0_REGNUM) + { + const gdb_byte zero[8] = { 0 }; + + gdb_assert (sizeof (zero) == register_size (regnum)); + supply_register (regcache, regnum, zero); + return 1; + } + + /* fr0 cannot be fetched but is always zero. */ + if (regnum == IA64_FR0_REGNUM) + { + const gdb_byte f_zero[16] = { 0 }; + + gdb_assert (sizeof (f_zero) == register_size (regnum)); + supply_register (regcache, regnum, f_zero); + return 1; + } + + /* fr1 cannot be fetched but is always one (1.0). */ + if (regnum == IA64_FR1_REGNUM) + { + const gdb_byte f_one[16] = + { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 }; + + gdb_assert (sizeof (f_one) == register_size (regnum)); + supply_register (regcache, regnum, f_one); + return 1; + } + + return 0; +} + struct linux_target_ops the_low_target = { init_registers_ia64, ia64_num_regs, @@ -285,4 +327,5 @@ struct linux_target_ops the_low_target = { NULL, ia64_cannot_fetch_register, ia64_cannot_store_register, + ia64_fetch_register, }; diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 8becf78..aea8d36 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -4271,11 +4271,19 @@ linux_fetch_registers (struct regcache *regcache, int regno) if (regno == -1) { + if (the_low_target.fetch_register != NULL) + for (regno = 0; regno < the_low_target.num_regs; regno++) + (*the_low_target.fetch_register) (regcache, regno); + all = regsets_fetch_inferior_registers (regcache); - usr_fetch_inferior_registers (regcache, regno, all); + usr_fetch_inferior_registers (regcache, -1, all); } else { + if (the_low_target.fetch_register != NULL + && (*the_low_target.fetch_register) (regcache, regno)) + return; + use_regsets = linux_register_in_regsets (regno); if (use_regsets) all = regsets_fetch_inferior_registers (regcache); diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h index 3aeae70..07eda12 100644 --- a/gdb/gdbserver/linux-low.h +++ b/gdb/gdbserver/linux-low.h @@ -81,6 +81,14 @@ struct linux_target_ops store the register, and 2 if failure to store the register is acceptable. */ int (*cannot_store_register) (int); + + /* Hook to fetch a register in some non-standard way. Used for + example by backends that have read-only registers with hardcoded + values (e.g., IA64's gr0/fr0/fr1). Returns true if register + REGNO was supplied, false if not, and we should fallback to the + standard ptrace methods. */ + int (*fetch_register) (struct regcache *regcache, int regno); + CORE_ADDR (*get_pc) (struct regcache *regcache); void (*set_pc) (struct regcache *regcache, CORE_ADDR newpc); const unsigned char *breakpoint; diff --git a/gdb/gdbserver/linux-m32r-low.c b/gdb/gdbserver/linux-m32r-low.c index fd70cf2..29bb3f7 100644 --- a/gdb/gdbserver/linux-m32r-low.c +++ b/gdb/gdbserver/linux-m32r-low.c @@ -94,6 +94,7 @@ struct linux_target_ops the_low_target = { NULL, m32r_cannot_fetch_register, m32r_cannot_store_register, + NULL, /* fetch_register */ m32r_get_pc, m32r_set_pc, (const unsigned char *) &m32r_breakpoint, diff --git a/gdb/gdbserver/linux-m68k-low.c b/gdb/gdbserver/linux-m68k-low.c index a640e4c..6769dac 100644 --- a/gdb/gdbserver/linux-m68k-low.c +++ b/gdb/gdbserver/linux-m68k-low.c @@ -182,6 +182,7 @@ struct linux_target_ops the_low_target = { NULL, m68k_cannot_fetch_register, m68k_cannot_store_register, + NULL, /* fetch_register */ m68k_get_pc, m68k_set_pc, m68k_breakpoint, diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c index 1f58442..8e37298 100644 --- a/gdb/gdbserver/linux-mips-low.c +++ b/gdb/gdbserver/linux-mips-low.c @@ -430,6 +430,7 @@ struct linux_target_ops the_low_target = { NULL, mips_cannot_fetch_register, mips_cannot_store_register, + NULL, /* fetch_register */ mips_get_pc, mips_set_pc, (const unsigned char *) &mips_breakpoint, diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c index 518a59e..ed254fa 100644 --- a/gdb/gdbserver/linux-ppc-low.c +++ b/gdb/gdbserver/linux-ppc-low.c @@ -613,6 +613,7 @@ struct linux_target_ops the_low_target = { NULL, ppc_cannot_fetch_register, ppc_cannot_store_register, + NULL, /* fetch_register */ ppc_get_pc, ppc_set_pc, (const unsigned char *) &ppc_breakpoint, diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c index 8a32795..ea46206 100644 --- a/gdb/gdbserver/linux-s390-low.c +++ b/gdb/gdbserver/linux-s390-low.c @@ -464,6 +464,7 @@ struct linux_target_ops the_low_target = { NULL, s390_cannot_fetch_register, s390_cannot_store_register, + NULL, /* fetch_register */ s390_get_pc, s390_set_pc, s390_breakpoint, diff --git a/gdb/gdbserver/linux-sh-low.c b/gdb/gdbserver/linux-sh-low.c index e2537d6..fbd67c6 100644 --- a/gdb/gdbserver/linux-sh-low.c +++ b/gdb/gdbserver/linux-sh-low.c @@ -115,6 +115,7 @@ struct linux_target_ops the_low_target = { NULL, sh_cannot_fetch_register, sh_cannot_store_register, + NULL, /* fetch_register */ sh_get_pc, sh_set_pc, (const unsigned char *) &sh_breakpoint, diff --git a/gdb/gdbserver/linux-sparc-low.c b/gdb/gdbserver/linux-sparc-low.c index dc9c0cc..0460587 100644 --- a/gdb/gdbserver/linux-sparc-low.c +++ b/gdb/gdbserver/linux-sparc-low.c @@ -284,6 +284,7 @@ struct linux_target_ops the_low_target = { NULL, sparc_cannot_fetch_register, sparc_cannot_store_register, + NULL, /* fetch_register */ sparc_get_pc, /* No sparc_set_pc is needed. */ NULL, diff --git a/gdb/gdbserver/linux-tic6x-low.c b/gdb/gdbserver/linux-tic6x-low.c index db7c5a4..69d538b 100644 --- a/gdb/gdbserver/linux-tic6x-low.c +++ b/gdb/gdbserver/linux-tic6x-low.c @@ -324,6 +324,7 @@ struct linux_target_ops the_low_target = { NULL, tic6x_cannot_fetch_register, tic6x_cannot_store_register, + NULL, /* fetch_register */ tic6x_get_pc, tic6x_set_pc, (const unsigned char *) &tic6x_breakpoint, diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index b466b5d..7feb721 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -2969,6 +2969,7 @@ struct linux_target_ops the_low_target = NULL, NULL, NULL, + NULL, /* fetch_register */ x86_get_pc, x86_set_pc, x86_breakpoint, diff --git a/gdb/gdbserver/linux-xtensa-low.c b/gdb/gdbserver/linux-xtensa-low.c index bf7f064..34370f9 100644 --- a/gdb/gdbserver/linux-xtensa-low.c +++ b/gdb/gdbserver/linux-xtensa-low.c @@ -183,6 +183,7 @@ struct linux_target_ops the_low_target = { NULL, 0, 0, + NULL, /* fetch_register */ xtensa_get_pc, xtensa_set_pc, xtensa_breakpoint, |