[libcxx-commits] [libcxxabi] [libc++abi] Fix lpStart adjustment for exceptions table (PR #72727)

Maksim Panchenko via libcxx-commits libcxx-commits at lists.llvm.org
Sat Nov 18 17:00:26 PST 2023


https://github.com/maksfb updated https://github.com/llvm/llvm-project/pull/72727

>From 73afd1b5aab3ead0b2410890e34e7b4252c8ab41 Mon Sep 17 00:00:00 2001
From: Maksim Panchenko <maks at fb.com>
Date: Fri, 17 Nov 2023 12:40:09 -0800
Subject: [PATCH 1/2] [libc++abi] Fix lpStart adjustment for exceptions table

When lpStartEncoding is different from DW_EH_PE_omit, lpStart can be set
to zero which is a valid base address for landing pads. Such base value
is useful when landing pads are placed in different sections.

Fixes #72582.
---
 libcxxabi/src/cxa_personality.cpp             |   7 +-
 .../native/x86_64-unknown-linux/lit.local.cfg |   9 ++
 .../lpstart-zero.pass.sh.s                    | 107 ++++++++++++++++++
 3 files changed, 119 insertions(+), 4 deletions(-)
 create mode 100644 libcxxabi/test/native/x86_64-unknown-linux/lit.local.cfg
 create mode 100644 libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s

diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp
index 4570d0b5beb2e2e..4b6c4edbc266985 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -660,10 +660,9 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
     //       dwarf emission
     // Parse LSDA header.
     uint8_t lpStartEncoding = *lsda++;
-    const uint8_t* lpStart =
-        (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding, base);
-    if (lpStart == 0)
-        lpStart = (const uint8_t*)funcStart;
+    const uint8_t* lpStart = lpStartEncoding == DW_EH_PE_omit
+                                 ? (const uint8_t*)funcStart
+                                 : (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding, base);
     uint8_t ttypeEncoding = *lsda++;
     if (ttypeEncoding != DW_EH_PE_omit)
     {
diff --git a/libcxxabi/test/native/x86_64-unknown-linux/lit.local.cfg b/libcxxabi/test/native/x86_64-unknown-linux/lit.local.cfg
new file mode 100644
index 000000000000000..bf3abe0d4881d98
--- /dev/null
+++ b/libcxxabi/test/native/x86_64-unknown-linux/lit.local.cfg
@@ -0,0 +1,9 @@
+def is_x86_64_linux(triple):
+    return ("x86_64" in triple) and ("linux" in triple)
+
+
+is_native = hasattr(config.root, "target_triple") and (
+    config.root.host_triple == config.root.target_triple
+)
+if not is_native or not is_x86_64_linux(config.root.host_triple):
+    config.unsupported = True
diff --git a/libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s b/libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s
new file mode 100644
index 000000000000000..3fd9102b340a13b
--- /dev/null
+++ b/libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s
@@ -0,0 +1,107 @@
+# RUN: %{cxx} %{flags} %{link_flags} -no-pie %s -o %t.exe
+# RUN: %t.exe
+# UNSUPPORTED: no-exceptions
+
+# PURPOSE: Check that libc++abi works correctly when LPStart address is
+# explicitly set to zero.
+
+# This file is generated from the following C++ source code.
+#
+# ```
+# int main() {
+#   try {
+#     throw 42;
+#   } catch (...) {
+#     return 0;
+#   }
+#   return 1;
+# }
+# ```
+# The exception table is modified to use udata4 encoding for LPStart and
+# sdata4 encoding for call sites.
+
+	.text
+	.globl	main                            # -- Begin function main
+	.p2align	4, 0x90
+	.type	main, at function
+main:                                   # @main
+.Lfunc_begin0:
+	.cfi_startproc
+	.globl	__gxx_personality_v0
+	.cfi_personality 3, __gxx_personality_v0
+	.cfi_lsda 27, .Lexception0
+# %bb.0:                                # %entry
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	subq	$32, %rsp
+	movl	$0, -4(%rbp)
+	movl	$4, %edi
+	callq	__cxa_allocate_exception at PLT
+	movq	%rax, %rdi
+	movl	$42, (%rdi)
+.Ltmp0:
+	movq	_ZTIi at GOTPCREL(%rip), %rsi
+	xorl	%eax, %eax
+	movl	%eax, %edx
+	callq	__cxa_throw at PLT
+.Ltmp1:
+	jmp	.LBB0_4
+.LBB0_1:                                # %lpad
+.Ltmp2:
+	movq	%rax, %rcx
+	movl	%edx, %eax
+	movq	%rcx, -16(%rbp)
+	movl	%eax, -20(%rbp)
+# %bb.2:                                # %catch
+	movq	-16(%rbp), %rdi
+	callq	__cxa_begin_catch at PLT
+	movl	$0, -4(%rbp)
+	callq	__cxa_end_catch at PLT
+# %bb.3:                                # %return
+	movl	-4(%rbp), %eax
+	addq	$32, %rsp
+	popq	%rbp
+	.cfi_def_cfa %rsp, 8
+	retq
+.LBB0_4:                                # %unreachable
+.Lfunc_end0:
+	.size	main, .Lfunc_end0-main
+	.cfi_endproc
+
+	.section	.gcc_except_table,"a", at progbits
+	.p2align	2, 0x0
+GCC_except_table0:
+.Lexception0:
+	.byte	3                               # @LPStart Encoding = udata4
+  .long 0
+	.byte	155                             # @TType Encoding = indirect pcrel sdata4
+	.uleb128 .Lttbase0-.Lttbaseref0
+.Lttbaseref0:
+	.byte	11                              # Call site Encoding = udata4
+	.uleb128 .Lcst_end0-.Lcst_begin0
+.Lcst_begin0:
+	.long .Lfunc_begin0-.Lfunc_begin0    # >> Call Site 1 <<
+	.long .Ltmp0-.Lfunc_begin0           #   Call between .Lfunc_begin0 and .Ltmp0
+	.long	0                               #     has no landing pad
+	.byte	0                               #   On action: cleanup
+	.long .Ltmp0-.Lfunc_begin0           # >> Call Site 2 <<
+	.long .Ltmp1-.Ltmp0                  #   Call between .Ltmp0 and .Ltmp1
+  .long .Ltmp2
+	.byte	1                               #   On action: 1
+	.long .Ltmp1-.Lfunc_begin0           # >> Call Site 3 <<
+	.long .Lfunc_end0-.Ltmp1             #   Call between .Ltmp1 and .Lfunc_end0
+	.long	0                               #     has no landing pad
+	.byte	0                               #   On action: cleanup
+.Lcst_end0:
+	.byte	1                               # >> Action Record 1 <<
+                                        #   Catch TypeInfo 1
+	.byte	0                               #   No further actions
+	.p2align	2, 0x0
+                                        # >> Catch TypeInfos <<
+	.long	0                               # TypeInfo 1
+.Lttbase0:
+	.p2align	2, 0x0
+                                        # -- End function

>From 3bade843c88e1b45110dd2ca015e9ad58302f7f7 Mon Sep 17 00:00:00 2001
From: Maksim Panchenko <maks at fb.com>
Date: Sat, 18 Nov 2023 16:59:14 -0800
Subject: [PATCH 2/2] fixup! [libc++abi] Fix lpStart adjustment for exceptions
 table

---
 .../test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s b/libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s
index 3fd9102b340a13b..1943561cdfda893 100644
--- a/libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s
+++ b/libcxxabi/test/native/x86_64-unknown-linux/lpstart-zero.pass.sh.s
@@ -1,4 +1,4 @@
-# RUN: %{cxx} %{flags} %{link_flags} -no-pie %s -o %t.exe
+# RUN: %{cxx} %{flags} %s %{link_flags} -no-pie -o %t.exe
 # RUN: %t.exe
 # UNSUPPORTED: no-exceptions
 



More information about the libcxx-commits mailing list