mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-01 05:55:23 +08:00
S390: Fix for inadvertently setting 24-bit mode in fill_gregset
On 64-bit S390 platforms, for programs compiled with -m31, it could happen that GDB inadvertently cleared the inferior's 31-bit addressing mode bit and left the inferior running in 24-bit addressing mode. In particular this occurred with checkpoint.exp, when the "restore" command needed to create a new regcache copy: At the time when the PSWM register was copied over, the addressing mode bit was taken from the PSWA register, which was still zero since it had not been copied yet. And when the PSWA register was copied, the addressing mode was not updated again. The fix affects fill_gregset, where the bits "belonging" to each of the PSWA and PSWM registers are now carefully separated. The addressing mode bit is no longer touched when writing PSWM, and -- more importantly -- it *is* written when writing PSWA. gdb/ChangeLog: * s390-linux-nat.c (fill_gregset): Avoid relying on the PSWA register in the regcache when treating the PSWM register, and vice versa.
This commit is contained in:
parent
63fc80ce17
commit
2492f0d005
@ -1,3 +1,9 @@
|
||||
2015-05-08 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||
|
||||
* s390-linux-nat.c (fill_gregset): Avoid relying on the PSWA
|
||||
register in the regcache when treating the PSWM register, and vice
|
||||
versa.
|
||||
|
||||
2015-05-07 Gary Benson <gbenson@redhat.com>
|
||||
|
||||
* linux-thread-db.c (struct thread_db_info)
|
||||
|
@ -156,19 +156,29 @@ fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
ULONGEST pswa, pswm;
|
||||
gdb_byte buf[4];
|
||||
gdb_byte *pswm_p = (gdb_byte *) regp + S390_PSWM_OFFSET;
|
||||
gdb_byte *pswa_p = (gdb_byte *) regp + S390_PSWA_OFFSET;
|
||||
|
||||
regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
|
||||
pswm = extract_unsigned_integer (buf, 4, byte_order);
|
||||
regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
|
||||
pswa = extract_unsigned_integer (buf, 4, byte_order);
|
||||
pswm = extract_unsigned_integer (pswm_p, 8, byte_order);
|
||||
|
||||
if (regno == -1 || regno == S390_PSWM_REGNUM)
|
||||
store_unsigned_integer ((gdb_byte *) regp + S390_PSWM_OFFSET, 8,
|
||||
byte_order, ((pswm & 0xfff7ffff) << 32) |
|
||||
(pswa & 0x80000000));
|
||||
{
|
||||
pswm &= 0x80000000;
|
||||
regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
|
||||
pswm |= (extract_unsigned_integer (buf, 4, byte_order)
|
||||
& 0xfff7ffff) << 32;
|
||||
}
|
||||
|
||||
if (regno == -1 || regno == S390_PSWA_REGNUM)
|
||||
store_unsigned_integer ((gdb_byte *) regp + S390_PSWA_OFFSET, 8,
|
||||
byte_order, pswa & 0x7fffffff);
|
||||
{
|
||||
regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
|
||||
pswa = extract_unsigned_integer (buf, 4, byte_order);
|
||||
pswm ^= (pswm ^ pswa) & 0x80000000;
|
||||
pswa &= 0x7fffffff;
|
||||
store_unsigned_integer (pswa_p, 8, byte_order, pswa);
|
||||
}
|
||||
|
||||
store_unsigned_integer (pswm_p, 8, byte_order, pswm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user