diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0955d648e7..5f6b41d731 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2020-03-19 Luis Machado + + * nat/aarch64-sve-linux-ptrace.c (aarch64_sve_set_vq): If vg is not + valid, fetch vg value from ptrace. + 2020-03-19 Kamil Rytarowski * x86-bsd-nat.c (gdb_ptrace): New. diff --git a/gdb/nat/aarch64-sve-linux-ptrace.c b/gdb/nat/aarch64-sve-linux-ptrace.c index b8f0711f9b..2ce90ccfd7 100644 --- a/gdb/nat/aarch64-sve-linux-ptrace.c +++ b/gdb/nat/aarch64-sve-linux-ptrace.c @@ -92,11 +92,26 @@ aarch64_sve_set_vq (int tid, uint64_t vq) bool aarch64_sve_set_vq (int tid, struct reg_buffer_common *reg_buf) { - if (reg_buf->get_register_status (AARCH64_SVE_VG_REGNUM) != REG_VALID) - return false; - uint64_t reg_vg = 0; - reg_buf->raw_collect (AARCH64_SVE_VG_REGNUM, ®_vg); + + /* The VG register may not be valid if we've not collected any value yet. + This can happen, for example, if we're restoring the regcache after an + inferior function call, and the VG register comes after the Z + registers. */ + if (reg_buf->get_register_status (AARCH64_SVE_VG_REGNUM) != REG_VALID) + { + /* If vg is not available yet, fetch it from ptrace. The VG value from + ptrace is likely the correct one. */ + uint64_t vq = aarch64_sve_get_vq (tid); + + /* If something went wrong, just bail out. */ + if (vq == 0) + return false; + + reg_vg = sve_vg_from_vq (vq); + } + else + reg_buf->raw_collect (AARCH64_SVE_VG_REGNUM, ®_vg); return aarch64_sve_set_vq (tid, sve_vq_from_vg (reg_vg)); }