[Lldb-commits] [lldb] [lldb][AArch64][Linux] Use memcpy when serialising data (PR #210710)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 20 06:06:00 PDT 2026


https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/210710

In few places we are reinterpreting raw bytes as typed data. This works but is undefined behaviour if the address being used isn't at the same alignment as the target type.

It likely has always been because we've got 4 and 8 byte types and 4 or 8 byte registers. However I prefer to use memcpy anyway to be safe.

m_sve_state is a single byte but for consistency I'm using memcpy for it also.

>From 6f7c44df8c98e24dc89db93d448ae51a60e8eba6 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at arm.com>
Date: Mon, 20 Jul 2026 12:47:58 +0000
Subject: [PATCH] [lldb][AArch64][Linux] Use memcpy when serialising data

In few places we are reinterpreting raw bytes as typed
data. This works but is undefined behaviour if the address
being used isn't at the same alignment as the target type.

It likley has always been because we've got 4 and 8 byte
types and 4 or 8 byte registers. However I prefer to use
memcpy anyway to be safe.

m_sve_state is a single byte but for consistency I'm
using memcpy for it also.
---
 .../Linux/NativeRegisterContextLinux_arm64.cpp      | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index f224d73b82221..3377c8d018629 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -775,7 +775,7 @@ Status NativeRegisterContextLinux_arm64::WriteRegister(
 
 uint8_t *NativeRegisterContextLinux_arm64::AddRegisterSetType(
     uint8_t *dst, RegisterSetType register_set_type) {
-  *(reinterpret_cast<RegisterSetType *>(dst)) = register_set_type;
+  std::memcpy(dst, &register_set_type, sizeof(register_set_type));
   return dst + sizeof(RegisterSetType);
 }
 
@@ -946,7 +946,7 @@ Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
   if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
       m_sve_state != SVEState::StreamingFPSIMD) {
     dst = AddRegisterSetType(dst, RegisterSetType::SVE);
-    *(reinterpret_cast<SVEState *>(dst)) = m_sve_state;
+    std::memcpy(dst, &m_sve_state, sizeof(m_sve_state));
     dst += sizeof(m_sve_state);
     dst = AddSavedRegistersData(dst, GetSVEBuffer(), GetSVEBufferSize());
   } else {
@@ -1050,8 +1050,8 @@ Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
 
   const uint8_t *end = src + data_sp->GetByteSize();
   while (src < end) {
-    const RegisterSetType kind =
-        *reinterpret_cast<const RegisterSetType *>(src);
+    RegisterSetType kind;
+    std::memcpy(&kind, src, sizeof(kind));
     src += sizeof(RegisterSetType);
 
     switch (kind) {
@@ -1062,7 +1062,7 @@ Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
       break;
     case RegisterSetType::SVE:
       // Restore to the correct mode, streaming or not.
-      m_sve_state = static_cast<SVEState>(*src);
+      std::memcpy(&m_sve_state, src, sizeof(m_sve_state));
       src += sizeof(m_sve_state);
 
       // First write SVE header. We do not use RestoreRegisters because we do
@@ -1221,7 +1221,8 @@ Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
         return error;
 
       uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
-      gcs_regs new_gcs_regs = *reinterpret_cast<const gcs_regs *>(src);
+      gcs_regs new_gcs_regs;
+      std::memcpy(&new_gcs_regs, src, sizeof(new_gcs_regs));
       new_gcs_regs.features_enabled =
           (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
 



More information about the lldb-commits mailing list