X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fia64-linux-nat.c;h=3bd4237ea20e9358245523100e192789eed364e5;hb=7d266584031b069cc16e33071c064cc65a555218;hp=19b827f84a66c656a526f0589b4d470542e03816;hpb=a5362b9aa469c18afd99a035c8556ee065bc6e93;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c index 19b827f84a..3bd4237ea2 100644 --- a/gdb/ia64-linux-nat.c +++ b/gdb/ia64-linux-nat.c @@ -1,7 +1,7 @@ /* Functions specific to running gdb native on IA-64 running GNU/Linux. - Copyright (C) 1999-2012 Free Software Foundation, Inc. + Copyright (C) 1999-2013 Free Software Foundation, Inc. This file is part of GDB. @@ -272,7 +272,7 @@ static int u_offsets[] = -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, @@ -447,8 +447,20 @@ supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp) { int regi; const char *from; + const gdb_byte f_zero[16] = { 0 }; + const gdb_byte f_one[16] = + { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 }; - for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++) + /* Kernel generated cores have fr1==0 instead of 1.0. Older GDBs + did the same. So ignore whatever might be recorded in fpregset_t + for fr0/fr1 and always supply their expected values. */ + + /* fr0 is always read as zero. */ + regcache_raw_supply (regcache, IA64_FR0_REGNUM, f_zero); + /* fr1 is always read as one (1.0). */ + regcache_raw_supply (regcache, IA64_FR1_REGNUM, f_one); + + for (regi = IA64_FR2_REGNUM; regi <= IA64_FR127_REGNUM; regi++) { from = (const char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]); regcache_raw_supply (regcache, regi, from); @@ -637,13 +649,14 @@ static int ia64_linux_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p) { CORE_ADDR psr; - siginfo_t *siginfo_p; + siginfo_t siginfo; struct regcache *regcache = get_current_regcache (); - siginfo_p = linux_nat_get_siginfo (inferior_ptid); + if (!linux_nat_get_siginfo (inferior_ptid, &siginfo)) + return 0; - if (siginfo_p->si_signo != SIGTRAP - || (siginfo_p->si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */) + if (siginfo.si_signo != SIGTRAP + || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */) return 0; regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr); @@ -651,7 +664,7 @@ ia64_linux_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p) for the next instruction. */ regcache_cooked_write_unsigned (regcache, IA64_PSR_REGNUM, psr); - *addr_p = (CORE_ADDR)siginfo_p->si_addr; + *addr_p = (CORE_ADDR) siginfo.si_addr; return 1; } @@ -680,6 +693,37 @@ ia64_linux_fetch_register (struct regcache *regcache, int regnum) PTRACE_TYPE_RET *buf; int pid, i; + /* 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 (gdbarch, regnum)); + regcache_raw_supply (regcache, regnum, zero); + return; + } + + /* 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 (gdbarch, regnum)); + regcache_raw_supply (regcache, regnum, f_zero); + return; + } + + /* 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 (gdbarch, regnum)); + regcache_raw_supply (regcache, regnum, f_one); + return; + } + if (ia64_cannot_fetch_register (gdbarch, regnum)) { regcache_raw_supply (regcache, regnum, NULL);