]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/nat/aarch64-scalable-linux-ptrace.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / nat / aarch64-scalable-linux-ptrace.c
CommitLineData
ca65640f 1/* Common native Linux code for the AArch64 scalable extensions: SVE and SME.
122394f1 2
1d506c26 3 Copyright (C) 2018-2024 Free Software Foundation, Inc.
122394f1
AH
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include <sys/utsname.h>
21#include <sys/uio.h>
268a13a5 22#include "gdbsupport/common-defs.h"
122394f1
AH
23#include "elf/external.h"
24#include "elf/common.h"
6ada909e 25#include "aarch64-scalable-linux-ptrace.h"
122394f1 26#include "arch/aarch64.h"
268a13a5
TT
27#include "gdbsupport/common-regcache.h"
28#include "gdbsupport/byte-vector.h"
6afcd2d4 29#include <endian.h>
ca65640f
LM
30#include "arch/aarch64-scalable-linux.h"
31
32/* See nat/aarch64-scalable-linux-ptrace.h. */
33
34bool
35aarch64_has_sve_state (int tid)
36{
37 struct user_sve_header header;
38
39 if (!read_sve_header (tid, header))
40 return false;
41
42 if ((header.flags & SVE_PT_REGS_SVE) == 0)
43 return false;
44
45 if (sizeof (header) == header.size)
46 return false;
47
48 return true;
49}
50
51/* See nat/aarch64-scalable-linux-ptrace.h. */
52
53bool
54aarch64_has_ssve_state (int tid)
55{
56 struct user_sve_header header;
57
58 if (!read_ssve_header (tid, header))
59 return false;
60
61 if ((header.flags & SVE_PT_REGS_SVE) == 0)
62 return false;
63
64 if (sizeof (header) == header.size)
65 return false;
66
67 return true;
68}
69
70/* See nat/aarch64-scalable-linux-ptrace.h. */
71
72bool
73aarch64_has_za_state (int tid)
74{
75 struct user_za_header header;
76
77 if (!read_za_header (tid, header))
78 return false;
79
80 if (sizeof (header) == header.size)
81 return false;
82
83 return true;
84}
85
86/* See nat/aarch64-scalable-linux-ptrace.h. */
87
88bool
89read_sve_header (int tid, struct user_sve_header &header)
90{
91 struct iovec iovec;
92
93 iovec.iov_len = sizeof (header);
94 iovec.iov_base = &header;
95
96 if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_SVE, &iovec) < 0)
97 {
98 /* SVE is not supported. */
99 return false;
100 }
101 return true;
102}
103
104/* See nat/aarch64-scalable-linux-ptrace.h. */
105
106bool
107write_sve_header (int tid, const struct user_sve_header &header)
108{
109 struct iovec iovec;
110
111 iovec.iov_len = sizeof (header);
112 iovec.iov_base = (void *) &header;
113
114 if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_SVE, &iovec) < 0)
115 {
116 /* SVE is not supported. */
117 return false;
118 }
119 return true;
120}
121
122/* See nat/aarch64-scalable-linux-ptrace.h. */
123
124bool
125read_ssve_header (int tid, struct user_sve_header &header)
126{
127 struct iovec iovec;
128
129 iovec.iov_len = sizeof (header);
130 iovec.iov_base = &header;
131
132 if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_SSVE, &iovec) < 0)
133 {
134 /* SSVE is not supported. */
135 return false;
136 }
137 return true;
138}
139
140/* See nat/aarch64-scalable-linux-ptrace.h. */
141
142bool
143write_ssve_header (int tid, const struct user_sve_header &header)
144{
145 struct iovec iovec;
146
147 iovec.iov_len = sizeof (header);
148 iovec.iov_base = (void *) &header;
149
150 if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_SSVE, &iovec) < 0)
151 {
152 /* SSVE is not supported. */
153 return false;
154 }
155 return true;
156}
157
158/* See nat/aarch64-scalable-linux-ptrace.h. */
159
160bool
161read_za_header (int tid, struct user_za_header &header)
162{
163 struct iovec iovec;
164
165 iovec.iov_len = sizeof (header);
166 iovec.iov_base = &header;
167
168 if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_ZA, &iovec) < 0)
169 {
170 /* ZA is not supported. */
171 return false;
172 }
173 return true;
174}
175
176/* See nat/aarch64-scalable-linux-ptrace.h. */
177
178bool
179write_za_header (int tid, const struct user_za_header &header)
180{
181 struct iovec iovec;
182
183 iovec.iov_len = sizeof (header);
184 iovec.iov_base = (void *) &header;
185
186 if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_ZA, &iovec) < 0)
187 {
188 /* ZA is not supported. */
189 return false;
190 }
191 return true;
192}
193
194/* Given VL, the streaming vector length for SME, return true if it is valid
195 and false otherwise. */
196
197static bool
198aarch64_sme_vl_valid (size_t vl)
199{
200 return (vl == 16 || vl == 32 || vl == 64 || vl == 128 || vl == 256);
201}
202
203/* Given VL, the vector length for SVE, return true if it is valid and false
204 otherwise. SVE_state is true when the check is for the SVE register set.
205 Otherwise the check is for the SSVE register set. */
206
207static bool
208aarch64_sve_vl_valid (const bool sve_state, size_t vl)
209{
210 if (sve_state)
211 return sve_vl_valid (vl);
212
213 /* We have an active SSVE state, where the valid vector length values are
214 more restrictive. */
215 return aarch64_sme_vl_valid (vl);
216}
e9902bfc 217
6ada909e 218/* See nat/aarch64-scalable-linux-ptrace.h. */
122394f1 219
39bfb937 220uint64_t
122394f1
AH
221aarch64_sve_get_vq (int tid)
222{
223 struct iovec iovec;
224 struct user_sve_header header;
122394f1
AH
225 iovec.iov_len = sizeof (header);
226 iovec.iov_base = &header;
227
ca65640f
LM
228 /* Figure out which register set to use for the request. The vector length
229 for SVE can be different from the vector length for SSVE. */
230 bool has_sve_state = !aarch64_has_ssve_state (tid);
231 if (ptrace (PTRACE_GETREGSET, tid, has_sve_state? NT_ARM_SVE : NT_ARM_SSVE,
232 &iovec) < 0)
122394f1
AH
233 {
234 /* SVE is not supported. */
235 return 0;
236 }
237
ca65640f
LM
238 /* Ptrace gives the vector length in bytes. Convert it to VQ, the number of
239 128bit chunks in a Z register. We use VQ because 128 bits is the minimum
240 a Z register can increase in size. */
e9902bfc 241 uint64_t vq = sve_vq_from_vl (header.vl);
122394f1 242
ca65640f 243 if (!aarch64_sve_vl_valid (has_sve_state, header.vl))
122394f1
AH
244 {
245 warning (_("Invalid SVE state from kernel; SVE disabled."));
246 return 0;
247 }
248
249 return vq;
250}
e9902bfc 251
6ada909e 252/* See nat/aarch64-scalable-linux-ptrace.h. */
e9902bfc 253
48574d91
AH
254bool
255aarch64_sve_set_vq (int tid, uint64_t vq)
256{
257 struct iovec iovec;
258 struct user_sve_header header;
259
260 iovec.iov_len = sizeof (header);
261 iovec.iov_base = &header;
262
ca65640f
LM
263 /* Figure out which register set to use for the request. The vector length
264 for SVE can be different from the vector length for SSVE. */
265 bool has_sve_state = !aarch64_has_ssve_state (tid);
266 if (ptrace (PTRACE_GETREGSET, tid, has_sve_state? NT_ARM_SVE : NT_ARM_SSVE,
267 &iovec) < 0)
48574d91 268 {
ca65640f 269 /* SVE/SSVE is not supported. */
48574d91
AH
270 return false;
271 }
272
273 header.vl = sve_vl_from_vq (vq);
274
ca65640f
LM
275 if (ptrace (PTRACE_SETREGSET, tid, has_sve_state? NT_ARM_SVE : NT_ARM_SSVE,
276 &iovec) < 0)
48574d91
AH
277 {
278 /* Vector length change failed. */
279 return false;
280 }
281
282 return true;
283}
284
6ada909e 285/* See nat/aarch64-scalable-linux-ptrace.h. */
48574d91
AH
286
287bool
288aarch64_sve_set_vq (int tid, struct reg_buffer_common *reg_buf)
289{
2d07da27
LM
290 uint64_t reg_vg = 0;
291
292 /* The VG register may not be valid if we've not collected any value yet.
293 This can happen, for example, if we're restoring the regcache after an
294 inferior function call, and the VG register comes after the Z
295 registers. */
48574d91 296 if (reg_buf->get_register_status (AARCH64_SVE_VG_REGNUM) != REG_VALID)
01add95b
SM
297 {
298 /* If vg is not available yet, fetch it from ptrace. The VG value from
299 ptrace is likely the correct one. */
300 uint64_t vq = aarch64_sve_get_vq (tid);
48574d91 301
01add95b
SM
302 /* If something went wrong, just bail out. */
303 if (vq == 0)
304 return false;
2d07da27 305
01add95b
SM
306 reg_vg = sve_vg_from_vq (vq);
307 }
2d07da27
LM
308 else
309 reg_buf->raw_collect (AARCH64_SVE_VG_REGNUM, &reg_vg);
48574d91
AH
310
311 return aarch64_sve_set_vq (tid, sve_vq_from_vg (reg_vg));
312}
313
6ada909e 314/* See nat/aarch64-scalable-linux-ptrace.h. */
48574d91 315
ca65640f
LM
316uint64_t
317aarch64_za_get_svq (int tid)
318{
319 struct user_za_header header;
320 if (!read_za_header (tid, header))
321 return 0;
322
323 uint64_t vq = sve_vq_from_vl (header.vl);
324
325 if (!aarch64_sve_vl_valid (false, header.vl))
326 {
327 warning (_("Invalid ZA state from kernel; ZA disabled."));
328 return 0;
329 }
330
331 return vq;
332}
333
334/* See nat/aarch64-scalable-linux-ptrace.h. */
335
336bool
337aarch64_za_set_svq (int tid, uint64_t vq)
338{
339 struct iovec iovec;
340
341 /* Read the NT_ARM_ZA header. */
342 struct user_za_header header;
343 if (!read_za_header (tid, header))
344 {
345 /* ZA is not supported. */
346 return false;
347 }
348
349 /* If the size is the correct one already, don't update it. If we do
350 update the streaming vector length, we will invalidate the register
351 state for ZA, and we do not want that. */
352 if (header.vl == sve_vl_from_vq (vq))
353 return true;
354
355 /* The streaming vector length is about to get updated. Set the new value
356 in the NT_ARM_ZA header and adjust the size as well. */
357
358 header.vl = sve_vl_from_vq (vq);
359 header.size = sizeof (struct user_za_header);
360
361 /* Update the NT_ARM_ZA register set with the new streaming vector
362 length. */
363 iovec.iov_len = sizeof (header);
364 iovec.iov_base = &header;
365
366 if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_ZA, &iovec) < 0)
367 {
368 /* Streaming vector length change failed. */
369 return false;
370 }
371
372 /* At this point we have successfully adjusted the streaming vector length
373 for the NT_ARM_ZA register set, and it should have no payload
374 (no ZA state). */
375
376 return true;
377}
378
379/* See nat/aarch64-scalable-linux-ptrace.h. */
380
381bool
382aarch64_za_set_svq (int tid, const struct reg_buffer_common *reg_buf,
383 int svg_regnum)
384{
385 uint64_t reg_svg = 0;
386
387 /* The svg register may not be valid if we've not collected any value yet.
388 This can happen, for example, if we're restoring the regcache after an
389 inferior function call, and the svg register comes after the Z
390 registers. */
391 if (reg_buf->get_register_status (svg_regnum) != REG_VALID)
392 {
393 /* If svg is not available yet, fetch it from ptrace. The svg value from
394 ptrace is likely the correct one. */
395 uint64_t svq = aarch64_za_get_svq (tid);
396
397 /* If something went wrong, just bail out. */
398 if (svq == 0)
399 return false;
400
401 reg_svg = sve_vg_from_vq (svq);
402 }
403 else
404 reg_buf->raw_collect (svg_regnum, &reg_svg);
405
406 return aarch64_za_set_svq (tid, sve_vq_from_vg (reg_svg));
407}
408
409/* See nat/aarch64-scalable-linux-ptrace.h. */
410
78d6a7e9
LM
411gdb::byte_vector
412aarch64_fetch_sve_regset (int tid)
e9902bfc 413{
e9902bfc
AH
414 uint64_t vq = aarch64_sve_get_vq (tid);
415
416 if (vq == 0)
ca65640f 417 perror_with_name (_("Unable to fetch SVE/SSVE vector length"));
e9902bfc
AH
418
419 /* A ptrace call with NT_ARM_SVE will return a header followed by either a
420 dump of all the SVE and FP registers, or an fpsimd structure (identical to
421 the one returned by NT_FPREGSET) if the kernel has not yet executed any
422 SVE code. Make sure we allocate enough space for a full SVE dump. */
423
78d6a7e9
LM
424 gdb::byte_vector sve_state (SVE_PT_SIZE (vq, SVE_PT_REGS_SVE), 0);
425
426 struct iovec iovec;
427 iovec.iov_base = sve_state.data ();
428 iovec.iov_len = sve_state.size ();
e9902bfc 429
ca65640f
LM
430 bool has_sve_state = !aarch64_has_ssve_state (tid);
431 if (ptrace (PTRACE_GETREGSET, tid, has_sve_state? NT_ARM_SVE : NT_ARM_SSVE,
432 &iovec) < 0)
433 perror_with_name (_("Unable to fetch SVE/SSVE registers"));
e9902bfc 434
78d6a7e9
LM
435 return sve_state;
436}
437
438/* See nat/aarch64-scalable-linux-ptrace.h. */
439
440void
441aarch64_store_sve_regset (int tid, const gdb::byte_vector &sve_state)
442{
443 struct iovec iovec;
444 /* We need to cast from (const void *) here. */
445 iovec.iov_base = (void *) sve_state.data ();
446 iovec.iov_len = sve_state.size ();
447
ca65640f
LM
448 bool has_sve_state = !aarch64_has_ssve_state (tid);
449 if (ptrace (PTRACE_SETREGSET, tid, has_sve_state? NT_ARM_SVE : NT_ARM_SSVE,
450 &iovec) < 0)
451 perror_with_name (_("Unable to store SVE/SSVE registers"));
452}
453
454/* See nat/aarch64-scalable-linux-ptrace.h. */
455
456gdb::byte_vector
457aarch64_fetch_za_regset (int tid)
458{
459 struct user_za_header header;
460 if (!read_za_header (tid, header))
461 error (_("Failed to read NT_ARM_ZA header."));
462
463 if (!aarch64_sme_vl_valid (header.vl))
464 error (_("Found invalid vector length for NT_ARM_ZA."));
465
466 struct iovec iovec;
467 iovec.iov_len = header.size;
468 gdb::byte_vector za_state (header.size);
469 iovec.iov_base = za_state.data ();
470
471 if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_ZA, &iovec) < 0)
472 perror_with_name (_("Failed to fetch NT_ARM_ZA register set."));
473
474 return za_state;
475}
476
477/* See nat/aarch64-scalable-linux-ptrace.h. */
478
479void
480aarch64_store_za_regset (int tid, const gdb::byte_vector &za_state)
481{
482 struct iovec iovec;
483 /* We need to cast from (const void *) here. */
484 iovec.iov_base = (void *) za_state.data ();
485 iovec.iov_len = za_state.size ();
486
487 if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_ZA, &iovec) < 0)
488 perror_with_name (_("Failed to write to the NT_ARM_ZA register set."));
489}
490
491/* See nat/aarch64-scalable-linux-ptrace.h. */
492
493void
494aarch64_initialize_za_regset (int tid)
495{
496 /* First fetch the NT_ARM_ZA header so we can fetch the streaming vector
497 length. */
498 struct user_za_header header;
499 if (!read_za_header (tid, header))
500 error (_("Failed to read NT_ARM_ZA header."));
501
502 /* The vector should be default-initialized to zero, and we should account
503 for the payload as well. */
504 std::vector<gdb_byte> za_new_state (ZA_PT_SIZE (sve_vq_from_vl (header.vl)));
505
506 /* Adjust the header size since we are adding the initialized ZA
507 payload. */
508 header.size = ZA_PT_SIZE (sve_vq_from_vl (header.vl));
509
510 /* Overlay the modified header onto the new ZA state. */
511 const gdb_byte *base = (gdb_byte *) &header;
512 memcpy (za_new_state.data (), base, sizeof (user_za_header));
513
514 /* Set the ptrace request up and update the NT_ARM_ZA register set. */
515 struct iovec iovec;
516 iovec.iov_len = za_new_state.size ();
517 iovec.iov_base = za_new_state.data ();
518
519 if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_ZA, &iovec) < 0)
520 perror_with_name (_("Failed to initialize the NT_ARM_ZA register set."));
521
42019af6
LM
522 if (supports_zt_registers (tid))
523 {
524 /* If this target supports SME2, upon initializing ZA, we also need to
525 initialize the ZT registers with 0 values. Do so now. */
526 gdb::byte_vector zt_new_state (AARCH64_SME2_ZT0_SIZE, 0);
527 aarch64_store_zt_regset (tid, zt_new_state);
528 }
529
ca65640f
LM
530 /* The NT_ARM_ZA register set should now contain a zero-initialized ZA
531 payload. */
e9902bfc
AH
532}
533
42019af6
LM
534/* See nat/aarch64-scalable-linux-ptrace.h. */
535
536gdb::byte_vector
537aarch64_fetch_zt_regset (int tid)
538{
539 /* Read NT_ARM_ZT. This register set is only available if
540 the ZA bit is non-zero. */
541 gdb::byte_vector zt_state (AARCH64_SME2_ZT0_SIZE);
542
543 struct iovec iovec;
544 iovec.iov_len = AARCH64_SME2_ZT0_SIZE;
545 iovec.iov_base = zt_state.data ();
546
547 if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_ZT, &iovec) < 0)
548 perror_with_name (_("Failed to fetch NT_ARM_ZT register set."));
549
550 return zt_state;
551}
552
553/* See nat/aarch64-scalable-linux-ptrace.h. */
554
555void
556aarch64_store_zt_regset (int tid, const gdb::byte_vector &zt_state)
557{
558 gdb_assert (zt_state.size () == AARCH64_SME2_ZT0_SIZE
559 || zt_state.size () == 0);
560
561 /* We need to be mindful of writing data to NT_ARM_ZT. If the ZA bit
562 is 0 and we write something to ZT, it will flip the ZA bit.
563
564 Right now this is taken care of by callers of this function. */
565 struct iovec iovec;
566 iovec.iov_len = zt_state.size ();
567 iovec.iov_base = (void *) zt_state.data ();
568
569 /* Write the contents of ZT_STATE to the NT_ARM_ZT register set. */
570 if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_ZT, &iovec) < 0)
571 perror_with_name (_("Failed to write to the NT_ARM_ZT register set."));
572}
573
574/* See nat/aarch64-scalable-linux-ptrace.h. */
575
576bool
577supports_zt_registers (int tid)
578{
579 gdb_byte zt_state[AARCH64_SME2_ZT0_SIZE];
580
581 struct iovec iovec;
582 iovec.iov_len = AARCH64_SME2_ZT0_SIZE;
583 iovec.iov_base = (void *) zt_state;
584
585 if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_ZT, &iovec) < 0)
586 return false;
587
588 return true;
589}
590
6afcd2d4
LM
591/* If we are running in BE mode, byteswap the contents
592 of SRC to DST for SIZE bytes. Other, just copy the contents
593 from SRC to DST. */
594
595static void
596aarch64_maybe_swab128 (gdb_byte *dst, const gdb_byte *src, size_t size)
597{
598 gdb_assert (src != nullptr && dst != nullptr);
599 gdb_assert (size > 1);
600
601#if (__BYTE_ORDER == __BIG_ENDIAN)
602 for (int i = 0; i < size - 1; i++)
603 dst[i] = src[size - i];
604#else
605 memcpy (dst, src, size);
606#endif
607}
608
6ada909e 609/* See nat/aarch64-scalable-linux-ptrace.h. */
e9902bfc
AH
610
611void
78d6a7e9 612aarch64_sve_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf)
e9902bfc 613{
78d6a7e9
LM
614 gdb::byte_vector sve_state = aarch64_fetch_sve_regset (tid);
615
51e6b8cf 616 gdb_byte *base = sve_state.data ();
78d6a7e9
LM
617 struct user_sve_header *header
618 = (struct user_sve_header *) sve_state.data ();
e9902bfc 619
48574d91
AH
620 uint64_t vq = sve_vq_from_vl (header->vl);
621 uint64_t vg = sve_vg_from_vl (header->vl);
e9902bfc
AH
622
623 /* Sanity check the data in the header. */
624 if (!sve_vl_valid (header->vl)
625 || SVE_PT_SIZE (vq, header->flags) != header->size)
626 error (_("Invalid SVE header from kernel."));
627
48574d91
AH
628 /* Update VG. Note, the registers in the regcache will already be of the
629 correct length. */
630 reg_buf->raw_supply (AARCH64_SVE_VG_REGNUM, &vg);
e9902bfc
AH
631
632 if (HAS_SVE_STATE (*header))
633 {
634 /* The register dump contains a set of SVE registers. */
635
636 for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
637 reg_buf->raw_supply (AARCH64_SVE_Z0_REGNUM + i,
638 base + SVE_PT_SVE_ZREG_OFFSET (vq, i));
639
640 for (int i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
641 reg_buf->raw_supply (AARCH64_SVE_P0_REGNUM + i,
642 base + SVE_PT_SVE_PREG_OFFSET (vq, i));
643
644 reg_buf->raw_supply (AARCH64_SVE_FFR_REGNUM,
645 base + SVE_PT_SVE_FFR_OFFSET (vq));
646 reg_buf->raw_supply (AARCH64_FPSR_REGNUM,
647 base + SVE_PT_SVE_FPSR_OFFSET (vq));
648 reg_buf->raw_supply (AARCH64_FPCR_REGNUM,
649 base + SVE_PT_SVE_FPCR_OFFSET (vq));
650 }
651 else
652 {
6afcd2d4
LM
653 /* WARNING: SIMD state is laid out in memory in target-endian format,
654 while SVE state is laid out in an endianness-independent format (LE).
655
656 So we have a couple cases to consider:
657
658 1 - If the target is big endian, then SIMD state is big endian,
659 requiring a byteswap.
660
661 2 - If the target is little endian, then SIMD state is little endian,
662 which matches the SVE format, so no byteswap is needed. */
663
e9902bfc
AH
664 /* There is no SVE state yet - the register dump contains a fpsimd
665 structure instead. These registers still exist in the hardware, but
666 the kernel has not yet initialised them, and so they will be null. */
667
6afcd2d4 668 gdb_byte *reg = (gdb_byte *) alloca (SVE_PT_SVE_ZREG_SIZE (vq));
e9902bfc
AH
669 struct user_fpsimd_state *fpsimd
670 = (struct user_fpsimd_state *)(base + SVE_PT_FPSIMD_OFFSET);
671
6afcd2d4
LM
672 /* Make sure we have a zeroed register buffer. We will need the zero
673 padding below. */
674 memset (reg, 0, SVE_PT_SVE_ZREG_SIZE (vq));
675
e9902bfc
AH
676 /* Copy across the V registers from fpsimd structure to the Z registers,
677 ensuring the non overlapping state is set to null. */
678
e9902bfc
AH
679 for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
680 {
6afcd2d4
LM
681 /* Handle big endian/little endian SIMD/SVE conversion. */
682 aarch64_maybe_swab128 (reg, (const gdb_byte *) &fpsimd->vregs[i],
683 V_REGISTER_SIZE);
684 reg_buf->raw_supply (AARCH64_SVE_Z0_REGNUM + i, reg);
e9902bfc
AH
685 }
686
51e6b8cf
SM
687 reg_buf->raw_supply (AARCH64_FPSR_REGNUM,
688 (const gdb_byte *) &fpsimd->fpsr);
689 reg_buf->raw_supply (AARCH64_FPCR_REGNUM,
690 (const gdb_byte *) &fpsimd->fpcr);
e9902bfc
AH
691
692 /* Clear the SVE only registers. */
6afcd2d4 693 memset (reg, 0, SVE_PT_SVE_ZREG_SIZE (vq));
e9902bfc
AH
694
695 for (int i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
6afcd2d4 696 reg_buf->raw_supply (AARCH64_SVE_P0_REGNUM + i, reg);
e9902bfc 697
6afcd2d4 698 reg_buf->raw_supply (AARCH64_SVE_FFR_REGNUM, reg);
e9902bfc 699 }
78d6a7e9
LM
700
701 /* At this point we have updated the register cache with the contents of
702 the NT_ARM_SVE register set. */
e9902bfc
AH
703}
704
6ada909e 705/* See nat/aarch64-scalable-linux-ptrace.h. */
e9902bfc
AH
706
707void
78d6a7e9
LM
708aarch64_sve_regs_copy_from_reg_buf (int tid,
709 struct reg_buffer_common *reg_buf)
e9902bfc 710{
78d6a7e9
LM
711 /* First store the vector length to the thread. This is done first to
712 ensure the ptrace buffers read from the kernel are the correct size. */
713 if (!aarch64_sve_set_vq (tid, reg_buf))
714 perror_with_name (_("Unable to set VG register"));
715
716 /* Obtain a dump of SVE registers from ptrace. */
717 gdb::byte_vector sve_state = aarch64_fetch_sve_regset (tid);
718
719 struct user_sve_header *header = (struct user_sve_header *) sve_state.data ();
48574d91 720 uint64_t vq = sve_vq_from_vl (header->vl);
e9902bfc 721
78d6a7e9
LM
722 gdb::byte_vector new_state (SVE_PT_SIZE (32, SVE_PT_REGS_SVE), 0);
723 memcpy (new_state.data (), sve_state.data (), sve_state.size ());
724 header = (struct user_sve_header *) new_state.data ();
51e6b8cf 725 gdb_byte *base = new_state.data ();
78d6a7e9 726
e9902bfc
AH
727 /* Sanity check the data in the header. */
728 if (!sve_vl_valid (header->vl)
729 || SVE_PT_SIZE (vq, header->flags) != header->size)
730 error (_("Invalid SVE header from kernel."));
731
e9902bfc
AH
732 if (!HAS_SVE_STATE (*header))
733 {
734 /* There is no SVE state yet - the register dump contains a fpsimd
735 structure instead. Where possible we want to write the reg_buf data
736 back to the kernel using the fpsimd structure. However, if we cannot
737 then we'll need to reformat the fpsimd into a full SVE structure,
738 resulting in the initialization of SVE state written back to the
739 kernel, which is why we try to avoid it. */
740
78d6a7e9
LM
741 /* Buffer (using the maximum size a Z register) used to look for zeroed
742 out sve state. */
743 gdb_byte reg[256];
744 memset (reg, 0, sizeof (reg));
e9902bfc
AH
745
746 /* Check in the reg_buf if any of the Z registers are set after the
747 first 128 bits, or if any of the other SVE registers are set. */
78d6a7e9 748 bool has_sve_state = false;
e9902bfc
AH
749 for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
750 {
78d6a7e9
LM
751 if (!reg_buf->raw_compare (AARCH64_SVE_Z0_REGNUM + i, reg,
752 V_REGISTER_SIZE))
753 {
754 has_sve_state = true;
755 break;
756 }
e9902bfc
AH
757 }
758
759 if (!has_sve_state)
760 for (int i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
761 {
78d6a7e9
LM
762 if (!reg_buf->raw_compare (AARCH64_SVE_P0_REGNUM + i, reg, 0))
763 {
764 has_sve_state = true;
765 break;
766 }
e9902bfc
AH
767 }
768
769 if (!has_sve_state)
78d6a7e9
LM
770 has_sve_state
771 = !reg_buf->raw_compare (AARCH64_SVE_FFR_REGNUM, reg, 0);
772
773 struct user_fpsimd_state *fpsimd
774 = (struct user_fpsimd_state *)(base + SVE_PT_FPSIMD_OFFSET);
e9902bfc
AH
775
776 /* If no SVE state exists, then use the existing fpsimd structure to
777 write out state and return. */
778 if (!has_sve_state)
779 {
6afcd2d4
LM
780 /* WARNING: SIMD state is laid out in memory in target-endian format,
781 while SVE state is laid out in an endianness-independent format
782 (LE).
783
784 So we have a couple cases to consider:
785
786 1 - If the target is big endian, then SIMD state is big endian,
787 requiring a byteswap.
788
789 2 - If the target is little endian, then SIMD state is little
790 endian, which matches the SVE format, so no byteswap is needed. */
791
e9902bfc
AH
792 /* The collects of the Z registers will overflow the size of a vreg.
793 There is enough space in the structure to allow for this, but we
794 cannot overflow into the next register as we might not be
795 collecting every register. */
796
797 for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
798 {
799 if (REG_VALID
800 == reg_buf->get_register_status (AARCH64_SVE_Z0_REGNUM + i))
801 {
6afcd2d4
LM
802 reg_buf->raw_collect (AARCH64_SVE_Z0_REGNUM + i, reg);
803 /* Handle big endian/little endian SIMD/SVE conversion. */
804 aarch64_maybe_swab128 ((gdb_byte *) &fpsimd->vregs[i], reg,
805 V_REGISTER_SIZE);
e9902bfc
AH
806 }
807 }
808
809 if (REG_VALID == reg_buf->get_register_status (AARCH64_FPSR_REGNUM))
51e6b8cf
SM
810 reg_buf->raw_collect (AARCH64_FPSR_REGNUM,
811 (gdb_byte *) &fpsimd->fpsr);
e9902bfc 812 if (REG_VALID == reg_buf->get_register_status (AARCH64_FPCR_REGNUM))
51e6b8cf
SM
813 reg_buf->raw_collect (AARCH64_FPCR_REGNUM,
814 (gdb_byte *) &fpsimd->fpcr);
e9902bfc 815
78d6a7e9
LM
816 /* At this point we have collected all the data from the register
817 cache and we are ready to update the FPSIMD register content
818 of the thread. */
e9902bfc 819
78d6a7e9
LM
820 /* Fall through so we can update the thread's contents with the
821 FPSIMD register cache values. */
822 }
823 else
824 {
825 /* Otherwise, reformat the fpsimd structure into a full SVE set, by
826 expanding the V registers (working backwards so we don't splat
827 registers before they are copied) and using zero for everything
828 else.
829 Note that enough space for a full SVE dump was originally allocated
830 for base. */
831
832 header->flags |= SVE_PT_REGS_SVE;
833 header->size = SVE_PT_SIZE (vq, SVE_PT_REGS_SVE);
834
835 memcpy (base + SVE_PT_SVE_FPSR_OFFSET (vq), &fpsimd->fpsr,
836 sizeof (uint32_t));
837 memcpy (base + SVE_PT_SVE_FPCR_OFFSET (vq), &fpsimd->fpcr,
838 sizeof (uint32_t));
839
840 for (int i = AARCH64_SVE_Z_REGS_NUM - 1; i >= 0 ; i--)
841 {
842 memcpy (base + SVE_PT_SVE_ZREG_OFFSET (vq, i), &fpsimd->vregs[i],
843 sizeof (__int128_t));
844 }
e9902bfc 845
78d6a7e9
LM
846 /* At this point we have converted the FPSIMD layout to an SVE
847 layout and copied the register data.
e9902bfc 848
78d6a7e9
LM
849 Fall through so we can update the thread's contents with the SVE
850 register cache values. */
e9902bfc
AH
851 }
852 }
78d6a7e9
LM
853 else
854 {
855 /* We already have SVE state for this thread, so we just need to update
856 the values of the registers. */
857 for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
858 if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_Z0_REGNUM
859 + i))
860 reg_buf->raw_collect (AARCH64_SVE_Z0_REGNUM + i,
861 base + SVE_PT_SVE_ZREG_OFFSET (vq, i));
e9902bfc 862
78d6a7e9
LM
863 for (int i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
864 if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_P0_REGNUM
865 + i))
866 reg_buf->raw_collect (AARCH64_SVE_P0_REGNUM + i,
867 base + SVE_PT_SVE_PREG_OFFSET (vq, i));
868
869 if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_FFR_REGNUM))
870 reg_buf->raw_collect (AARCH64_SVE_FFR_REGNUM,
871 base + SVE_PT_SVE_FFR_OFFSET (vq));
872 if (REG_VALID == reg_buf->get_register_status (AARCH64_FPSR_REGNUM))
873 reg_buf->raw_collect (AARCH64_FPSR_REGNUM,
874 base + SVE_PT_SVE_FPSR_OFFSET (vq));
875 if (REG_VALID == reg_buf->get_register_status (AARCH64_FPCR_REGNUM))
876 reg_buf->raw_collect (AARCH64_FPCR_REGNUM,
877 base + SVE_PT_SVE_FPCR_OFFSET (vq));
878 }
e9902bfc 879
78d6a7e9
LM
880 /* At this point we have collected all the data from the register cache and
881 we are ready to update the SVE/FPSIMD register contents of the thread.
e9902bfc 882
78d6a7e9
LM
883 sve_state should contain all the data in the correct format, ready to be
884 passed on to ptrace. */
885 aarch64_store_sve_regset (tid, new_state);
e9902bfc 886}
ca65640f
LM
887
888/* See nat/aarch64-scalable-linux-ptrace.h. */
889
890void
891aarch64_za_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf,
892 int za_regnum, int svg_regnum,
893 int svcr_regnum)
894{
895 /* Fetch the current ZA state from the thread. */
896 gdb::byte_vector za_state = aarch64_fetch_za_regset (tid);
897
898 /* Sanity check. */
899 gdb_assert (!za_state.empty ());
900
51e6b8cf 901 gdb_byte *base = za_state.data ();
ca65640f
LM
902 struct user_za_header *header = (struct user_za_header *) base;
903
904 /* If we have ZA state, read it. Otherwise, make the contents of ZA
905 in the register cache all zeroes. This is how we present the ZA
906 state when it is not initialized. */
907 uint64_t svcr_value = 0;
908 if (aarch64_has_za_state (tid))
909 {
910 /* Sanity check the data in the header. */
911 if (!sve_vl_valid (header->vl)
912 || ZA_PT_SIZE (sve_vq_from_vl (header->vl)) != header->size)
913 {
914 error (_("Found invalid streaming vector length in NT_ARM_ZA"
915 " register set"));
916 }
917
918 reg_buf->raw_supply (za_regnum, base + ZA_PT_ZA_OFFSET);
919 svcr_value |= SVCR_ZA_BIT;
920 }
921 else
922 {
923 size_t za_bytes = header->vl * header->vl;
924 gdb_byte za_zeroed[za_bytes];
925 memset (za_zeroed, 0, za_bytes);
926 reg_buf->raw_supply (za_regnum, za_zeroed);
927 }
928
929 /* Handle the svg and svcr registers separately. We need to calculate
930 their values manually, as the Linux Kernel doesn't expose those
931 explicitly. */
932 svcr_value |= aarch64_has_ssve_state (tid)? SVCR_SM_BIT : 0;
933 uint64_t svg_value = sve_vg_from_vl (header->vl);
934
935 /* Update the contents of svg and svcr registers. */
936 reg_buf->raw_supply (svg_regnum, &svg_value);
937 reg_buf->raw_supply (svcr_regnum, &svcr_value);
938
939 /* The register buffer should now contain the updated copy of the NT_ARM_ZA
940 state. */
941}
942
943/* See nat/aarch64-scalable-linux-ptrace.h. */
944
945void
946aarch64_za_regs_copy_from_reg_buf (int tid,
947 struct reg_buffer_common *reg_buf,
948 int za_regnum, int svg_regnum,
949 int svcr_regnum)
950{
951 /* REG_BUF contains the updated ZA state. We need to extract that state
952 and write it to the thread TID. */
953
954
955 /* First check if there is a change to the streaming vector length. Two
956 outcomes are possible here:
957
958 1 - The streaming vector length in the register cache differs from the
959 one currently on the thread state. This means that we will need to
960 update the NT_ARM_ZA register set to reflect the new streaming vector
961 length.
962
963 2 - The streaming vector length in the register cache is the same as in
964 the thread state. This means we do not need to update the NT_ARM_ZA
965 register set for a new streaming vector length, and we only need to
966 deal with changes to za, svg and svcr.
967
968 None of the two possibilities above imply that the ZA state actually
969 exists. They only determine what needs to be done with any ZA content
970 based on the state of the streaming vector length. */
971
972 /* First fetch the NT_ARM_ZA header so we can fetch the streaming vector
973 length. */
974 struct user_za_header header;
975 if (!read_za_header (tid, header))
976 error (_("Failed to read NT_ARM_ZA header."));
977
978 /* Fetch the current streaming vector length. */
979 uint64_t old_svg = sve_vg_from_vl (header.vl);
980
981 /* Fetch the (potentially) new streaming vector length. */
982 uint64_t new_svg;
983 reg_buf->raw_collect (svg_regnum, &new_svg);
984
985 /* Did the streaming vector length change? */
986 bool svg_changed = new_svg != old_svg;
987
988 /* First store the streaming vector length to the thread. This is done
989 first to ensure the ptrace buffers read from the kernel are the correct
990 size. If the streaming vector length is the same as the current one, it
991 won't be updated. */
992 if (!aarch64_za_set_svq (tid, reg_buf, svg_regnum))
993 error (_("Unable to set svg register"));
994
995 bool has_za_state = aarch64_has_za_state (tid);
996
997 size_t za_bytes = sve_vl_from_vg (old_svg) * sve_vl_from_vg (old_svg);
998 gdb_byte za_zeroed[za_bytes];
999 memset (za_zeroed, 0, za_bytes);
1000
1001 /* If the streaming vector length changed, zero out the contents of ZA in
1002 the register cache. Otherwise, we will need to update the ZA contents
1003 in the thread with the ZA contents from the register cache, and they will
1004 differ in size. */
1005 if (svg_changed)
1006 reg_buf->raw_supply (za_regnum, za_zeroed);
1007
1008 /* When we update svg, we don't automatically initialize the ZA buffer. If
1009 we have no ZA state and the ZA register contents in the register cache are
1010 zero, just return and leave the ZA register cache contents as zero. */
1011 if (!has_za_state
1012 && reg_buf->raw_compare (za_regnum, za_zeroed, 0))
1013 {
1014 /* No ZA state in the thread or in the register cache. This was likely
1015 just an adjustment of the streaming vector length. Let this fall
1016 through and update svcr and svg in the register cache. */
1017 }
1018 else
1019 {
1020 /* If there is no ZA state but the register cache contains ZA data, we
1021 need to initialize the ZA data through ptrace. First we initialize
1022 all the bytes of ZA to zero. */
1023 if (!has_za_state
1024 && !reg_buf->raw_compare (za_regnum, za_zeroed, 0))
1025 aarch64_initialize_za_regset (tid);
1026
1027 /* From this point onwards, it is assumed we have a ZA payload in
1028 the NT_ARM_ZA register set for this thread, and we need to update
1029 such state based on the contents of the register cache. */
1030
1031 /* Fetch the current ZA state from the thread. */
1032 gdb::byte_vector za_state = aarch64_fetch_za_regset (tid);
1033
51e6b8cf 1034 gdb_byte *base = za_state.data ();
ca65640f
LM
1035 struct user_za_header *za_header = (struct user_za_header *) base;
1036 uint64_t svq = sve_vq_from_vl (za_header->vl);
1037
1038 /* Sanity check the data in the header. */
1039 if (!sve_vl_valid (za_header->vl)
1040 || ZA_PT_SIZE (svq) != za_header->size)
1041 error (_("Invalid vector length or payload size when reading ZA."));
1042
1043 /* Overwrite the ZA state contained in the thread with the ZA state from
1044 the register cache. */
1045 if (REG_VALID == reg_buf->get_register_status (za_regnum))
1046 reg_buf->raw_collect (za_regnum, base + ZA_PT_ZA_OFFSET);
1047
1048 /* Write back the ZA state to the thread's NT_ARM_ZA register set. */
1049 aarch64_store_za_regset (tid, za_state);
1050 }
1051
1052 /* Update svcr and svg accordingly. */
1053 uint64_t svcr_value = 0;
1054 svcr_value |= aarch64_has_ssve_state (tid)? SVCR_SM_BIT : 0;
1055 svcr_value |= aarch64_has_za_state (tid)? SVCR_ZA_BIT : 0;
1056 reg_buf->raw_supply (svcr_regnum, &svcr_value);
1057
1058 /* At this point we have written the data contained in the register cache to
1059 the thread's NT_ARM_ZA register set. */
1060}
42019af6
LM
1061
1062/* See nat/aarch64-scalable-linux-ptrace.h. */
1063
1064void
1065aarch64_zt_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf,
1066 int zt_regnum)
1067{
1068 /* If we have ZA state, read the ZT state. Otherwise, make the contents of
1069 ZT in the register cache all zeroes. This is how we present the ZT
1070 state when it is not initialized (ZA not active). */
1071 if (aarch64_has_za_state (tid))
1072 {
1073 /* Fetch the current ZT state from the thread. */
1074 gdb::byte_vector zt_state = aarch64_fetch_zt_regset (tid);
1075
1076 /* Sanity check. */
1077 gdb_assert (!zt_state.empty ());
1078
1079 /* Copy the ZT data to the register buffer. */
1080 reg_buf->raw_supply (zt_regnum, zt_state.data ());
1081 }
1082 else
1083 {
1084 /* Zero out ZT. */
1085 gdb::byte_vector zt_zeroed (AARCH64_SME2_ZT0_SIZE, 0);
1086 reg_buf->raw_supply (zt_regnum, zt_zeroed.data ());
1087 }
1088
1089 /* The register buffer should now contain the updated copy of the NT_ARM_ZT
1090 state. */
1091}
1092
1093/* See nat/aarch64-scalable-linux-ptrace.h. */
1094
1095void
1096aarch64_zt_regs_copy_from_reg_buf (int tid,
1097 struct reg_buffer_common *reg_buf,
1098 int zt_regnum)
1099{
1100 /* Do we have a valid ZA state? */
1101 bool valid_za = aarch64_has_za_state (tid);
1102
1103 /* Is the register buffer contents for ZT all zeroes? */
1104 gdb::byte_vector zt_bytes (AARCH64_SME2_ZT0_SIZE, 0);
1105 bool zt_is_all_zeroes
1106 = reg_buf->raw_compare (zt_regnum, zt_bytes.data (), 0);
1107
1108 /* If ZA state is valid or if we have non-zero data for ZT in the register
1109 buffer, we will invoke ptrace to write the ZT state. Otherwise we don't
1110 have to do anything here. */
1111 if (valid_za || !zt_is_all_zeroes)
1112 {
1113 if (!valid_za)
1114 {
1115 /* ZA state is not valid. That means we need to initialize the ZA
1116 state prior to writing the ZT state. */
1117 aarch64_initialize_za_regset (tid);
1118 }
1119
1120 /* Extract the ZT data from the register buffer. */
1121 reg_buf->raw_collect (zt_regnum, zt_bytes.data ());
1122
1123 /* Write the ZT data to thread TID. */
1124 aarch64_store_zt_regset (tid, zt_bytes);
1125 }
1126
1127 /* At this point we have (potentially) written the data contained in the
1128 register cache to the thread's NT_ARM_ZT register set. */
1129}