[libc-commits] [libc] 33d14e3 - [libc][aarch64] Set frame pointer of the new thread to the stack pointer.
Siva Chandra via libc-commits
libc-commits at lists.llvm.org
Wed Jun 15 23:00:39 PDT 2022
Author: Siva Chandra
Date: 2022-06-15T22:58:49-07:00
New Revision: 33d14e3cd3b3c6b478e9b91b8575edfa8da63f31
URL: https://github.com/llvm/llvm-project/commit/33d14e3cd3b3c6b478e9b91b8575edfa8da63f31
DIFF: https://github.com/llvm/llvm-project/commit/33d14e3cd3b3c6b478e9b91b8575edfa8da63f31.diff
LOG: [libc][aarch64] Set frame pointer of the new thread to the stack pointer.
This allows sniffing thread start args in a robust fashion.
Added:
Modified:
libc/src/__support/threads/linux/thread.h
Removed:
################################################################################
diff --git a/libc/src/__support/threads/linux/thread.h b/libc/src/__support/threads/linux/thread.h
index b389b8a4c9816..b865b3f34fb98 100644
--- a/libc/src/__support/threads/linux/thread.h
+++ b/libc/src/__support/threads/linux/thread.h
@@ -15,6 +15,7 @@
#include "src/__support/threads/linux/futex_word.h" // For FutexWordType
#include "src/__support/threads/thread_attrib.h"
+#include <arm_acle.h>
#include <linux/futex.h>
#include <linux/sched.h> // For CLONE_* flags.
#include <stdint.h>
@@ -85,14 +86,19 @@ __attribute__((always_inline)) inline uintptr_t get_start_args_addr() {
// NOTE: For __builtin_frame_address to work reliably across compilers,
// architectures and various optimization levels, the TU including this file
// should be compiled with -fno-omit-frame-pointer.
+#ifdef LLVM_LIBC_ARCH_X86_64
return reinterpret_cast<uintptr_t>(__builtin_frame_address(0))
// The x86_64 call instruction pushes resume address on to the stack.
// Next, The x86_64 SysV ABI requires that the frame pointer be pushed
- // on to the stack. Similarly on aarch64, previous frame pointer and
- // the value of the link register are pushed on to the stack. So, in
- // both these cases, we have to step past two 64-bit values to get
+ // on to the stack. So, we have to step past two 64-bit values to get
// to the start args.
+ sizeof(uintptr_t) * 2;
+#elif defined(LLVM_LIBC_ARCH_AARCH64)
+ // The frame pointer after cloning the new thread in the Thread::run method
+ // is set to the stack pointer where start args are stored. So, we fetch
+ // from there.
+ return reinterpret_cast<uintptr_t>(__builtin_frame_address(1));
+#endif
}
template <typename ReturnType> struct Thread {
@@ -179,6 +185,11 @@ template <typename ReturnType> struct Thread {
#endif
if (clone_result == 0) {
+#ifdef LLVM_LIBC_ARCH_AARCH64
+ // We set the frame pointer to be the same as the "sp" so that start args
+ // can be sniffed out from start_thread.
+ __arm_wsr64("x29", __arm_rsr64("sp"));
+#endif
start_thread();
} else if (clone_result < 0) {
if (attrib->owned_stack)
More information about the libc-commits
mailing list