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 <[email protected]> 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 <[email protected]> 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: _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
