1 /* Common native Linux code for the AArch64 scalable extensions: SVE and SME.
3 Copyright (C) 2018-2023 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include <sys/utsname.h>
22 #include "gdbsupport/common-defs.h"
23 #include "elf/external.h"
24 #include "elf/common.h"
25 #include "aarch64-scalable-linux-ptrace.h"
26 #include "arch/aarch64.h"
27 #include "gdbsupport/common-regcache.h"
28 #include "gdbsupport/byte-vector.h"
30 #include "arch/aarch64-scalable-linux.h"
32 /* See nat/aarch64-scalable-linux-ptrace.h. */
35 aarch64_has_sve_state (int tid
)
37 struct user_sve_header header
;
39 if (!read_sve_header (tid
, header
))
42 if ((header
.flags
& SVE_PT_REGS_SVE
) == 0)
45 if (sizeof (header
) == header
.size
)
51 /* See nat/aarch64-scalable-linux-ptrace.h. */
54 aarch64_has_ssve_state (int tid
)
56 struct user_sve_header header
;
58 if (!read_ssve_header (tid
, header
))
61 if ((header
.flags
& SVE_PT_REGS_SVE
) == 0)
64 if (sizeof (header
) == header
.size
)
70 /* See nat/aarch64-scalable-linux-ptrace.h. */
73 aarch64_has_za_state (int tid
)
75 struct user_za_header header
;
77 if (!read_za_header (tid
, header
))
80 if (sizeof (header
) == header
.size
)
86 /* See nat/aarch64-scalable-linux-ptrace.h. */
89 read_sve_header (int tid
, struct user_sve_header
&header
)
93 iovec
.iov_len
= sizeof (header
);
94 iovec
.iov_base
= &header
;
96 if (ptrace (PTRACE_GETREGSET
, tid
, NT_ARM_SVE
, &iovec
) < 0)
98 /* SVE is not supported. */
104 /* See nat/aarch64-scalable-linux-ptrace.h. */
107 write_sve_header (int tid
, const struct user_sve_header
&header
)
111 iovec
.iov_len
= sizeof (header
);
112 iovec
.iov_base
= (void *) &header
;
114 if (ptrace (PTRACE_SETREGSET
, tid
, NT_ARM_SVE
, &iovec
) < 0)
116 /* SVE is not supported. */
122 /* See nat/aarch64-scalable-linux-ptrace.h. */
125 read_ssve_header (int tid
, struct user_sve_header
&header
)
129 iovec
.iov_len
= sizeof (header
);
130 iovec
.iov_base
= &header
;
132 if (ptrace (PTRACE_GETREGSET
, tid
, NT_ARM_SSVE
, &iovec
) < 0)
134 /* SSVE is not supported. */
140 /* See nat/aarch64-scalable-linux-ptrace.h. */
143 write_ssve_header (int tid
, const struct user_sve_header
&header
)
147 iovec
.iov_len
= sizeof (header
);
148 iovec
.iov_base
= (void *) &header
;
150 if (ptrace (PTRACE_SETREGSET
, tid
, NT_ARM_SSVE
, &iovec
) < 0)
152 /* SSVE is not supported. */
158 /* See nat/aarch64-scalable-linux-ptrace.h. */
161 read_za_header (int tid
, struct user_za_header
&header
)
165 iovec
.iov_len
= sizeof (header
);
166 iovec
.iov_base
= &header
;
168 if (ptrace (PTRACE_GETREGSET
, tid
, NT_ARM_ZA
, &iovec
) < 0)
170 /* ZA is not supported. */
176 /* See nat/aarch64-scalable-linux-ptrace.h. */
179 write_za_header (int tid
, const struct user_za_header
&header
)
183 iovec
.iov_len
= sizeof (header
);
184 iovec
.iov_base
= (void *) &header
;
186 if (ptrace (PTRACE_SETREGSET
, tid
, NT_ARM_ZA
, &iovec
) < 0)
188 /* ZA is not supported. */
194 /* Given VL, the streaming vector length for SME, return true if it is valid
195 and false otherwise. */
198 aarch64_sme_vl_valid (size_t vl
)
200 return (vl
== 16 || vl
== 32 || vl
== 64 || vl
== 128 || vl
== 256);
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. */
208 aarch64_sve_vl_valid (const bool sve_state
, size_t vl
)
211 return sve_vl_valid (vl
);
213 /* We have an active SSVE state, where the valid vector length values are
215 return aarch64_sme_vl_valid (vl
);
218 /* See nat/aarch64-scalable-linux-ptrace.h. */
221 aarch64_sve_get_vq (int tid
)
224 struct user_sve_header header
;
225 iovec
.iov_len
= sizeof (header
);
226 iovec
.iov_base
= &header
;
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
,
234 /* SVE is not supported. */
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. */
241 uint64_t vq
= sve_vq_from_vl (header
.vl
);
243 if (!aarch64_sve_vl_valid (has_sve_state
, header
.vl
))
245 warning (_("Invalid SVE state from kernel; SVE disabled."));
252 /* See nat/aarch64-scalable-linux-ptrace.h. */
255 aarch64_sve_set_vq (int tid
, uint64_t vq
)
258 struct user_sve_header header
;
260 iovec
.iov_len
= sizeof (header
);
261 iovec
.iov_base
= &header
;
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
,
269 /* SVE/SSVE is not supported. */
273 header
.vl
= sve_vl_from_vq (vq
);
275 if (ptrace (PTRACE_SETREGSET
, tid
, has_sve_state
? NT_ARM_SVE
: NT_ARM_SSVE
,
278 /* Vector length change failed. */
285 /* See nat/aarch64-scalable-linux-ptrace.h. */
288 aarch64_sve_set_vq (int tid
, struct reg_buffer_common
*reg_buf
)
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
296 if (reg_buf
->get_register_status (AARCH64_SVE_VG_REGNUM
) != REG_VALID
)
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
);
302 /* If something went wrong, just bail out. */
306 reg_vg
= sve_vg_from_vq (vq
);
309 reg_buf
->raw_collect (AARCH64_SVE_VG_REGNUM
, ®_vg
);
311 return aarch64_sve_set_vq (tid
, sve_vq_from_vg (reg_vg
));
314 /* See nat/aarch64-scalable-linux-ptrace.h. */
317 aarch64_za_get_svq (int tid
)
319 struct user_za_header header
;
320 if (!read_za_header (tid
, header
))
323 uint64_t vq
= sve_vq_from_vl (header
.vl
);
325 if (!aarch64_sve_vl_valid (false, header
.vl
))
327 warning (_("Invalid ZA state from kernel; ZA disabled."));
334 /* See nat/aarch64-scalable-linux-ptrace.h. */
337 aarch64_za_set_svq (int tid
, uint64_t vq
)
341 /* Read the NT_ARM_ZA header. */
342 struct user_za_header header
;
343 if (!read_za_header (tid
, header
))
345 /* ZA is not supported. */
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
))
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. */
358 header
.vl
= sve_vl_from_vq (vq
);
359 header
.size
= sizeof (struct user_za_header
);
361 /* Update the NT_ARM_ZA register set with the new streaming vector
363 iovec
.iov_len
= sizeof (header
);
364 iovec
.iov_base
= &header
;
366 if (ptrace (PTRACE_SETREGSET
, tid
, NT_ARM_ZA
, &iovec
) < 0)
368 /* Streaming vector length change failed. */
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
379 /* See nat/aarch64-scalable-linux-ptrace.h. */
382 aarch64_za_set_svq (int tid
, const struct reg_buffer_common
*reg_buf
,
385 uint64_t reg_svg
= 0;
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
391 if (reg_buf
->get_register_status (svg_regnum
) != REG_VALID
)
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
);
397 /* If something went wrong, just bail out. */
401 reg_svg
= sve_vg_from_vq (svq
);
404 reg_buf
->raw_collect (svg_regnum
, ®_svg
);
406 return aarch64_za_set_svq (tid
, sve_vq_from_vg (reg_svg
));
409 /* See nat/aarch64-scalable-linux-ptrace.h. */
412 aarch64_fetch_sve_regset (int tid
)
414 uint64_t vq
= aarch64_sve_get_vq (tid
);
417 perror_with_name (_("Unable to fetch SVE/SSVE vector length"));
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. */
424 gdb::byte_vector
sve_state (SVE_PT_SIZE (vq
, SVE_PT_REGS_SVE
), 0);
427 iovec
.iov_base
= sve_state
.data ();
428 iovec
.iov_len
= sve_state
.size ();
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
,
433 perror_with_name (_("Unable to fetch SVE/SSVE registers"));
438 /* See nat/aarch64-scalable-linux-ptrace.h. */
441 aarch64_store_sve_regset (int tid
, const gdb::byte_vector
&sve_state
)
444 /* We need to cast from (const void *) here. */
445 iovec
.iov_base
= (void *) sve_state
.data ();
446 iovec
.iov_len
= sve_state
.size ();
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
,
451 perror_with_name (_("Unable to store SVE/SSVE registers"));
454 /* See nat/aarch64-scalable-linux-ptrace.h. */
457 aarch64_fetch_za_regset (int tid
)
459 struct user_za_header header
;
460 if (!read_za_header (tid
, header
))
461 error (_("Failed to read NT_ARM_ZA header."));
463 if (!aarch64_sme_vl_valid (header
.vl
))
464 error (_("Found invalid vector length for NT_ARM_ZA."));
467 iovec
.iov_len
= header
.size
;
468 gdb::byte_vector
za_state (header
.size
);
469 iovec
.iov_base
= za_state
.data ();
471 if (ptrace (PTRACE_GETREGSET
, tid
, NT_ARM_ZA
, &iovec
) < 0)
472 perror_with_name (_("Failed to fetch NT_ARM_ZA register set."));
477 /* See nat/aarch64-scalable-linux-ptrace.h. */
480 aarch64_store_za_regset (int tid
, const gdb::byte_vector
&za_state
)
483 /* We need to cast from (const void *) here. */
484 iovec
.iov_base
= (void *) za_state
.data ();
485 iovec
.iov_len
= za_state
.size ();
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."));
491 /* See nat/aarch64-scalable-linux-ptrace.h. */
494 aarch64_initialize_za_regset (int tid
)
496 /* First fetch the NT_ARM_ZA header so we can fetch the streaming vector
498 struct user_za_header header
;
499 if (!read_za_header (tid
, header
))
500 error (_("Failed to read NT_ARM_ZA header."));
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
)));
506 /* Adjust the header size since we are adding the initialized ZA
508 header
.size
= ZA_PT_SIZE (sve_vq_from_vl (header
.vl
));
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
));
514 /* Set the ptrace request up and update the NT_ARM_ZA register set. */
516 iovec
.iov_len
= za_new_state
.size ();
517 iovec
.iov_base
= za_new_state
.data ();
519 if (ptrace (PTRACE_SETREGSET
, tid
, NT_ARM_ZA
, &iovec
) < 0)
520 perror_with_name (_("Failed to initialize the NT_ARM_ZA register set."));
522 if (supports_zt_registers (tid
))
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
);
530 /* The NT_ARM_ZA register set should now contain a zero-initialized ZA
534 /* See nat/aarch64-scalable-linux-ptrace.h. */
537 aarch64_fetch_zt_regset (int tid
)
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
);
544 iovec
.iov_len
= AARCH64_SME2_ZT0_SIZE
;
545 iovec
.iov_base
= zt_state
.data ();
547 if (ptrace (PTRACE_GETREGSET
, tid
, NT_ARM_ZT
, &iovec
) < 0)
548 perror_with_name (_("Failed to fetch NT_ARM_ZT register set."));
553 /* See nat/aarch64-scalable-linux-ptrace.h. */
556 aarch64_store_zt_regset (int tid
, const gdb::byte_vector
&zt_state
)
558 gdb_assert (zt_state
.size () == AARCH64_SME2_ZT0_SIZE
559 || zt_state
.size () == 0);
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.
564 Right now this is taken care of by callers of this function. */
566 iovec
.iov_len
= zt_state
.size ();
567 iovec
.iov_base
= (void *) zt_state
.data ();
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."));
574 /* See nat/aarch64-scalable-linux-ptrace.h. */
577 supports_zt_registers (int tid
)
579 gdb_byte zt_state
[AARCH64_SME2_ZT0_SIZE
];
582 iovec
.iov_len
= AARCH64_SME2_ZT0_SIZE
;
583 iovec
.iov_base
= (void *) zt_state
;
585 if (ptrace (PTRACE_GETREGSET
, tid
, NT_ARM_ZT
, &iovec
) < 0)
591 /* If we are running in BE mode, byteswap the contents
592 of SRC to DST for SIZE bytes. Other, just copy the contents
596 aarch64_maybe_swab128 (gdb_byte
*dst
, const gdb_byte
*src
, size_t size
)
598 gdb_assert (src
!= nullptr && dst
!= nullptr);
599 gdb_assert (size
> 1);
601 #if (__BYTE_ORDER == __BIG_ENDIAN)
602 for (int i
= 0; i
< size
- 1; i
++)
603 dst
[i
] = src
[size
- i
];
605 memcpy (dst
, src
, size
);
609 /* See nat/aarch64-scalable-linux-ptrace.h. */
612 aarch64_sve_regs_copy_to_reg_buf (int tid
, struct reg_buffer_common
*reg_buf
)
614 gdb::byte_vector sve_state
= aarch64_fetch_sve_regset (tid
);
616 char *base
= (char *) sve_state
.data ();
617 struct user_sve_header
*header
618 = (struct user_sve_header
*) sve_state
.data ();
620 uint64_t vq
= sve_vq_from_vl (header
->vl
);
621 uint64_t vg
= sve_vg_from_vl (header
->vl
);
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."));
628 /* Update VG. Note, the registers in the regcache will already be of the
630 reg_buf
->raw_supply (AARCH64_SVE_VG_REGNUM
, &vg
);
632 if (HAS_SVE_STATE (*header
))
634 /* The register dump contains a set of SVE registers. */
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
));
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
));
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
));
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).
656 So we have a couple cases to consider:
658 1 - If the target is big endian, then SIMD state is big endian,
659 requiring a byteswap.
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. */
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. */
668 gdb_byte
*reg
= (gdb_byte
*) alloca (SVE_PT_SVE_ZREG_SIZE (vq
));
669 struct user_fpsimd_state
*fpsimd
670 = (struct user_fpsimd_state
*)(base
+ SVE_PT_FPSIMD_OFFSET
);
672 /* Make sure we have a zeroed register buffer. We will need the zero
674 memset (reg
, 0, SVE_PT_SVE_ZREG_SIZE (vq
));
676 /* Copy across the V registers from fpsimd structure to the Z registers,
677 ensuring the non overlapping state is set to null. */
679 for (int i
= 0; i
< AARCH64_SVE_Z_REGS_NUM
; i
++)
681 /* Handle big endian/little endian SIMD/SVE conversion. */
682 aarch64_maybe_swab128 (reg
, (const gdb_byte
*) &fpsimd
->vregs
[i
],
684 reg_buf
->raw_supply (AARCH64_SVE_Z0_REGNUM
+ i
, reg
);
687 reg_buf
->raw_supply (AARCH64_FPSR_REGNUM
, &fpsimd
->fpsr
);
688 reg_buf
->raw_supply (AARCH64_FPCR_REGNUM
, &fpsimd
->fpcr
);
690 /* Clear the SVE only registers. */
691 memset (reg
, 0, SVE_PT_SVE_ZREG_SIZE (vq
));
693 for (int i
= 0; i
< AARCH64_SVE_P_REGS_NUM
; i
++)
694 reg_buf
->raw_supply (AARCH64_SVE_P0_REGNUM
+ i
, reg
);
696 reg_buf
->raw_supply (AARCH64_SVE_FFR_REGNUM
, reg
);
699 /* At this point we have updated the register cache with the contents of
700 the NT_ARM_SVE register set. */
703 /* See nat/aarch64-scalable-linux-ptrace.h. */
706 aarch64_sve_regs_copy_from_reg_buf (int tid
,
707 struct reg_buffer_common
*reg_buf
)
709 /* First store the vector length to the thread. This is done first to
710 ensure the ptrace buffers read from the kernel are the correct size. */
711 if (!aarch64_sve_set_vq (tid
, reg_buf
))
712 perror_with_name (_("Unable to set VG register"));
714 /* Obtain a dump of SVE registers from ptrace. */
715 gdb::byte_vector sve_state
= aarch64_fetch_sve_regset (tid
);
717 struct user_sve_header
*header
= (struct user_sve_header
*) sve_state
.data ();
718 uint64_t vq
= sve_vq_from_vl (header
->vl
);
720 gdb::byte_vector
new_state (SVE_PT_SIZE (32, SVE_PT_REGS_SVE
), 0);
721 memcpy (new_state
.data (), sve_state
.data (), sve_state
.size ());
722 header
= (struct user_sve_header
*) new_state
.data ();
723 char *base
= (char *) new_state
.data ();
725 /* Sanity check the data in the header. */
726 if (!sve_vl_valid (header
->vl
)
727 || SVE_PT_SIZE (vq
, header
->flags
) != header
->size
)
728 error (_("Invalid SVE header from kernel."));
730 if (!HAS_SVE_STATE (*header
))
732 /* There is no SVE state yet - the register dump contains a fpsimd
733 structure instead. Where possible we want to write the reg_buf data
734 back to the kernel using the fpsimd structure. However, if we cannot
735 then we'll need to reformat the fpsimd into a full SVE structure,
736 resulting in the initialization of SVE state written back to the
737 kernel, which is why we try to avoid it. */
739 /* Buffer (using the maximum size a Z register) used to look for zeroed
742 memset (reg
, 0, sizeof (reg
));
744 /* Check in the reg_buf if any of the Z registers are set after the
745 first 128 bits, or if any of the other SVE registers are set. */
746 bool has_sve_state
= false;
747 for (int i
= 0; i
< AARCH64_SVE_Z_REGS_NUM
; i
++)
749 if (!reg_buf
->raw_compare (AARCH64_SVE_Z0_REGNUM
+ i
, reg
,
752 has_sve_state
= true;
758 for (int i
= 0; i
< AARCH64_SVE_P_REGS_NUM
; i
++)
760 if (!reg_buf
->raw_compare (AARCH64_SVE_P0_REGNUM
+ i
, reg
, 0))
762 has_sve_state
= true;
769 = !reg_buf
->raw_compare (AARCH64_SVE_FFR_REGNUM
, reg
, 0);
771 struct user_fpsimd_state
*fpsimd
772 = (struct user_fpsimd_state
*)(base
+ SVE_PT_FPSIMD_OFFSET
);
774 /* If no SVE state exists, then use the existing fpsimd structure to
775 write out state and return. */
778 /* WARNING: SIMD state is laid out in memory in target-endian format,
779 while SVE state is laid out in an endianness-independent format
782 So we have a couple cases to consider:
784 1 - If the target is big endian, then SIMD state is big endian,
785 requiring a byteswap.
787 2 - If the target is little endian, then SIMD state is little
788 endian, which matches the SVE format, so no byteswap is needed. */
790 /* The collects of the Z registers will overflow the size of a vreg.
791 There is enough space in the structure to allow for this, but we
792 cannot overflow into the next register as we might not be
793 collecting every register. */
795 for (int i
= 0; i
< AARCH64_SVE_Z_REGS_NUM
; i
++)
798 == reg_buf
->get_register_status (AARCH64_SVE_Z0_REGNUM
+ i
))
800 reg_buf
->raw_collect (AARCH64_SVE_Z0_REGNUM
+ i
, reg
);
801 /* Handle big endian/little endian SIMD/SVE conversion. */
802 aarch64_maybe_swab128 ((gdb_byte
*) &fpsimd
->vregs
[i
], reg
,
807 if (REG_VALID
== reg_buf
->get_register_status (AARCH64_FPSR_REGNUM
))
808 reg_buf
->raw_collect (AARCH64_FPSR_REGNUM
, &fpsimd
->fpsr
);
809 if (REG_VALID
== reg_buf
->get_register_status (AARCH64_FPCR_REGNUM
))
810 reg_buf
->raw_collect (AARCH64_FPCR_REGNUM
, &fpsimd
->fpcr
);
812 /* At this point we have collected all the data from the register
813 cache and we are ready to update the FPSIMD register content
816 /* Fall through so we can update the thread's contents with the
817 FPSIMD register cache values. */
821 /* Otherwise, reformat the fpsimd structure into a full SVE set, by
822 expanding the V registers (working backwards so we don't splat
823 registers before they are copied) and using zero for everything
825 Note that enough space for a full SVE dump was originally allocated
828 header
->flags
|= SVE_PT_REGS_SVE
;
829 header
->size
= SVE_PT_SIZE (vq
, SVE_PT_REGS_SVE
);
831 memcpy (base
+ SVE_PT_SVE_FPSR_OFFSET (vq
), &fpsimd
->fpsr
,
833 memcpy (base
+ SVE_PT_SVE_FPCR_OFFSET (vq
), &fpsimd
->fpcr
,
836 for (int i
= AARCH64_SVE_Z_REGS_NUM
- 1; i
>= 0 ; i
--)
838 memcpy (base
+ SVE_PT_SVE_ZREG_OFFSET (vq
, i
), &fpsimd
->vregs
[i
],
839 sizeof (__int128_t
));
842 /* At this point we have converted the FPSIMD layout to an SVE
843 layout and copied the register data.
845 Fall through so we can update the thread's contents with the SVE
846 register cache values. */
851 /* We already have SVE state for this thread, so we just need to update
852 the values of the registers. */
853 for (int i
= 0; i
< AARCH64_SVE_Z_REGS_NUM
; i
++)
854 if (REG_VALID
== reg_buf
->get_register_status (AARCH64_SVE_Z0_REGNUM
856 reg_buf
->raw_collect (AARCH64_SVE_Z0_REGNUM
+ i
,
857 base
+ SVE_PT_SVE_ZREG_OFFSET (vq
, i
));
859 for (int i
= 0; i
< AARCH64_SVE_P_REGS_NUM
; i
++)
860 if (REG_VALID
== reg_buf
->get_register_status (AARCH64_SVE_P0_REGNUM
862 reg_buf
->raw_collect (AARCH64_SVE_P0_REGNUM
+ i
,
863 base
+ SVE_PT_SVE_PREG_OFFSET (vq
, i
));
865 if (REG_VALID
== reg_buf
->get_register_status (AARCH64_SVE_FFR_REGNUM
))
866 reg_buf
->raw_collect (AARCH64_SVE_FFR_REGNUM
,
867 base
+ SVE_PT_SVE_FFR_OFFSET (vq
));
868 if (REG_VALID
== reg_buf
->get_register_status (AARCH64_FPSR_REGNUM
))
869 reg_buf
->raw_collect (AARCH64_FPSR_REGNUM
,
870 base
+ SVE_PT_SVE_FPSR_OFFSET (vq
));
871 if (REG_VALID
== reg_buf
->get_register_status (AARCH64_FPCR_REGNUM
))
872 reg_buf
->raw_collect (AARCH64_FPCR_REGNUM
,
873 base
+ SVE_PT_SVE_FPCR_OFFSET (vq
));
876 /* At this point we have collected all the data from the register cache and
877 we are ready to update the SVE/FPSIMD register contents of the thread.
879 sve_state should contain all the data in the correct format, ready to be
880 passed on to ptrace. */
881 aarch64_store_sve_regset (tid
, new_state
);
884 /* See nat/aarch64-scalable-linux-ptrace.h. */
887 aarch64_za_regs_copy_to_reg_buf (int tid
, struct reg_buffer_common
*reg_buf
,
888 int za_regnum
, int svg_regnum
,
891 /* Fetch the current ZA state from the thread. */
892 gdb::byte_vector za_state
= aarch64_fetch_za_regset (tid
);
895 gdb_assert (!za_state
.empty ());
897 char *base
= (char *) za_state
.data ();
898 struct user_za_header
*header
= (struct user_za_header
*) base
;
900 /* If we have ZA state, read it. Otherwise, make the contents of ZA
901 in the register cache all zeroes. This is how we present the ZA
902 state when it is not initialized. */
903 uint64_t svcr_value
= 0;
904 if (aarch64_has_za_state (tid
))
906 /* Sanity check the data in the header. */
907 if (!sve_vl_valid (header
->vl
)
908 || ZA_PT_SIZE (sve_vq_from_vl (header
->vl
)) != header
->size
)
910 error (_("Found invalid streaming vector length in NT_ARM_ZA"
914 reg_buf
->raw_supply (za_regnum
, base
+ ZA_PT_ZA_OFFSET
);
915 svcr_value
|= SVCR_ZA_BIT
;
919 size_t za_bytes
= header
->vl
* header
->vl
;
920 gdb_byte za_zeroed
[za_bytes
];
921 memset (za_zeroed
, 0, za_bytes
);
922 reg_buf
->raw_supply (za_regnum
, za_zeroed
);
925 /* Handle the svg and svcr registers separately. We need to calculate
926 their values manually, as the Linux Kernel doesn't expose those
928 svcr_value
|= aarch64_has_ssve_state (tid
)? SVCR_SM_BIT
: 0;
929 uint64_t svg_value
= sve_vg_from_vl (header
->vl
);
931 /* Update the contents of svg and svcr registers. */
932 reg_buf
->raw_supply (svg_regnum
, &svg_value
);
933 reg_buf
->raw_supply (svcr_regnum
, &svcr_value
);
935 /* The register buffer should now contain the updated copy of the NT_ARM_ZA
939 /* See nat/aarch64-scalable-linux-ptrace.h. */
942 aarch64_za_regs_copy_from_reg_buf (int tid
,
943 struct reg_buffer_common
*reg_buf
,
944 int za_regnum
, int svg_regnum
,
947 /* REG_BUF contains the updated ZA state. We need to extract that state
948 and write it to the thread TID. */
951 /* First check if there is a change to the streaming vector length. Two
952 outcomes are possible here:
954 1 - The streaming vector length in the register cache differs from the
955 one currently on the thread state. This means that we will need to
956 update the NT_ARM_ZA register set to reflect the new streaming vector
959 2 - The streaming vector length in the register cache is the same as in
960 the thread state. This means we do not need to update the NT_ARM_ZA
961 register set for a new streaming vector length, and we only need to
962 deal with changes to za, svg and svcr.
964 None of the two possibilities above imply that the ZA state actually
965 exists. They only determine what needs to be done with any ZA content
966 based on the state of the streaming vector length. */
968 /* First fetch the NT_ARM_ZA header so we can fetch the streaming vector
970 struct user_za_header header
;
971 if (!read_za_header (tid
, header
))
972 error (_("Failed to read NT_ARM_ZA header."));
974 /* Fetch the current streaming vector length. */
975 uint64_t old_svg
= sve_vg_from_vl (header
.vl
);
977 /* Fetch the (potentially) new streaming vector length. */
979 reg_buf
->raw_collect (svg_regnum
, &new_svg
);
981 /* Did the streaming vector length change? */
982 bool svg_changed
= new_svg
!= old_svg
;
984 /* First store the streaming vector length to the thread. This is done
985 first to ensure the ptrace buffers read from the kernel are the correct
986 size. If the streaming vector length is the same as the current one, it
988 if (!aarch64_za_set_svq (tid
, reg_buf
, svg_regnum
))
989 error (_("Unable to set svg register"));
991 bool has_za_state
= aarch64_has_za_state (tid
);
993 size_t za_bytes
= sve_vl_from_vg (old_svg
) * sve_vl_from_vg (old_svg
);
994 gdb_byte za_zeroed
[za_bytes
];
995 memset (za_zeroed
, 0, za_bytes
);
997 /* If the streaming vector length changed, zero out the contents of ZA in
998 the register cache. Otherwise, we will need to update the ZA contents
999 in the thread with the ZA contents from the register cache, and they will
1002 reg_buf
->raw_supply (za_regnum
, za_zeroed
);
1004 /* When we update svg, we don't automatically initialize the ZA buffer. If
1005 we have no ZA state and the ZA register contents in the register cache are
1006 zero, just return and leave the ZA register cache contents as zero. */
1008 && reg_buf
->raw_compare (za_regnum
, za_zeroed
, 0))
1010 /* No ZA state in the thread or in the register cache. This was likely
1011 just an adjustment of the streaming vector length. Let this fall
1012 through and update svcr and svg in the register cache. */
1016 /* If there is no ZA state but the register cache contains ZA data, we
1017 need to initialize the ZA data through ptrace. First we initialize
1018 all the bytes of ZA to zero. */
1020 && !reg_buf
->raw_compare (za_regnum
, za_zeroed
, 0))
1021 aarch64_initialize_za_regset (tid
);
1023 /* From this point onwards, it is assumed we have a ZA payload in
1024 the NT_ARM_ZA register set for this thread, and we need to update
1025 such state based on the contents of the register cache. */
1027 /* Fetch the current ZA state from the thread. */
1028 gdb::byte_vector za_state
= aarch64_fetch_za_regset (tid
);
1030 char *base
= (char *) za_state
.data ();
1031 struct user_za_header
*za_header
= (struct user_za_header
*) base
;
1032 uint64_t svq
= sve_vq_from_vl (za_header
->vl
);
1034 /* Sanity check the data in the header. */
1035 if (!sve_vl_valid (za_header
->vl
)
1036 || ZA_PT_SIZE (svq
) != za_header
->size
)
1037 error (_("Invalid vector length or payload size when reading ZA."));
1039 /* Overwrite the ZA state contained in the thread with the ZA state from
1040 the register cache. */
1041 if (REG_VALID
== reg_buf
->get_register_status (za_regnum
))
1042 reg_buf
->raw_collect (za_regnum
, base
+ ZA_PT_ZA_OFFSET
);
1044 /* Write back the ZA state to the thread's NT_ARM_ZA register set. */
1045 aarch64_store_za_regset (tid
, za_state
);
1048 /* Update svcr and svg accordingly. */
1049 uint64_t svcr_value
= 0;
1050 svcr_value
|= aarch64_has_ssve_state (tid
)? SVCR_SM_BIT
: 0;
1051 svcr_value
|= aarch64_has_za_state (tid
)? SVCR_ZA_BIT
: 0;
1052 reg_buf
->raw_supply (svcr_regnum
, &svcr_value
);
1054 /* At this point we have written the data contained in the register cache to
1055 the thread's NT_ARM_ZA register set. */
1058 /* See nat/aarch64-scalable-linux-ptrace.h. */
1061 aarch64_zt_regs_copy_to_reg_buf (int tid
, struct reg_buffer_common
*reg_buf
,
1064 /* If we have ZA state, read the ZT state. Otherwise, make the contents of
1065 ZT in the register cache all zeroes. This is how we present the ZT
1066 state when it is not initialized (ZA not active). */
1067 if (aarch64_has_za_state (tid
))
1069 /* Fetch the current ZT state from the thread. */
1070 gdb::byte_vector zt_state
= aarch64_fetch_zt_regset (tid
);
1073 gdb_assert (!zt_state
.empty ());
1075 /* Copy the ZT data to the register buffer. */
1076 reg_buf
->raw_supply (zt_regnum
, zt_state
.data ());
1081 gdb::byte_vector
zt_zeroed (AARCH64_SME2_ZT0_SIZE
, 0);
1082 reg_buf
->raw_supply (zt_regnum
, zt_zeroed
.data ());
1085 /* The register buffer should now contain the updated copy of the NT_ARM_ZT
1089 /* See nat/aarch64-scalable-linux-ptrace.h. */
1092 aarch64_zt_regs_copy_from_reg_buf (int tid
,
1093 struct reg_buffer_common
*reg_buf
,
1096 /* Do we have a valid ZA state? */
1097 bool valid_za
= aarch64_has_za_state (tid
);
1099 /* Is the register buffer contents for ZT all zeroes? */
1100 gdb::byte_vector
zt_bytes (AARCH64_SME2_ZT0_SIZE
, 0);
1101 bool zt_is_all_zeroes
1102 = reg_buf
->raw_compare (zt_regnum
, zt_bytes
.data (), 0);
1104 /* If ZA state is valid or if we have non-zero data for ZT in the register
1105 buffer, we will invoke ptrace to write the ZT state. Otherwise we don't
1106 have to do anything here. */
1107 if (valid_za
|| !zt_is_all_zeroes
)
1111 /* ZA state is not valid. That means we need to initialize the ZA
1112 state prior to writing the ZT state. */
1113 aarch64_initialize_za_regset (tid
);
1116 /* Extract the ZT data from the register buffer. */
1117 reg_buf
->raw_collect (zt_regnum
, zt_bytes
.data ());
1119 /* Write the ZT data to thread TID. */
1120 aarch64_store_zt_regset (tid
, zt_bytes
);
1123 /* At this point we have (potentially) written the data contained in the
1124 register cache to the thread's NT_ARM_ZT register set. */