From 4db10d8f4911298d06d2bb25927946f66f0f33e3 Mon Sep 17 00:00:00 2001 From: Pedro Franco de Carvalho Date: Mon, 30 Mar 2020 12:04:25 -0300 Subject: [PATCH] [PowerPC] Move up some register access routines Keep the routines related to register access grouped together. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho * ppc-linux-nat.c (ppc_linux_nat_target::store_registers) (ppc_linux_nat_target::auxv_parse) (ppc_linux_nat_target::read_description) (supply_gregset, fill_gregset, supply_fpregset, fill_fpregset): Move up. --- gdb/ChangeLog | 8 ++ gdb/ppc-linux-nat.c | 328 ++++++++++++++++++++++---------------------- 2 files changed, 172 insertions(+), 164 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 61f01ab2438..f0e0bc7e5de 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2020-03-30 Pedro Franco de Carvalho + + * ppc-linux-nat.c (ppc_linux_nat_target::store_registers) + (ppc_linux_nat_target::auxv_parse) + (ppc_linux_nat_target::read_description) + (supply_gregset, fill_gregset, supply_fpregset, fill_fpregset): + Move up. + 2020-03-30 Pedro Franco de Carvalho * linux-nat.h (low_new_clone): New method. diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 27fa7f93e2b..22954062341 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -1555,6 +1555,170 @@ store_ppc_registers (const struct regcache *regcache, int tid) function to fail most of the time, so we ignore them. */ } +void +ppc_linux_nat_target::store_registers (struct regcache *regcache, int regno) +{ + pid_t tid = get_ptrace_pid (regcache->ptid ()); + + if (regno >= 0) + store_register (regcache, tid, regno); + else + store_ppc_registers (regcache, tid); +} + +/* Functions for transferring registers between a gregset_t or fpregset_t + (see sys/ucontext.h) and gdb's regcache. The word size is that used + by the ptrace interface, not the current program's ABI. Eg. if a + powerpc64-linux gdb is being used to debug a powerpc32-linux app, we + read or write 64-bit gregsets. This is to suit the host libthread_db. */ + +void +supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) +{ + const struct regset *regset = ppc_linux_gregset (sizeof (long)); + + ppc_supply_gregset (regset, regcache, -1, gregsetp, sizeof (*gregsetp)); +} + +void +fill_gregset (const struct regcache *regcache, + gdb_gregset_t *gregsetp, int regno) +{ + const struct regset *regset = ppc_linux_gregset (sizeof (long)); + + if (regno == -1) + memset (gregsetp, 0, sizeof (*gregsetp)); + ppc_collect_gregset (regset, regcache, regno, gregsetp, sizeof (*gregsetp)); +} + +void +supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp) +{ + const struct regset *regset = ppc_linux_fpregset (); + + ppc_supply_fpregset (regset, regcache, -1, + fpregsetp, sizeof (*fpregsetp)); +} + +void +fill_fpregset (const struct regcache *regcache, + gdb_fpregset_t *fpregsetp, int regno) +{ + const struct regset *regset = ppc_linux_fpregset (); + + ppc_collect_fpregset (regset, regcache, regno, + fpregsetp, sizeof (*fpregsetp)); +} + +int +ppc_linux_nat_target::auxv_parse (gdb_byte **readptr, + gdb_byte *endptr, CORE_ADDR *typep, + CORE_ADDR *valp) +{ + int tid = inferior_ptid.lwp (); + if (tid == 0) + tid = inferior_ptid.pid (); + + int sizeof_auxv_field = ppc_linux_target_wordsize (tid); + + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); + gdb_byte *ptr = *readptr; + + if (endptr == ptr) + return 0; + + if (endptr - ptr < sizeof_auxv_field * 2) + return -1; + + *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); + ptr += sizeof_auxv_field; + *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); + ptr += sizeof_auxv_field; + + *readptr = ptr; + return 1; +} + +const struct target_desc * +ppc_linux_nat_target::read_description () +{ + int tid = inferior_ptid.lwp (); + if (tid == 0) + tid = inferior_ptid.pid (); + + if (have_ptrace_getsetevrregs) + { + struct gdb_evrregset_t evrregset; + + if (ptrace (PTRACE_GETEVRREGS, tid, 0, &evrregset) >= 0) + return tdesc_powerpc_e500l; + + /* EIO means that the PTRACE_GETEVRREGS request isn't supported. + Anything else needs to be reported. */ + else if (errno != EIO) + perror_with_name (_("Unable to fetch SPE registers")); + } + + struct ppc_linux_features features = ppc_linux_no_features; + + features.wordsize = ppc_linux_target_wordsize (tid); + + CORE_ADDR hwcap = linux_get_hwcap (current_top_target ()); + CORE_ADDR hwcap2 = linux_get_hwcap2 (current_top_target ()); + + if (have_ptrace_getsetvsxregs + && (hwcap & PPC_FEATURE_HAS_VSX)) + { + gdb_vsxregset_t vsxregset; + + if (ptrace (PTRACE_GETVSXREGS, tid, 0, &vsxregset) >= 0) + features.vsx = true; + + /* EIO means that the PTRACE_GETVSXREGS request isn't supported. + Anything else needs to be reported. */ + else if (errno != EIO) + perror_with_name (_("Unable to fetch VSX registers")); + } + + if (have_ptrace_getvrregs + && (hwcap & PPC_FEATURE_HAS_ALTIVEC)) + { + gdb_vrregset_t vrregset; + + if (ptrace (PTRACE_GETVRREGS, tid, 0, &vrregset) >= 0) + features.altivec = true; + + /* EIO means that the PTRACE_GETVRREGS request isn't supported. + Anything else needs to be reported. */ + else if (errno != EIO) + perror_with_name (_("Unable to fetch AltiVec registers")); + } + + features.isa205 = ppc_linux_has_isa205 (hwcap); + + if ((hwcap2 & PPC_FEATURE2_DSCR) + && check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET) + && check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET)) + { + features.ppr_dscr = true; + if ((hwcap2 & PPC_FEATURE2_ARCH_2_07) + && (hwcap2 & PPC_FEATURE2_TAR) + && (hwcap2 & PPC_FEATURE2_EBB) + && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET) + && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET) + && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET)) + { + features.isa207 = true; + if ((hwcap2 & PPC_FEATURE2_HTM) + && check_regset (tid, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET)) + features.htm = true; + } + } + + return ppc_linux_match_description (features); +} + /* The cached DABR value, to install in new threads. This variable is used when the PowerPC HWDEBUG ptrace interface is not available. */ @@ -2507,170 +2671,6 @@ ppc_linux_nat_target::masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask return 2; } -void -ppc_linux_nat_target::store_registers (struct regcache *regcache, int regno) -{ - pid_t tid = get_ptrace_pid (regcache->ptid ()); - - if (regno >= 0) - store_register (regcache, tid, regno); - else - store_ppc_registers (regcache, tid); -} - -/* Functions for transferring registers between a gregset_t or fpregset_t - (see sys/ucontext.h) and gdb's regcache. The word size is that used - by the ptrace interface, not the current program's ABI. Eg. if a - powerpc64-linux gdb is being used to debug a powerpc32-linux app, we - read or write 64-bit gregsets. This is to suit the host libthread_db. */ - -void -supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) -{ - const struct regset *regset = ppc_linux_gregset (sizeof (long)); - - ppc_supply_gregset (regset, regcache, -1, gregsetp, sizeof (*gregsetp)); -} - -void -fill_gregset (const struct regcache *regcache, - gdb_gregset_t *gregsetp, int regno) -{ - const struct regset *regset = ppc_linux_gregset (sizeof (long)); - - if (regno == -1) - memset (gregsetp, 0, sizeof (*gregsetp)); - ppc_collect_gregset (regset, regcache, regno, gregsetp, sizeof (*gregsetp)); -} - -void -supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp) -{ - const struct regset *regset = ppc_linux_fpregset (); - - ppc_supply_fpregset (regset, regcache, -1, - fpregsetp, sizeof (*fpregsetp)); -} - -void -fill_fpregset (const struct regcache *regcache, - gdb_fpregset_t *fpregsetp, int regno) -{ - const struct regset *regset = ppc_linux_fpregset (); - - ppc_collect_fpregset (regset, regcache, regno, - fpregsetp, sizeof (*fpregsetp)); -} - -int -ppc_linux_nat_target::auxv_parse (gdb_byte **readptr, - gdb_byte *endptr, CORE_ADDR *typep, - CORE_ADDR *valp) -{ - int tid = inferior_ptid.lwp (); - if (tid == 0) - tid = inferior_ptid.pid (); - - int sizeof_auxv_field = ppc_linux_target_wordsize (tid); - - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); - gdb_byte *ptr = *readptr; - - if (endptr == ptr) - return 0; - - if (endptr - ptr < sizeof_auxv_field * 2) - return -1; - - *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); - ptr += sizeof_auxv_field; - *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); - ptr += sizeof_auxv_field; - - *readptr = ptr; - return 1; -} - -const struct target_desc * -ppc_linux_nat_target::read_description () -{ - int tid = inferior_ptid.lwp (); - if (tid == 0) - tid = inferior_ptid.pid (); - - if (have_ptrace_getsetevrregs) - { - struct gdb_evrregset_t evrregset; - - if (ptrace (PTRACE_GETEVRREGS, tid, 0, &evrregset) >= 0) - return tdesc_powerpc_e500l; - - /* EIO means that the PTRACE_GETEVRREGS request isn't supported. - Anything else needs to be reported. */ - else if (errno != EIO) - perror_with_name (_("Unable to fetch SPE registers")); - } - - struct ppc_linux_features features = ppc_linux_no_features; - - features.wordsize = ppc_linux_target_wordsize (tid); - - CORE_ADDR hwcap = linux_get_hwcap (current_top_target ()); - CORE_ADDR hwcap2 = linux_get_hwcap2 (current_top_target ()); - - if (have_ptrace_getsetvsxregs - && (hwcap & PPC_FEATURE_HAS_VSX)) - { - gdb_vsxregset_t vsxregset; - - if (ptrace (PTRACE_GETVSXREGS, tid, 0, &vsxregset) >= 0) - features.vsx = true; - - /* EIO means that the PTRACE_GETVSXREGS request isn't supported. - Anything else needs to be reported. */ - else if (errno != EIO) - perror_with_name (_("Unable to fetch VSX registers")); - } - - if (have_ptrace_getvrregs - && (hwcap & PPC_FEATURE_HAS_ALTIVEC)) - { - gdb_vrregset_t vrregset; - - if (ptrace (PTRACE_GETVRREGS, tid, 0, &vrregset) >= 0) - features.altivec = true; - - /* EIO means that the PTRACE_GETVRREGS request isn't supported. - Anything else needs to be reported. */ - else if (errno != EIO) - perror_with_name (_("Unable to fetch AltiVec registers")); - } - - features.isa205 = ppc_linux_has_isa205 (hwcap); - - if ((hwcap2 & PPC_FEATURE2_DSCR) - && check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET) - && check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET)) - { - features.ppr_dscr = true; - if ((hwcap2 & PPC_FEATURE2_ARCH_2_07) - && (hwcap2 & PPC_FEATURE2_TAR) - && (hwcap2 & PPC_FEATURE2_EBB) - && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET) - && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET) - && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET)) - { - features.isa207 = true; - if ((hwcap2 & PPC_FEATURE2_HTM) - && check_regset (tid, NT_PPC_TM_SPR, - PPC_LINUX_SIZEOF_TM_SPRREGSET)) - features.htm = true; - } - } - - return ppc_linux_match_description (features); -} - void _initialize_ppc_linux_nat (); void _initialize_ppc_linux_nat () -- 2.30.2