diff options
author | Luis Machado <luis.machado@arm.com> | 2023-03-17 21:23:59 +0000 |
---|---|---|
committer | Luis Machado <luis.machado@arm.com> | 2023-10-04 16:23:39 +0100 |
commit | 15f38ed1016b9809848b13994fc06b058c1289ad (patch) | |
tree | 8d739803a9fd4756eb781212481ed6dc28dbd36f /gdb/aarch64-linux-nat.c | |
parent | 5dd233b31414abfe10680baf63462f6d5fa8f139 (diff) | |
download | gdb-15f38ed1016b9809848b13994fc06b058c1289ad.zip gdb-15f38ed1016b9809848b13994fc06b058c1289ad.tar.gz gdb-15f38ed1016b9809848b13994fc06b058c1289ad.tar.bz2 |
Fix register fetch/store order for native AArch64 Linux
I noticed we don't handle register reads/writes in the best way for native
AArch64 Linux. Some other registers are fetched/stored even if upper level
code told us to fetch a particular register number.
Fix this by being more strict about which registers we touch when
reading/writing them in the native AArch64 Linux layer.
There should be no user-visible changes due to this patch.
Regression-tested on aarch64-linux Ubuntu 22.04/20.04.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Diffstat (limited to 'gdb/aarch64-linux-nat.c')
-rw-r--r-- | gdb/aarch64-linux-nat.c | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index eeb9761..8844fc7 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -504,6 +504,7 @@ aarch64_fetch_registers (struct regcache *regcache, int regno) aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ()); + /* Do we need to fetch all registers? */ if (regno == -1) { fetch_gregs_from_thread (regcache); @@ -521,28 +522,28 @@ aarch64_fetch_registers (struct regcache *regcache, int regno) if (tdep->has_tls ()) fetch_tlsregs_from_thread (regcache); } + /* General purpose register? */ else if (regno < AARCH64_V0_REGNUM) fetch_gregs_from_thread (regcache); - else if (tdep->has_sve ()) + /* SVE register? */ + else if (tdep->has_sve () && regno <= AARCH64_SVE_VG_REGNUM) fetch_sveregs_from_thread (regcache); - else + /* FPSIMD register? */ + else if (regno <= AARCH64_FPCR_REGNUM) fetch_fpregs_from_thread (regcache); - - if (tdep->has_pauth ()) - { - if (regno == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base) - || regno == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base)) - fetch_pauth_masks_from_thread (regcache); - } - - /* Fetch individual MTE registers. */ - if (tdep->has_mte () - && (regno == tdep->mte_reg_base)) + /* PAuth register? */ + else if (tdep->has_pauth () + && (regno == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base) + || regno == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base))) + fetch_pauth_masks_from_thread (regcache); + /* MTE register? */ + else if (tdep->has_mte () + && (regno == tdep->mte_reg_base)) fetch_mteregs_from_thread (regcache); - - if (tdep->has_tls () - && regno >= tdep->tls_regnum_base - && regno < tdep->tls_regnum_base + tdep->tls_register_count) + /* TLS register? */ + else if (tdep->has_tls () + && regno >= tdep->tls_regnum_base + && regno < tdep->tls_regnum_base + tdep->tls_register_count) fetch_tlsregs_from_thread (regcache); } @@ -592,6 +593,7 @@ aarch64_store_registers (struct regcache *regcache, int regno) aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ()); + /* Do we need to store all registers? */ if (regno == -1) { store_gregs_to_thread (regcache); @@ -606,22 +608,26 @@ aarch64_store_registers (struct regcache *regcache, int regno) if (tdep->has_tls ()) store_tlsregs_to_thread (regcache); } + /* General purpose register? */ else if (regno < AARCH64_V0_REGNUM) store_gregs_to_thread (regcache); - else if (tdep->has_sve ()) + /* SVE register? */ + else if (tdep->has_sve () && regno <= AARCH64_SVE_VG_REGNUM) store_sveregs_to_thread (regcache); - else + /* FPSIMD register? */ + else if (regno <= AARCH64_FPCR_REGNUM) store_fpregs_to_thread (regcache); - - /* Store MTE registers. */ - if (tdep->has_mte () - && (regno == tdep->mte_reg_base)) + /* MTE register? */ + else if (tdep->has_mte () + && (regno == tdep->mte_reg_base)) store_mteregs_to_thread (regcache); - - if (tdep->has_tls () - && regno >= tdep->tls_regnum_base - && regno < tdep->tls_regnum_base + tdep->tls_register_count) + /* TLS register? */ + else if (tdep->has_tls () + && regno >= tdep->tls_regnum_base + && regno < tdep->tls_regnum_base + tdep->tls_register_count) store_tlsregs_to_thread (regcache); + + /* PAuth registers are read-only. */ } /* A version of the "store_registers" target_ops method used when running |