Skip to content

Commit 4da037e

Browse files
committed
AArch64 SVE: Check for vector length change when getting gdbarch
Override the thread_architecture method, similar to SPU. If the vector length has changed, then find the arch using info, making sure the vector length is passed down to the init routine. In the init routine, ensure the arch has the correct vector length. Example output. Program is stopped in thread 2, just before it calls prctl to change the vector length (gdb) info threads Id Target Id Frame 1 Thread 0xffffbf6f4000 (LWP 3188) "sve_change" 0x0000ffffbf6ae130 in pthread_join () * 2 Thread 0xffffbf55e200 (LWP 3189) "sve_change" thread1 (arg=0xfeedface) at sve_change_size.c:28 (gdb) print $vg $1 = 8 (gdb) print $z0.s.u $2 = {623191333, 623191333, 623191333, 623191333, 0 <repeats 12 times>} (gdb) n 29 int ret = prctl(PR_SVE_SET_VL, vl/2); (gdb) n 30 printf ("Changed: ret\n", ret); (gdb) print $vg $4 = 4 (gdb) print $z0.s.u $5 = {623191333, 623191333, 623191333, 623191333, 0, 0, 0, 0} (gdb) thr 1 [Switching to thread 1 (Thread 0xffffbf6f4000 (LWP 3181))] (gdb) print $vg $6 = 8 (gdb) print $z0.s.u $7 = {623191333, 623191333, 623191333, 623191333, 0 <repeats 12 times>} gdb/ChangeLog: * aarch64-linux-nat.c (aarch64_linux_nat_target::thread_architecture): Add override. * aarch64-tdep.c (aarch64_gdbarch_init): Ensure different tdesc for each VQ.
1 parent ccb8d7e commit 4da037e

3 files changed

Lines changed: 59 additions & 5 deletions

File tree

‎gdb/ChangeLog‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2019-04-15 Alan Hayward <alan.hayward@arm.com>
2+
3+
* aarch64-linux-nat.c
4+
(aarch64_linux_nat_target::thread_architecture): Add override.
5+
* aarch64-tdep.c (aarch64_gdbarch_init): Ensure different tdesc for
6+
each VQ.
7+
18
2019-04-15 Alan Hayward <alan.hayward@arm.com>
29

310
* aarch64-tdep.c (aarch64_gdbarch_init): Move gdbarch lookup.

‎gdb/aarch64-linux-nat.c‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
/* Defines ps_err_e, struct ps_prochandle. */
4848
#include "gdb_proc_service.h"
49+
#include "arch-utils.h"
4950

5051
#ifndef TRAP_HWBKPT
5152
#define TRAP_HWBKPT 0x0004
@@ -95,6 +96,8 @@ class aarch64_linux_nat_target final : public linux_nat_target
9596
/* Add our siginfo layout converter. */
9697
bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
9798
override;
99+
100+
struct gdbarch *thread_architecture (ptid_t) override;
98101
};
99102

100103
static aarch64_linux_nat_target the_aarch64_linux_nat_target;
@@ -939,6 +942,34 @@ aarch64_linux_nat_target::can_do_single_step ()
939942
return 1;
940943
}
941944

945+
/* Implement the "thread_architecture" target_ops method. */
946+
947+
struct gdbarch *
948+
aarch64_linux_nat_target::thread_architecture (ptid_t ptid)
949+
{
950+
/* Return the gdbarch for the current thread. If the vector length has
951+
changed since the last time this was called, then do a further lookup. */
952+
953+
uint64_t vq = aarch64_sve_get_vq (ptid.lwp ());
954+
955+
/* Find the current gdbarch the same way as process_stratum_target. Only
956+
return it if the current vector length matches the one in the tdep. */
957+
inferior *inf = find_inferior_ptid (ptid);
958+
gdb_assert (inf != NULL);
959+
if (vq == gdbarch_tdep (inf->gdbarch)->vq)
960+
return inf->gdbarch;
961+
962+
/* We reach here if the vector length for the thread is different from its
963+
value at process start. Lookup gdbarch via info (potentially creating a
964+
new one), stashing the vector length inside id. Use -1 for when SVE
965+
unavailable, to distinguish from an unset value of 0. */
966+
struct gdbarch_info info;
967+
gdbarch_info_init (&info);
968+
info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
969+
info.id = (int *) (vq == 0 ? -1 : vq);
970+
return gdbarch_find_by_info (info);
971+
}
972+
942973
/* Define AArch64 maintenance commands. */
943974

944975
static void

‎gdb/aarch64-tdep.c‎

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3198,20 +3198,36 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
31983198
int i, num_regs = 0, num_pseudo_regs = 0;
31993199
int first_pauth_regnum = -1, pauth_ra_state_offset = -1;
32003200

3201+
/* Use the vector length passed via the target info. Here -1 is used for no
3202+
SVE, and 0 is unset. If unset then use the vector length from the existing
3203+
tdesc. */
3204+
uint64_t vq = 0;
3205+
if (info.id == (int *) -1)
3206+
vq = 0;
3207+
else if (info.id != 0)
3208+
vq = (uint64_t) info.id;
3209+
else
3210+
vq = aarch64_get_tdesc_vq (info.target_desc);
3211+
3212+
if (vq > AARCH64_MAX_SVE_VQ)
3213+
internal_error (__FILE__, __LINE__, _("VQ out of bounds: %ld (max %d)"),
3214+
vq, AARCH64_MAX_SVE_VQ);
3215+
32013216
/* If there is already a candidate, use it. */
32023217
for (gdbarch_list *best_arch = gdbarch_list_lookup_by_info (arches, &info);
32033218
best_arch != nullptr;
32043219
best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
32053220
{
32063221
struct gdbarch_tdep *tdep = gdbarch_tdep (best_arch->gdbarch);
3207-
if (tdep)
3222+
if (tdep && tdep->vq == vq)
32083223
return best_arch->gdbarch;
32093224
}
32103225

3211-
/* Ensure we always have a target description. */
3226+
/* Ensure we always have a target descriptor, and that it is for the given VQ
3227+
value. */
32123228
const struct target_desc *tdesc = info.target_desc;
3213-
if (!tdesc_has_registers (tdesc))
3214-
tdesc = aarch64_read_description (0, false);
3229+
if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc))
3230+
tdesc = aarch64_read_description (vq, false);
32153231
gdb_assert (tdesc);
32163232

32173233
feature_core = tdesc_find_feature (tdesc,"org.gnu.gdb.aarch64.core");
@@ -3304,7 +3320,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
33043320
tdep->lowest_pc = 0x20;
33053321
tdep->jb_pc = -1; /* Longjump support not enabled by default. */
33063322
tdep->jb_elt_size = 8;
3307-
tdep->vq = aarch64_get_tdesc_vq (tdesc);
3323+
tdep->vq = vq;
33083324
tdep->pauth_reg_base = first_pauth_regnum;
33093325
tdep->pauth_ra_state_regnum = (feature_pauth == NULL) ? -1
33103326
: pauth_ra_state_offset + num_regs;

0 commit comments

Comments
 (0)