• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修訂9ad94eaded134cf5824776ab0ccf8ecd47518919 (tree)
時間2018-09-14 00:49:24
作者Alan Hayward <alan.hayward@arm....>
CommiterAlan Hayward

Log Message

Aarch64 SVE: Support changing vector lengths in gdbserver

There are two parts to this patch - gdbserver and GDB.

In gdbserver, there needs to be an equivalent of the thread_architecture
method used in GDB. In regcache, validate the tdesc with the
use target_validate_tdesc target function. If this fails then re-obtain
the target descriptor via general setup.
The aarch64 validation step simply checks the value of the VG register to
see if it matches the current kernel value.

In GDB, we have a similar check when receiving a stop reply. Validate the
tdesc using gdbarch_target_description_changed_p. If this fails re-obtain
the target descriptor via general setup - which is done by setting up an
tdep info structure containing the vector length.
The aarch64 validation step checks the value of VG (which is marked as
an expediated register, so is in the stop reply).

2018-08-03 Alan Hayward <alan.hayward@arm.com>

gdb/
* aarch64-tdep.c
(aarch64_target_description_changed_p): Check vector length.
(aarch64_target_get_tdep_info): Store vector length.
* remote.c (remote_target::process_stop_reply): Validate tdesc.
* target-descriptions.c (target_find_description): Pass through info.
* target-descriptions.h (target_find_description): Add arg.

gdbserver/
* linux-aarch64-low.c (aarch64_validate_tdesc): Check vector length.
* regcache.c (get_thread_regcache): Validate tdesc.

Change Summary

差異

