From: John Baldwin Date: Fri, 28 Jan 2022 19:14:37 +0000 (-0800) Subject: regcache: Zero-extend small registers described by a register map. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b623bbc9a5b18a1100837450b7806de220068ccc;p=binutils-gdb.git 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. --- diff --git a/gdb/regcache.c b/gdb/regcache.c index ab45277e3b6..00d7a10e289 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. */