aboutsummaryrefslogtreecommitdiff
path: root/gdb/regcache.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-01-28 11:14:37 -0800
committerJohn Baldwin <jhb@FreeBSD.org>2022-01-28 11:14:37 -0800
commitb623bbc9a5b18a1100837450b7806de220068ccc (patch)
tree8b94746b5789f82327160a098359ba69b2e453f1 /gdb/regcache.c
parent5046f3c8c0cf0a641f25cf0b3f6e3a6969f28dd8 (diff)
downloadfsf-binutils-gdb-b623bbc9a5b18a1100837450b7806de220068ccc.zip
fsf-binutils-gdb-b623bbc9a5b18a1100837450b7806de220068ccc.tar.gz
fsf-binutils-gdb-b623bbc9a5b18a1100837450b7806de220068ccc.tar.bz2
regcache: Zero-extend small registers described by a register map.
When registers are supplied via regcache_supply_register from a register block described by a register map, registers may be stored in slots smaller than GDB's native register size (e.g. x86 segment registers are 16 bits, but the GDB registers for those are 32-bits). regcache_collect_regset is careful to zero-extend slots larger than a register size, but regcache_supply_regset just used regcache::raw_supply_part and did not initialize the upper bytes of a register value. trad_frame_set_reg_regmap assumes these semantics (zero-extending short registers). Upcoming patches also require these semantics for handling x86 segment register values stored in 16-bit slots on FreeBSD. Note that architecturally x86 segment registers are 16 bits, but the x86 gdb architectures treat these registers as 32 bits.
Diffstat (limited to 'gdb/regcache.c')
-rw-r--r--gdb/regcache.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/gdb/regcache.c b/gdb/regcache.c
index ab45277..00d7a10 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1164,7 +1164,12 @@ regcache::transfer_regset_register (struct regcache *out_regcache, int regnum,
memset (out_buf + offs + reg_size, 0, slot_size - reg_size);
}
else if (in_buf != nullptr)
- out_regcache->raw_supply_part (regnum, 0, reg_size, in_buf + offs);
+ {
+ /* Zero-extend the register value if the slot is smaller than the register. */
+ if (slot_size < register_size (gdbarch, regnum))
+ out_regcache->raw_supply_zeroed (regnum);
+ out_regcache->raw_supply_part (regnum, 0, reg_size, in_buf + offs);
+ }
else
{
/* Invalidate the register. */