[libunwind] [libunwind][AIX] Fix up TOC register if unw_getcontext is called from a different module (PR #66549)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 18 09:51:58 PDT 2023
https://github.com/xingxue-ibm updated https://github.com/llvm/llvm-project/pull/66549
>From d42f6f35b8a4f3750b151f29951b215889d2c3e4 Mon Sep 17 00:00:00 2001
From: Xing Xue <xingxue at outlook.com>
Date: Fri, 15 Sep 2023 16:09:43 -0400
Subject: [PATCH 1/2] The TOC register (r2) was changed by the glue code if
unw_getcontext is called from a different module. Fix it up by using the
original TOC register saved in the stack frame.
---
libunwind/src/UnwindRegistersSave.S | 29 +++++++++++++++++++++++++++--
libunwind/test/unw_resume.pass.cpp | 3 ---
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S
index 58ffd1b9e1fb35a..f47b38ff848f729 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -305,9 +305,22 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
mflr 0
std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0
PPC64_STR(1)
+ PPC64_STR(4) // Save r4 first since it will be used for fixing r2.
+#if defined(_AIX)
+ // The TOC register (r2) was changed by the glue code if unw_getcontext
+ // is called from a different module. Save the original TOC register
+ // in the context if this is the case.
+ mflr 4
+ lwz 4, 0(4) // Get the first instruction at the return address.
+ lis 0, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"?
+ ori 0, 0, 0x28
+ cmpw 0, 0, 4
+ bne 0, LnoR2Fix // No need to fix up r2 if it is not.
+ ld 2, 40(1) // Use the saved TOC register in the stack.
+LnoR2Fix:
+#endif
PPC64_STR(2)
PPC64_STR(3)
- PPC64_STR(4)
PPC64_STR(5)
PPC64_STR(6)
PPC64_STR(7)
@@ -547,9 +560,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
mflr 0
stw 0, 0(3) // store lr as ssr0
stw 1, 12(3)
+ stw 4, 24(3) // Save r4 first since it will be used for fixing r2.
+#if defined(_AIX)
+ // The TOC register (r2) was changed by the glue code if unw_getcontext
+ // is called from a different module. Save the original TOC register
+ // in the context if this is the case.
+ mflr 4
+ lwz 4, 0(4) // Get the instruction at the return address.
+ xoris 4, 4, 0x8041 // Is it reloading the TOC register "lwz r2,20(r1)"?
+ cmplwi 4, 0x14
+ bne 0, LnoR2Fix // No need to fix up r2 if it is not.
+ lwz 2, 20(1) // Use the saved TOC register in the stack.
+LnoR2Fix:
+#endif
stw 2, 16(3)
stw 3, 20(3)
- stw 4, 24(3)
stw 5, 28(3)
stw 6, 32(3)
stw 7, 36(3)
diff --git a/libunwind/test/unw_resume.pass.cpp b/libunwind/test/unw_resume.pass.cpp
index 76273e4a8ef0a71..08e8d4edeaf2927 100644
--- a/libunwind/test/unw_resume.pass.cpp
+++ b/libunwind/test/unw_resume.pass.cpp
@@ -10,9 +10,6 @@
// Ensure that unw_resume() resumes execution at the stack frame identified by
// cursor.
-// TODO: Investigate this failure on AIX system.
-// XFAIL: target={{.*}}-aix{{.*}}
-
// TODO: Figure out why this fails with Memory Sanitizer.
// XFAIL: msan
>From b9b6bed9a3658627b3d93a22043edb1da40134f2 Mon Sep 17 00:00:00 2001
From: Xing Xue <xingxue at outlook.com>
Date: Mon, 18 Sep 2023 12:47:07 -0400
Subject: [PATCH 2/2] Addressed comment. - use the same code for 32- and 64-bit
comparison.
---
libunwind/src/UnwindRegistersSave.S | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S
index f47b38ff848f729..5534d1734b6ba7b 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -305,18 +305,17 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
mflr 0
std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0
PPC64_STR(1)
- PPC64_STR(4) // Save r4 first since it will be used for fixing r2.
+ PPC64_STR(4) // Save r4 first since it will be used for fixing r2.
#if defined(_AIX)
// The TOC register (r2) was changed by the glue code if unw_getcontext
// is called from a different module. Save the original TOC register
// in the context if this is the case.
- mflr 4
- lwz 4, 0(4) // Get the first instruction at the return address.
- lis 0, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"?
- ori 0, 0, 0x28
- cmpw 0, 0, 4
- bne 0, LnoR2Fix // No need to fix up r2 if it is not.
- ld 2, 40(1) // Use the saved TOC register in the stack.
+ mflr 4
+ lwz 4, 0(4) // Get the first instruction at the return address.
+ xoris 0, 4, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"?
+ cmplwi 0, 0x28
+ bne 0, LnoR2Fix // No need to fix up r2 if it is not.
+ ld 2, 40(1) // Use the saved TOC register in the stack.
LnoR2Fix:
#endif
PPC64_STR(2)
@@ -566,9 +565,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
// is called from a different module. Save the original TOC register
// in the context if this is the case.
mflr 4
- lwz 4, 0(4) // Get the instruction at the return address.
- xoris 4, 4, 0x8041 // Is it reloading the TOC register "lwz r2,20(r1)"?
- cmplwi 4, 0x14
+ lwz 4, 0(4) // Get the instruction at the return address.
+ xoris 0, 4, 0x8041 // Is it reloading the TOC register "ld 2,40(1)"?
+ cmplwi 0, 0x14
bne 0, LnoR2Fix // No need to fix up r2 if it is not.
lwz 2, 20(1) // Use the saved TOC register in the stack.
LnoR2Fix:
More information about the cfe-commits
mailing list