--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -2971,7 +2971,31 @@ aarch64_target_description_changed_p (struct gdbarch *gdbarch,
29712971 ptid_t ptid,
29722972 VEC (cached_reg_t) *registers)
29732973 {
2974- return false;
2974+ /* Return true if the VG value in the given VEC of registers list does not
2975+ match the VG value in the current regcache. */
2976+
2977+ cached_reg_t *reg;
2978+ bool regcache_has_vg = (gdbarch_num_regs (gdbarch) > AARCH64_SVE_VG_REGNUM);
2979+
2980+ for (int ix = 0; VEC_iterate (cached_reg_t, registers, ix, reg); ix++)
2981+ if (reg->num == AARCH64_SVE_VG_REGNUM)
2982+ {
2983+ if (!regcache_has_vg)
2984+ {
2985+ /* No VG in regcache. */
2986+ return true;
2987+ }
2988+
2989+ struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch);
2990+
2991+ if (regcache->get_register_status (AARCH64_SVE_VG_REGNUM) != REG_VALID)
2992+ return true;
2993+
2994+ return !regcache->raw_compare (AARCH64_SVE_VG_REGNUM, reg->data, 0);
2995+ }
2996+
2997+ /* VG is not in the given register list. */
2998+ return regcache_has_vg;
29752999 }
29763000
29773001 /* Implement the "target_get_tdep_info" gdbarch method. */
@@ -2979,7 +3003,21 @@ aarch64_target_description_changed_p (struct gdbarch *gdbarch,
29793003 static union gdbarch_target_info
29803004 aarch64_target_get_tdep_info (VEC (cached_reg_t) *registers)
29813005 {
2982- return {0};
3006+ gdbarch_target_info info = {0};
3007+
3008+ /* Use the current VQ value as the tdep info value. */
3009+
3010+ cached_reg_t *reg;
3011+
3012+ for (int ix = 0; VEC_iterate (cached_reg_t, registers, ix, reg); ix++)
3013+ if (reg->num == AARCH64_SVE_VG_REGNUM)
3014+ {
3015+ uint64_t vg = *(uint64_t *) reg->data;
3016+ info.id = (int *) sve_vq_from_vg (vg);
3017+ return info;
3018+ }
3019+
3020+ return info;
29833021 }
29843022
29853023 /* Initialize the current architecture based on INFO. If possible,
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -3042,7 +3042,26 @@ aarch64_supports_hardware_single_step (void)
30423042 static bool
30433043 aarch64_validate_tdesc (struct thread_info *thread)
30443044 {
3045- return true;
3045+ /* For SVE there is a target descriptor for each VL. Read the current vector
3046+ length and check if it matches the size of a variable register in the
3047+ current target descriptor. */
3048+
3049+ int tid = (ptid_of (thread)).lwp ();
3050+ long vl = sve_vl_from_vq (aarch64_sve_get_vq (tid));
3051+ struct regcache *regcache = thread_regcache_data (thread);
3052+ struct process_info *proc;
3053+
3054+ /* Non SVE targets always validate as true. */
3055+ if (vl == 0)
3056+ return true;
3057+
3058+ /* If there is a register cache, check the z0 register size. */
3059+ if (regcache)
3060+ return (register_size (regcache->tdesc, AARCH64_SVE_Z0_REGNUM) == vl);
3061+
3062+ /* Otherwise, check the z0 register size in the description. */
3063+ proc = get_thread_process (thread);
3064+ return (register_size (proc->tdesc, AARCH64_SVE_Z0_REGNUM) == vl);
30463065 }
30473066
30483067 struct linux_target_ops the_low_target =
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -28,6 +28,18 @@ get_thread_regcache (struct thread_info *thread, int fetch)
2828 {
2929 struct regcache *regcache;
3030
31+ /* Check the target descriptor is still valid for the current target. If
32+ not, then clear it and create a new one. */
33+ if (!target_validate_tdesc (thread))
34+ {
35+ /* Clear regcache. */
36+ free_register_cache (thread_regcache_data (thread));
37+ set_thread_regcache_data (thread, NULL);
38+ regcache = NULL;
39+
40+ target_arch_setup ();
41+ }
42+
3143 regcache = thread_regcache_data (thread);
3244
3345 /* Threads' regcaches are created lazily, because biarch targets add
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -7689,9 +7689,24 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply,
76897689 && status->kind != TARGET_WAITKIND_SIGNALLED
76907690 && status->kind != TARGET_WAITKIND_NO_RESUMED)
76917691 {
7692+ VEC (cached_reg_t) *stop_regs = stop_reply->regcache;
7693+
76927694 /* Expedited registers. */
7693- if (stop_reply->regcache)
7695+ if (stop_regs)
76947696 {
7697+ struct gdbarch *gdbarch = target_gdbarch ();
7698+
7699+ /* Check the target descriptor is still valid for the current target.
7700+ If not, then clear it find the correct one. */
7701+ if (gdbarch_target_description_changed_p (gdbarch, ptid, stop_regs))
7702+ {
7703+ gdbarch_target_info info
7704+ = gdbarch_target_get_tdep_info (gdbarch, stop_regs);
7705+ registers_changed ();
7706+ target_clear_description ();
7707+ target_find_description (info);
7708+ }
7709+
76957710 struct regcache *regcache
76967711 = get_thread_arch_regcache (ptid, stop_reply->arch);
76977712 cached_reg_t *reg;
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -491,11 +491,12 @@ target_desc_info_free (struct target_desc_info *tdesc_info)
491491
492492 static char *tdesc_filename_cmd_string;
493493
494-/* Fetch the current target's description, and switch the current
495- architecture to one which incorporates that description. */
494+/* Fetch the current inferior's description, and switch its current
495+ architecture to one which incorporates that description. If given, use the
496+ tdep_info when finding the description. */
496497
497498 void
498-target_find_description (void)
499+target_find_description (gdbarch_target_info target_info)
499500 {
500501 /* If we've already fetched a description from the target, don't do
501502 it again. This allows a target to fetch the description early,
@@ -534,6 +535,8 @@ target_find_description (void)
534535
535536 gdbarch_info_init (&info);
536537 info.target_desc = current_target_desc;
538+ info.target_info = target_info;
539+
537540 if (!gdbarch_update_p (info))
538541 warning (_("Architecture rejected target-supplied description"));
539542 else
--- a/gdb/target-descriptions.h
+++ b/gdb/target-descriptions.h
@@ -31,9 +31,10 @@ struct target_desc_info;
3131 struct inferior;
3232
3333 /* Fetch the current inferior's description, and switch its current
34- architecture to one which incorporates that description. */
34+ architecture to one which incorporates that description. If given, use the
35+ tdep_info when finding the description. */
3536
36-void target_find_description (void);
37+void target_find_description (gdbarch_target_info target_info = {0});
3738
3839 /* Discard any description fetched from the target for the current
3940 inferior, and switch the current architecture to one with no target