[llvm-branch-commits] [lldb] bc0a7de - [lldb][AArch64] Save/restore TLS registers around expressions

Tobias Hieta via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Aug 10 00:09:29 PDT 2023


Author: David Spickett
Date: 2023-08-10T09:04:42+02:00
New Revision: bc0a7de379e6c2540a551d7ca6ba2cf733347a3f

URL: https://github.com/llvm/llvm-project/commit/bc0a7de379e6c2540a551d7ca6ba2cf733347a3f
DIFF: https://github.com/llvm/llvm-project/commit/bc0a7de379e6c2540a551d7ca6ba2cf733347a3f.diff

LOG: [lldb][AArch64] Save/restore TLS registers around expressions

This was cherry-picked from 6239227172cdc92f3bb72131333f50f83a6439cf and has been
modified to remove references to the tpidr2 register that is not supported on
the 17 branch.

Previously lldb was storing them but not restoring them. Meaning that this function:
```
void expr(uint64_t value) {
  __asm__ volatile("msr tpidr_el0, %0" ::"r"(value));
}
```
When run from lldb:
```
(lldb) expression expr()
```
Would leave tpidr as `value` instead of the original value of the register.

A check for this scenario has been added to TestAArch64LinuxTLSRegister.py,

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D156512

Added: 
    

Modified: 
    lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
    lldb/test/API/linux/aarch64/tls_register/TestAArch64LinuxTLSRegister.py
    lldb/test/API/linux/aarch64/tls_register/main.c

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index c9384a651e81b2..206ee4ed4b8cb4 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -532,8 +532,10 @@ Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
     dst += GetFPRSize();
   }
 
-  if (GetRegisterInfo().IsMTEEnabled())
+  if (GetRegisterInfo().IsMTEEnabled()) {
     ::memcpy(dst, GetMTEControl(), GetMTEControlSize());
+    dst += GetMTEControlSize();
+  }
 
   ::memcpy(dst, GetTLSTPIDR(), GetTLSTPIDRSize());
 
@@ -640,8 +642,17 @@ Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
     ::memcpy(GetMTEControl(), src, GetMTEControlSize());
     m_mte_ctrl_is_valid = true;
     error = WriteMTEControl();
+    if (error.Fail())
+      return error;
+    src += GetMTEControlSize();
   }
 
+  // There is always a TLS set. It changes size based on system properties, it's
+  // not something an expression can change.
+  ::memcpy(GetTLSTPIDR(), src, GetTLSTPIDRSize());
+  m_tls_tpidr_is_valid = true;
+  error = WriteTLSTPIDR();
+
   return error;
 }
 

diff  --git a/lldb/test/API/linux/aarch64/tls_register/TestAArch64LinuxTLSRegister.py b/lldb/test/API/linux/aarch64/tls_register/TestAArch64LinuxTLSRegister.py
index d4ab5d70cc7643..235b0e8f79e03c 100644
--- a/lldb/test/API/linux/aarch64/tls_register/TestAArch64LinuxTLSRegister.py
+++ b/lldb/test/API/linux/aarch64/tls_register/TestAArch64LinuxTLSRegister.py
@@ -11,6 +11,15 @@
 class AArch64LinuxTLSRegister(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
 
+    def check_tpidr(self):
+        regs = self.thread().GetSelectedFrame().GetRegisters()
+        tls_regs = regs.GetFirstValueByName("Thread Local Storage Registers")
+        self.assertTrue(tls_regs.IsValid(), "No TLS registers found.")
+        tpidr = tls_regs.GetChildMemberWithName("tpidr")
+        self.assertTrue(tpidr.IsValid(), "No tpidr register found.")
+
+        self.assertEqual(tpidr.GetValueAsUnsigned(), 0x1122334455667788)
+
     @skipUnlessArch("aarch64")
     @skipUnlessPlatform(["linux"])
     def test_tls(self):
@@ -44,14 +53,11 @@ def test_tls(self):
 
         # Since we can't predict what the value will be, the program has set
         # a target value for us to find.
+        self.check_tpidr()
 
-        regs = self.thread().GetSelectedFrame().GetRegisters()
-        tls_regs = regs.GetFirstValueByName("Thread Local Storage Registers")
-        self.assertTrue(tls_regs.IsValid(), "No TLS registers found.")
-        tpidr = tls_regs.GetChildMemberWithName("tpidr")
-        self.assertTrue(tpidr.IsValid(), "No tpidr register found.")
-
-        self.assertEqual(tpidr.GetValueAsUnsigned(), 0x1122334455667788)
+        # It should be saved/restored before/after an expression.
+        self.runCmd("expression expr_func()")
+        self.check_tpidr()
 
         # Set our own value for the program to find.
         self.expect("register write tpidr 0x{:x}".format(0x8877665544332211))

diff  --git a/lldb/test/API/linux/aarch64/tls_register/main.c b/lldb/test/API/linux/aarch64/tls_register/main.c
index 7a5fd3f5fcbdff..12bc2ea479a39d 100644
--- a/lldb/test/API/linux/aarch64/tls_register/main.c
+++ b/lldb/test/API/linux/aarch64/tls_register/main.c
@@ -1,6 +1,12 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+const uint64_t pattern = 0x1122334455667788;
+
+void expr_func() {
+  __asm__ volatile("msr tpidr_el0, %0" ::"r"(~pattern));
+}
+
 int main() {
   // Save tpidr to restore later.
   uint64_t tpidr = 0;


        


More information about the llvm-branch-commits mailing list