feature:upgrade 1.8.1

Signed-off-by: cs1111 <chenshi51@huawei.com>
Change-Id: I1c83708579c5fb7bba10a16e6228758fa5ba5bc7
This commit is contained in:
cs1111
2025-05-17 18:18:22 +08:00
parent 9d3ce43f8c
commit c52b4a7394
18 changed files with 324 additions and 1271 deletions
@@ -1,31 +0,0 @@
From dd49933f80043f933bc10e2f0f1c6d3e664475ed Mon Sep 17 00:00:00 2001
From: hubin <hubin73@huawei.com>
Date: Fri, 16 Dec 2022 09:24:50 +0800
Subject: [PATCH] fix byte_order_is_valid function logic
byte_order_is_valid is an inline function extracted from unw_create_addr_space
in libunwind 1.6, currently its logic mismatches the function intention.
Signed-off-by: hubin <hubin73@huawei.com>
---
include/libunwind_i.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index fea5c26..9742267 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -119,8 +119,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
static inline int
byte_order_is_valid(int byte_order)
{
- return byte_order != UNW_BIG_ENDIAN
- && byte_order != UNW_LITTLE_ENDIAN;
+ return byte_order == UNW_BIG_ENDIAN
+ || byte_order == UNW_LITTLE_ENDIAN;
}
static inline int
--
2.33.0
+13 -167
View File
@@ -16,7 +16,7 @@ if (defined(ohos_lite)) {
} else {
import("//build/ohos.gni")
}
libunwind_code_dir = "${target_gen_dir}/libunwind-1.6.2"
libunwind_code_dir = "${target_gen_dir}/libunwind-1.8.1"
common_source = [
"$libunwind_code_dir/src/dwarf/Gexpr.c",
"$libunwind_code_dir/src/dwarf/Gfde.c",
@@ -36,6 +36,7 @@ common_source = [
"$libunwind_code_dir/src/mi/dyn-info-list.c",
"$libunwind_code_dir/src/mi/dyn-register.c",
"$libunwind_code_dir/src/mi/flush_cache.c",
"$libunwind_code_dir/src/mi/Gaddress_validator.c",
"$libunwind_code_dir/src/mi/Gdestroy_addr_space.c",
"$libunwind_code_dir/src/mi/Gdyn-extract.c",
"$libunwind_code_dir/src/mi/Gdyn-remote.c",
@@ -74,6 +75,7 @@ common_source = [
"$libunwind_code_dir/src/ptrace/_UPT_destroy.c",
"$libunwind_code_dir/src/ptrace/_UPT_find_proc_info.c",
"$libunwind_code_dir/src/ptrace/_UPT_get_dyn_info_list_addr.c",
"$libunwind_code_dir/src/ptrace/_UPT_get_elf_filename.c",
"$libunwind_code_dir/src/ptrace/_UPT_get_proc_name.c",
"$libunwind_code_dir/src/ptrace/_UPT_put_unwind_info.c",
"$libunwind_code_dir/src/ptrace/_UPT_reg_offset.c",
@@ -128,6 +130,7 @@ arm64_source = [
"$libunwind_code_dir/src/aarch64/Ginit.c",
"$libunwind_code_dir/src/aarch64/Ginit_local.c",
"$libunwind_code_dir/src/aarch64/Ginit_remote.c",
"$libunwind_code_dir/src/aarch64/Gos-linux.c",
"$libunwind_code_dir/src/aarch64/Gis_signal_frame.c",
"$libunwind_code_dir/src/aarch64/Gregs.c",
"$libunwind_code_dir/src/aarch64/Gresume.c",
@@ -141,6 +144,7 @@ arm64_source = [
"$libunwind_code_dir/src/aarch64/Linit.c",
"$libunwind_code_dir/src/aarch64/Linit_local.c",
"$libunwind_code_dir/src/aarch64/Linit_remote.c",
"$libunwind_code_dir/src/aarch64/Los-linux.c",
"$libunwind_code_dir/src/aarch64/Lis_signal_frame.c",
"$libunwind_code_dir/src/aarch64/Lregs.c",
"$libunwind_code_dir/src/aarch64/Lresume.c",
@@ -211,6 +215,7 @@ riscv64_source = [
"$libunwind_code_dir/src/riscv/Linit.c",
"$libunwind_code_dir/src/riscv/Linit_local.c",
"$libunwind_code_dir/src/riscv/Linit_remote.c",
"$libunwind_code_dir/src/riscv/Los-linux.c",
"$libunwind_code_dir/src/riscv/Lis_signal_frame.c",
"$libunwind_code_dir/src/riscv/Lregs.c",
"$libunwind_code_dir/src/riscv/Lreg_states_iterate.c",
@@ -244,6 +249,7 @@ action("libunwind_action") {
"$libunwind_code_dir/src/mi/dyn-info-list.c",
"$libunwind_code_dir/src/mi/dyn-register.c",
"$libunwind_code_dir/src/mi/flush_cache.c",
"$libunwind_code_dir/src/mi/Gaddress_validator.c",
"$libunwind_code_dir/src/mi/Gdestroy_addr_space.c",
"$libunwind_code_dir/src/mi/Gdyn-extract.c",
"$libunwind_code_dir/src/mi/Gdyn-remote.c",
@@ -281,6 +287,7 @@ action("libunwind_action") {
"$libunwind_code_dir/src/ptrace/_UPT_create.c",
"$libunwind_code_dir/src/ptrace/_UPT_destroy.c",
"$libunwind_code_dir/src/ptrace/_UPT_find_proc_info.c",
"$libunwind_code_dir/src/ptrace/_UPT_get_elf_filename.c",
"$libunwind_code_dir/src/ptrace/_UPT_get_dyn_info_list_addr.c",
"$libunwind_code_dir/src/ptrace/_UPT_get_proc_name.c",
"$libunwind_code_dir/src/ptrace/_UPT_put_unwind_info.c",
@@ -328,6 +335,7 @@ action("libunwind_action") {
"$libunwind_code_dir/src/aarch64/Ginit.c",
"$libunwind_code_dir/src/aarch64/Ginit_local.c",
"$libunwind_code_dir/src/aarch64/Ginit_remote.c",
"$libunwind_code_dir/src/aarch64/Gos-linux.c",
"$libunwind_code_dir/src/aarch64/Gis_signal_frame.c",
"$libunwind_code_dir/src/aarch64/Gregs.c",
"$libunwind_code_dir/src/aarch64/Gresume.c",
@@ -341,6 +349,7 @@ action("libunwind_action") {
"$libunwind_code_dir/src/aarch64/Linit.c",
"$libunwind_code_dir/src/aarch64/Linit_local.c",
"$libunwind_code_dir/src/aarch64/Linit_remote.c",
"$libunwind_code_dir/src/aarch64/Los-linux.c",
"$libunwind_code_dir/src/aarch64/Lis_signal_frame.c",
"$libunwind_code_dir/src/aarch64/Lregs.c",
"$libunwind_code_dir/src/aarch64/Lresume.c",
@@ -403,6 +412,7 @@ action("libunwind_action") {
"$libunwind_code_dir/src/riscv/Linit.c",
"$libunwind_code_dir/src/riscv/Linit_local.c",
"$libunwind_code_dir/src/riscv/Linit_remote.c",
"$libunwind_code_dir/src/riscv/Los-linux.c",
"$libunwind_code_dir/src/riscv/Lis_signal_frame.c",
"$libunwind_code_dir/src/riscv/Lregs.c",
"$libunwind_code_dir/src/riscv/Lreg_states_iterate.c",
@@ -414,7 +424,7 @@ action("libunwind_action") {
"$libunwind_code_dir/src/riscv/siglongjmp.S",
]
inputs = [ "//third_party/libunwind/libunwind-1.6.2.tar.gz" ]
inputs = [ "//third_party/libunwind/libunwind-1.8.1.tar.gz" ]
libunwind_path = rebase_path("${target_gen_dir}", root_build_dir)
libunwind_source_path = rebase_path("//third_party/libunwind", root_build_dir)
args = [
@@ -425,87 +435,6 @@ action("libunwind_action") {
]
}
if ("${target_cpu}" == "arm") {
arm_source_local = [
"$libunwind_code_dir/src/arm/Lcreate_addr_space.c",
"$libunwind_code_dir/src/arm/Lex_tables.c",
"$libunwind_code_dir/src/arm/Lget_proc_info.c",
"$libunwind_code_dir/src/arm/Lget_save_loc.c",
"$libunwind_code_dir/src/arm/Lglobal.c",
"$libunwind_code_dir/src/arm/Linit.c",
"$libunwind_code_dir/src/arm/Linit_local.c",
"$libunwind_code_dir/src/arm/Linit_remote.c",
"$libunwind_code_dir/src/arm/Los-linux.c",
"$libunwind_code_dir/src/arm/Lregs.c",
"$libunwind_code_dir/src/arm/Lresume.c",
"$libunwind_code_dir/src/arm/Lstash_frame.c",
"$libunwind_code_dir/src/arm/Lstep.c",
"$libunwind_code_dir/src/arm/Ltrace.c",
]
} else if ("${target_cpu}" == "arm64") {
arm64_source_local = [
"$libunwind_code_dir/src/aarch64/Lcreate_addr_space.c",
"$libunwind_code_dir/src/aarch64/Lget_proc_info.c",
"$libunwind_code_dir/src/aarch64/Lget_save_loc.c",
"$libunwind_code_dir/src/aarch64/Lglobal.c",
"$libunwind_code_dir/src/aarch64/Linit.c",
"$libunwind_code_dir/src/aarch64/Linit_local.c",
"$libunwind_code_dir/src/aarch64/Linit_remote.c",
"$libunwind_code_dir/src/aarch64/Lis_signal_frame.c",
"$libunwind_code_dir/src/aarch64/Lregs.c",
"$libunwind_code_dir/src/aarch64/Lresume.c",
"$libunwind_code_dir/src/aarch64/Lstash_frame.c",
"$libunwind_code_dir/src/aarch64/Lstep.c",
"$libunwind_code_dir/src/aarch64/Ltrace.c",
]
} else if ("${target_cpu}" == "riscv64") {
riscv64_source_local = [
"$libunwind_code_dir/src/riscv/Lcreate_addr_space.c",
"$libunwind_code_dir/src/riscv/Lget_proc_info.c",
"$libunwind_code_dir/src/riscv/Lget_save_loc.c",
"$libunwind_code_dir/src/riscv/Lglobal.c",
"$libunwind_code_dir/src/riscv/Linit.c",
"$libunwind_code_dir/src/riscv/Linit_local.c",
"$libunwind_code_dir/src/riscv/Linit_remote.c",
"$libunwind_code_dir/src/riscv/Lis_signal_frame.c",
"$libunwind_code_dir/src/riscv/Lreg_states_iterate.c",
"$libunwind_code_dir/src/riscv/Lregs.c",
"$libunwind_code_dir/src/riscv/Lresume.c",
"$libunwind_code_dir/src/riscv/Lstep.c",
]
} else if ("${target_cpu}" == "x64" || "${target_cpu}" == "x86_64") {
x64_source_local = [
"$libunwind_code_dir/src/x86_64/Lcreate_addr_space.c",
"$libunwind_code_dir/src/x86_64/Lget_proc_info.c",
"$libunwind_code_dir/src/x86_64/Lget_save_loc.c",
"$libunwind_code_dir/src/x86_64/Lglobal.c",
"$libunwind_code_dir/src/x86_64/Linit.c",
"$libunwind_code_dir/src/x86_64/Linit_local.c",
"$libunwind_code_dir/src/x86_64/Linit_remote.c",
"$libunwind_code_dir/src/x86_64/Los-linux.c",
"$libunwind_code_dir/src/x86_64/Lregs.c",
"$libunwind_code_dir/src/x86_64/Lresume.c",
"$libunwind_code_dir/src/x86_64/Lstash_frame.c",
"$libunwind_code_dir/src/x86_64/Lstep.c",
"$libunwind_code_dir/src/x86_64/Ltrace.c",
]
}
libunwind_la_SOURCES_local = [
"$libunwind_code_dir/src/mi/Ldyn-extract.c",
"$libunwind_code_dir/src/mi/Lfind_dynamic_proc_info.c",
"$libunwind_code_dir/src/mi/Lget_proc_info_by_ip.c",
"$libunwind_code_dir/src/mi/Lget_proc_name.c",
"$libunwind_code_dir/src/mi/Lput_dynamic_unwind_info.c",
"$libunwind_code_dir/src/mi/Ldestroy_addr_space.c",
"$libunwind_code_dir/src/mi/Lget_reg.c",
"$libunwind_code_dir/src/mi/Lset_reg.c",
"$libunwind_code_dir/src/mi/Lget_fpreg.c",
"$libunwind_code_dir/src/mi/Lset_fpreg.c",
"$libunwind_code_dir/src/mi/Lset_caching_policy.c",
"$libunwind_code_dir/src/mi/Lset_cache_size.c",
]
remove_sources = []
ptrace_sources = [
@@ -562,7 +491,7 @@ config("unwind_config_public") {
include_dirs = [
"$libunwind_code_dir/src",
"$libunwind_code_dir/include",
get_label_info(":libunwind_action", "target_gen_dir") + "/libunwind-1.6.2",
get_label_info(":libunwind_action", "target_gen_dir") + "/libunwind-1.8.1",
]
cflags = [
@@ -781,45 +710,6 @@ if (defined(ohos_lite)) {
]
public_configs = [ ":unwind_config_public" ]
}
static_library("libunwind_local") {
sources = common_source
public_configs = [ ":unwind_config_public" ]
public_configs += [ ":unwind_config_local_only" ]
if (target_cpu == "arm") {
sources += arm_source
sources -= arm_source_local
public_configs += [ ":unwind_config_arm" ]
} else if (target_cpu == "arm64") {
sources += arm64_source
sources -= arm64_source_local
public_configs += [ ":unwind_config_arm64" ]
} else if (target_cpu == "riscv64") {
sources += riscv64_source
sources -= riscv64_source_local
public_configs += [ ":unwind_config_riscv64" ]
} else if (target_cpu == "x64") {
sources += x64_source
sources -= x64_source_local
public_configs += [ ":unwind_config_x64" ]
} else if (target_cpu == "x86_64") {
sources += x64_source
sources -= x64_source_local
public_configs += [ ":unwind_config_x86_64" ]
}
sources -= libunwind_dwarf_local_la_SOURCES
sources -= libunwind_la_SOURCES_local
sources -= ptrace_sources
cflags = [
"-DHAS_ARK_FRAME",
"-DPARSE_BUILD_ID",
"-DUNW_LOCAL_ONLY",
"-DNO_RESERVE_CACHE",
]
deps = [ ":libunwind_action" ]
}
} else {
ohos_source_set("unwind_source_arm") {
configs = [ ":unwind_config_remote" ]
@@ -981,48 +871,4 @@ if (defined(ohos_lite)) {
subsystem_name = "thirdparty"
part_name = "libunwind"
}
# for internal use only, the interfaces may have compatible issue
ohos_static_library("libunwind_local") {
sources = common_source
public_configs = [ ":unwind_config_public" ]
public_configs += [ ":unwind_config_local_only" ]
if (target_cpu == "arm") {
sources += arm_source
sources -= arm_source_local
public_configs += [ ":unwind_config_arm" ]
} else if (target_cpu == "arm64") {
sources += arm64_source
sources -= arm64_source_local
public_configs += [ ":unwind_config_arm64" ]
} else if (target_cpu == "riscv64") {
sources += riscv64_source
sources -= riscv64_source_local
public_configs += [ ":unwind_config_riscv64" ]
} else if (target_cpu == "x64") {
sources += x64_source
sources -= x64_source_local
public_configs += [ ":unwind_config_x64" ]
} else if (target_cpu == "x86_64") {
sources += x64_source
sources -= x64_source_local
public_configs += [ ":unwind_config_x86_64" ]
}
sources -= libunwind_dwarf_local_la_SOURCES
sources -= libunwind_la_SOURCES_local
sources -= ptrace_sources
deps = [ ":libunwind_action" ]
cflags = [
"-DHAS_ARK_FRAME",
"-DPARSE_BUILD_ID",
"-DUNW_LOCAL_ONLY",
"-DNO_RESERVE_CACHE",
"-DHAVE_PIPE2",
]
subsystem_name = "thirdparty"
part_name = "libunwind"
}
}
+11 -48
View File
@@ -1,6 +1,7 @@
# libunwind
[![Build Status](https://travis-ci.org/libunwind/libunwind.svg?branch=master)](https://travis-ci.org/libunwind/libunwind)
[![CI - Unix](https://github.com/libunwind/libunwind/actions/workflows/CI-unix.yml/badge.svg)](https://github.com/libunwind/libunwind/actions/workflows/CI-unix.yml)
[![CI - Windows](https://github.com/libunwind/libunwind/actions/workflows/CI-win.yml/badge.svg)](https://github.com/libunwind/libunwind/actions/workflows/CI-win.yml)
This library supports several architecture/operating-system combinations:
@@ -15,13 +16,17 @@ This library supports several architecture/operating-system combinations:
| Linux | SuperH | ✓ |
| Linux | IA-64 | ✓ |
| Linux | PARISC | Works well, but C library missing unwind-info |
| Linux | Tilegx | 64-bit mode only |
| Linux | MIPS | Newly added |
| Linux | MIPS | |
| Linux | RISC-V | 64-bit only |
| Linux | LoongArch | 64-bit only |
| HP-UX | IA-64 | Mostly works, but known to have serious limitations |
| FreeBSD | x86-64 | ✓ |
| FreeBSD | x86 | ✓ |
| FreeBSD | AArch64 | ✓ |
| FreeBSD | PPC32 | ✓ |
| FreeBSD | PPC64 | ✓ |
| QNX | Aarch64 | ✓ |
| QNX | x86-64 | ✓ |
| Solaris | x86-64 | ✓ |
## Libc Requirements
@@ -41,13 +46,13 @@ such dependencies
| arm | p | |
| hppa | p | p |
| ia64 | p | r |
| loongarch | p | |
| mips | p | |
| ppc32 | r | |
| ppc64 | r | r |
| riscv | p | p |
| s390x | p | p |
| sh | r | |
| tilegx | r | r |
| x86 | p | r |
| x86_64 | p | p |
@@ -89,18 +94,6 @@ libunwind should be configured and installed on HP-UX like this:
Caveat: Unwinding of 32-bit (ILP32) binaries is not supported at the moment.
### Workaround for older versions of GCC
GCC v3.0 and GCC v3.2 ship with a bad version of `sys/types.h`. The
workaround is to issue the following commands before running
`configure`:
$ mkdir $top_dir/include/sys
$ cp /usr/include/sys/types.h $top_dir/include/sys
GCC v3.3.2 or later have been fixed and do not require this
workaround.
### Building for PowerPC64 / Linux
For building for power64 you should use:
@@ -136,27 +129,6 @@ After building the library, you can run a set of regression tests with:
$ make check
### Expected results on IA-64 Linux
Unless you have a very recent C library and compiler installed, it is
currently expected to have the following tests fail on IA-64 Linux:
* `Gtest-init` (should pass starting with glibc-2.3.x/gcc-3.4)
* `Ltest-init` (should pass starting with glibc-2.3.x/gcc-3.4)
* `test-ptrace` (should pass starting with glibc-2.3.x/gcc-3.4)
* `run-ia64-test-dyn1` (should pass starting with glibc-2.3.x)
This does not mean that libunwind cannot be used with older compilers
or C libraries, it just means that for certain corner cases, unwinding
will fail. Since they're corner cases, it is not likely for
applications to trigger them.
Note: If you get lots of errors in `Gia64-test-nat` and `Lia64-test-nat`, it's
almost certainly a sign of an old assembler. The GNU assembler used
to encode previous-stack-pointer-relative offsets incorrectly.
This bug was fixed on 21-Sep-2004 so any later assembler will be
fine.
### Expected results on x86 Linux
The following tests are expected to fail on x86 Linux:
@@ -172,10 +144,6 @@ The following tests are expected to fail on x86-64 Linux:
### Expected results on PARISC Linux
Caveat: GCC v3.4 or newer is needed on PA-RISC Linux. Earlier
versions of the compiler failed to generate the exception-handling
program header (`GNU_EH_FRAME`) needed for unwinding.
The following tests are expected to fail on x86-64 Linux:
* `Gtest-bt` (backtrace truncated at `kill()` due to lack of unwind-info)
@@ -232,10 +200,5 @@ commands:
## Contacting the Developers
Please direct all questions regarding this library to <libunwind-devel@nongnu.org>.
You can do this by sending an email to <libunwind-request@nongnu.org> with
a body of "subscribe libunwind-devel", or you can subscribe and manage your
subscription via the web-interface at <https://savannah.nongnu.org/mail/?group=libunwind>.
You can also interact on our GitHub page: <https://github.com/libunwind/libunwind>.
Please raise issues and pull requests through the GitHub repository:
<https://github.com/libunwind/libunwind>.
+3 -3
View File
@@ -1,11 +1,11 @@
[
{
"Name": "openEuler:libunwind",
"Name": "libunwind",
"License": "MIT License",
"License File": "LICENSE",
"Version Number": "1.6.2-7.oe2203sp3",
"Version Number": "1.8.1",
"Owner": "zengzhi5@huawei.com",
"Upstream URL": "http://www.openeuler.org",
"Upstream URL": "https://github.com/libunwind/libunwind.git",
"Description": "a portable and efficient C programming interface (API) to determine the call-chain of a program."
}
]
@@ -1,48 +0,0 @@
From 8a0e2fa6579085dc8f51b2bdd90d8b00a2e7d6ab Mon Sep 17 00:00:00 2001
From: he7850 <im.bin.hu@gmail.com>
Date: Wed, 3 May 2023 15:18:27 +0800
Subject: [PATCH] aarch64: unw_step() validates address before calling
dwarf_get
Signed-off-by: he7850 <im.bin.hu@gmail.com>
---
src/aarch64/Gstep.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/aarch64/Gstep.c b/src/aarch64/Gstep.c
index f4ef369d3..a2ed9bc35 100644
--- a/src/aarch64/Gstep.c
+++ b/src/aarch64/Gstep.c
@@ -156,18 +156,28 @@ unw_step (unw_cursor_t *cursor)
dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_X30], &c->dwarf.ip);
}
- /* Restore default memory validation state */
- c->validate = validate;
-
ret = dwarf_step (&c->dwarf);
Debug(1, "dwarf_step()=%d\n", ret);
+ /* Restore default memory validation state */
+ c->validate = validate;
+
if (unlikely (ret == -UNW_ESTOPUNWIND))
return ret;
if (unlikely (ret < 0))
{
/* DWARF failed. */
+
+ /*
+ * We could get here because of missing/bad unwind information.
+ * Validate all addresses before dereferencing.
+ */
+ if (c->dwarf.as == unw_local_addr_space)
+ {
+ c->validate = 1;
+ }
+
if (is_plt_entry (&c->dwarf))
{
Debug (2, "found plt entry\n");
@@ -1,46 +0,0 @@
From ffb69e2384538a7d4b634bdc491d7da9b7220f57 Mon Sep 17 00:00:00 2001
From: chenziyang <chenziyang4@huawei.com>
Date: Tue, 11 Jul 2023 10:19:22 +0800
Subject: [PATCH] avoid calling printf because OE glibc-2.34 used
-mno-outline-atomics buildflag, it will cause printf to be non-atomic
operations on ARMv8.1 platform. This will cause printf to stuck into dead
loop because ptrace sing-step execution cause race condition during printf
instructions.
---
tests/mapper.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/tests/mapper.c b/tests/mapper.c
index b47ae78..fcfb080 100644
--- a/tests/mapper.c
+++ b/tests/mapper.c
@@ -43,6 +43,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
# define MAP_NORESERVE 0
#endif
+void __attribute__((noinline)) push_some_stacks(int n)
+{
+ if (n >= 1)
+ {
+ push_some_stacks(n - 1);
+ push_some_stacks(n - 1);
+ }
+}
+
int
main (void)
{
@@ -71,7 +80,7 @@ main (void)
printf ("Turning on single-stepping...\n");
kill (getpid (), SIGUSR1); /* tell test-ptrace to start single-stepping */
- printf ("Va bene?\n");
+ push_some_stacks (4);
kill (getpid (), SIGUSR2); /* tell test-ptrace to stop single-stepping */
printf ("Turned single-stepping off...\n");
return 0;
--
2.33.0
@@ -1,140 +0,0 @@
From e8fa8d0ca5349d01cf5505eb0d952ef26c62cc94 Mon Sep 17 00:00:00 2001
From: Stephen Webb <swebb@blackberry.com>
Date: Fri, 21 Oct 2022 15:52:22 -0400
Subject: [PATCH] check-namespace.sh: adjust aarch64 symbols
Some symbols for aarch64 were missing, and some were marked as
extraneous in this ABI checker.
Fixes #389.
---
tests/check-namespace.sh.in | 46 ++++++++++++++++---------------------
1 file changed, 20 insertions(+), 26 deletions(-)
diff --git a/tests/check-namespace.sh.in b/tests/check-namespace.sh.in
index f99fb59..f9201a2 100644
--- a/tests/check-namespace.sh.in
+++ b/tests/check-namespace.sh.in
@@ -117,7 +117,8 @@ check_local_unw_abi () {
match _U${plat}_flush_cache
match _U${plat}_get_accessors
- match _U${plat}_getcontext
+ match _U${plat}_get_elf_image
+ match _U${plat}_get_exe_image_path
match _U${plat}_regname
match _U${plat}_strerror
@@ -130,68 +131,59 @@ check_local_unw_abi () {
case ${plat} in
arm)
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
+ match _U${plat}_getcontext
match _U${plat}_is_fpreg
match _UL${plat}_search_unwind_table
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
;;
hppa)
+ match _U${plat}_getcontext
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
match _U${plat}_setcontext
;;
ia64)
+ match _U${plat}_getcontext
match _UL${plat}_search_unwind_table
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
;;
x86)
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
+ match _U${plat}_getcontext
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
;;
x86_64)
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
+ match _U${plat}_getcontext
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
match _U${plat}_setcontext
;;
ppc*)
+ match _U${plat}_getcontext
match _U${plat}_get_func_addr
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
;;
tilegx)
+ match _U${plat}_getcontext
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
match _UL${plat}_local_addr_space_init
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
match ${plat}_lock
;;
s390x)
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
+ match _U${plat}_getcontext
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
match _U${plat}_setcontext
;;
riscv)
- match _U${plat}_get_elf_image
- match _U${plat}_get_exe_image_path
+ match _U${plat}_getcontext
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
@@ -288,15 +280,15 @@ check_generic_unw_abi () {
match _U${plat}_dwarf_search_unwind_table
match _U${plat}_dwarf_find_unwind_table
;;
- tilegx)
- match _U${plat}_dwarf_search_unwind_table
+ tilegx)
+ match _U${plat}_dwarf_search_unwind_table
match _U${plat}_dwarf_find_unwind_table
- match _U${plat}_get_elf_image
+ match _U${plat}_get_elf_image
match _U${plat}_get_exe_image_path
- match _U${plat}_is_fpreg
- match _U${plat}_local_addr_space_init
- match ${plat}_lock
- ;;
+ match _U${plat}_is_fpreg
+ match _U${plat}_local_addr_space_init
+ match ${plat}_lock
+ ;;
s390x)
match _U${plat}_is_fpreg
match _U${plat}_get_elf_image
@@ -315,6 +307,8 @@ check_generic_unw_abi () {
match _U${plat}_is_fpreg
match _U${plat}_dwarf_search_unwind_table
match _U${plat}_dwarf_find_unwind_table
+ match _U${plat}_get_elf_image
+ match _U${plat}_get_exe_image_path
;;
esac
--
2.27.0
@@ -1,28 +0,0 @@
From 0224ac01f620ff226bdf877e2b278d20c0fa1b56 Mon Sep 17 00:00:00 2001
From: chenziyang <chenziyang4@huawei.com>
Date: Mon, 3 Jul 2023 14:27:47 +0800
Subject: [PATCH] Fix run-ptrace-mapper test case failed by allowing
unw_get_proc_info() return unsuccessful result. Because it is not an error
unw_get_proc_info() does not return the auxiliary information, so we edit
test case and don't treat it as error.
---
tests/test-ptrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test-ptrace.c b/tests/test-ptrace.c
index 846bcd8..32f42e8 100644
--- a/tests/test-ptrace.c
+++ b/tests/test-ptrace.c
@@ -111,7 +111,7 @@ do_backtrace (void)
printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp);
}
- if ((ret = unw_get_proc_info (&c, &pi)) < 0)
+ if ((ret = unw_get_proc_info (&c, &pi)) < 0 && ret != -UNW_ENOINFO) /* It's possible unw_get_proc_info don't return infomation */
panic ("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret);
else if (verbose)
printf ("\tproc=%016lx-%016lx\n\thandler=%lx lsda=%lx",
--
2.33.0
@@ -1,31 +0,0 @@
From fedff5ac77c945fc0c5df534074163a784bfa5b3 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Wed, 7 Sep 2022 14:01:36 +0200
Subject: [PATCH] tests/run-coredump-unwind: Skip test if no coredump has been
created
In some build environments, coredumps are not created even if the
corresponding ulimit is positive. This change skips the test if
the coredump is missing.
---
tests/run-coredump-unwind | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tests/run-coredump-unwind b/tests/run-coredump-unwind
index 8d07742..0c2b28c 100755
--- a/tests/run-coredump-unwind
+++ b/tests/run-coredump-unwind
@@ -48,6 +48,10 @@ fi
./crasher backing_files
) 2>/dev/null
COREFILE=$TEMPDIR/core*
+if ! test -f "$COREFILE"; then
+ echo "crasher process did not produce coredump, test skipped"
+ exit 77
+fi
# magic option -testcase enables checking for the specific contents of the stack
./test-coredump-unwind $COREFILE -testcase `cat $TEMPDIR/backing_files`
--
2.33.0
View File
+6 -16
View File
@@ -31,14 +31,9 @@ def untar_file(tar_file_path, extract_path):
def move_file(src_path, dst_path):
files = [
"0001-fix-byte_order_is_valid-function-logic.patch",
"backport-check-namespace.sh-adjust-aarch64-symbols.patch",
"backport-tests-run-coredump-unwind-Skip-test-if-no-coredump-h.patch",
"backport-aarch64-unw_step-validates-address-before-calling-dwarf_get.patch",
"backport-avoid-calling-printf-because-OE-glibc-2.34-used-mno-.patch",
"backport-fix-run-ptrace-mapper-test-case-failed.patch",
"ohos-configure.patch",
"ohos-access-mem-crash-fix.patch"
"ohos-access-mem-no-sanitize.patch",
"ohos-fix-register-index-overflow.patch"
]
for file in files:
src_file = os.path.join(src_path, file)
@@ -59,14 +54,9 @@ def apply_patch(patch_file, target_dir):
def do_patch(target_dir):
patch_file = [
"0001-fix-byte_order_is_valid-function-logic.patch",
"backport-check-namespace.sh-adjust-aarch64-symbols.patch",
"backport-tests-run-coredump-unwind-Skip-test-if-no-coredump-h.patch",
"backport-aarch64-unw_step-validates-address-before-calling-dwarf_get.patch",
"backport-avoid-calling-printf-because-OE-glibc-2.34-used-mno-.patch",
"backport-fix-run-ptrace-mapper-test-case-failed.patch",
"ohos-configure.patch",
"ohos-access-mem-crash-fix.patch"
"ohos-access-mem-no-sanitize.patch",
"ohos-fix-register-index-overflow.patch"
]
for patch in patch_file:
@@ -78,8 +68,8 @@ def main():
libunwind_path.add_argument('--gen-dir', help='generate path of log', required=True)
libunwind_path.add_argument('--source-dir', help='generate path of log', required=True)
args = libunwind_path.parse_args()
tar_file_path = os.path.join(args.source_dir, "libunwind-1.6.2.tar.gz")
target_dir = os.path.join(args.gen_dir, "libunwind-1.6.2")
tar_file_path = os.path.join(args.source_dir, "libunwind-1.8.1.tar.gz")
target_dir = os.path.join(args.gen_dir, "libunwind-1.8.1")
untar_file(tar_file_path, args.gen_dir)
move_file(args.source_dir, target_dir)
Binary file not shown.
Binary file not shown.
-158
View File
@@ -1,158 +0,0 @@
Name: libunwind
Epoch: 2
Version: 1.6.2
Release: 7
Summary: Libunwind provides a C ABI to determine the call-chain of a program
License: BSD
URL: http://savannah.nongnu.org/projects/libunwind
Source: http://download-mirror.savannah.gnu.org/releases/libunwind/libunwind-%{version}.tar.gz
Patch0001: 0001-fix-byte_order_is_valid-function-logic.patch
Patch2: backport-check-namespace.sh-adjust-aarch64-symbols.patch
Patch3: backport-tests-run-coredump-unwind-Skip-test-if-no-coredump-h.patch
Patch4: backport-aarch64-unw_step-validates-address-before-calling-dwarf_get.patch
Patch5: backport-avoid-calling-printf-because-OE-glibc-2.34-used-mno-.patch
Patch6: backport-fix-run-ptrace-mapper-test-case-failed.patch
ExclusiveArch: aarch64 %{ix86} x86_64
BuildRequires: automake libtool autoconf texlive-latex2man gcc-c++
%description
Libunwind defines a portable and efficient C programming interface (API) to
determine the call-chain of a program. The API additionally provides the means
to manipulate the preserved (callee-saved) state of each call-frame and to
resume execution at any point in the call-chain (non-local goto). The API
supports both local (same-process) and remote (across-process) operation.
%package devel
Summary: Development files for libunwind
Requires: libunwind = %{epoch}:%{version}-%{release}
%description devel
This package contains development files for libunwind.
%package_help
%prep
%autosetup -n %{name}-%{version} -p1
%build
aclocal
libtoolize --force
autoheader
automake --add-missing
autoconf
%configure --enable-static --enable-shared --enable-setjmp=no
%make_build
%install
%make_install
%delete_la
# /usr/include/libunwind-ptrace.h
# [...] aren't really part of the libunwind API. They are implemented in
# a archive library called libunwind-ptrace.a.
mv -f $RPM_BUILD_ROOT%{_libdir}/libunwind-ptrace.a $RPM_BUILD_ROOT%{_libdir}/libunwind-ptrace.a-save
rm -f $RPM_BUILD_ROOT%{_libdir}/libunwind*.a
mv -f $RPM_BUILD_ROOT%{_libdir}/libunwind-ptrace.a-save $RPM_BUILD_ROOT%{_libdir}/libunwind-ptrace.a
rm -f $RPM_BUILD_ROOT%{_libdir}/libunwind-ptrace*.so*
# fix multilib conflicts
touch -r NEWS $RPM_BUILD_ROOT%{_includedir}/libunwind.h
%check
make check || true
%pre
%preun
%ldconfig_scriptlets
%files
%defattr(-,root,root)
%license COPYING
%{_libdir}/libunwind*.so.*
%files devel
%defattr(-,root,root)
%{_libdir}/pkgconfig/libunwind*.pc
# <unwind.h> does not get installed for REMOTE_ONLY targets - check it.
%{_includedir}/unwind.h
%{_includedir}/libunwind*.h
%{_libdir}/libunwind-ptrace.a
%{_libdir}/libunwind*.so
%files help
%defattr(-,root,root)
%doc README NEWS
%{_mandir}/*/*
%changelog
* Tue Jul 11 2023 chenziyang <chenziyang4@huawei.com> - 2:1.6.2-7
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:backport upstream patch to fix failed run-ptrace-mapper testcase
* Mon Jul 03 2023 chenziyang <chenziyang4@huawei.com> - 2:1.6.2-6
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:fix failed testcase by editing test-ptrace testcase
* Tue Jun 20 2023 wangjiang <wangjiang37@h-partners.com> - 2:1.6.2-5
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:fix failed testcase
* Mon Feb 20 2023 shixuantong <shixuantong1@huawei.com> - 2:1.6.2-4
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:fix some test fail
* Fri Dec 16 2022 Bin Hu <hubin73@huawei.com> - 2:1.6.2-2
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:fix byte_order_is_valid function logic
* Mon Nov 7 2022 Bin Hu <hubin73@huawei.com> - 2:1.6.2-1
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:update version 1.6.2
* Tue Oct 25 2022 zhangruifang <zhangruifang1@h-partners.com> - 2:1.5.0-3
- Rebuild for next release
- fix bogus date in changelog
* Tue Apr 26 2022 renhongxun<renhongxun@h-partners.com> - 2:1.5.0-2
- add epoch
* Wed Dec 22 2021 shangyibin<shangyibin1@huawei.com> - 1.5.0-1
- Upgrade to version 1.5.0
* Fri Jul 30 2021 liudabo<liudabo1@huawei.com> - 1.4.0-2
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:Fix gcc build
* Mon Mar 30 2020 wenzhanli<wenzhanli2@huawei.com> - 1.4.0-1
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:update version 1.4.0
* Sun Jan 12 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.3.1-3
- remove useless patch
* Fri Sep 27 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.3.1-2
- del unnecessary statement
* Mon Sep 2 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.3.1-1
- Package init
-505
View File
@@ -1,505 +0,0 @@
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index 97422679..bc529810 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -167,6 +167,7 @@ target_is_big_endian()
#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
#define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
+#define NO_SANITIZE __attribute__((no_sanitize("address"), no_sanitize("hwaddress")))
/* Type of a mask that can be used to inhibit preemption. At the
userlevel, preemption is caused by signals and hence sigset_t is
diff --git a/include/tdep-aarch64/libunwind_i.h b/include/tdep-aarch64/libunwind_i.h
index d96833a2..3d57587b 100644
--- a/include/tdep-aarch64/libunwind_i.h
+++ b/include/tdep-aarch64/libunwind_i.h
@@ -148,8 +148,7 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
{
if (!DWARF_GET_LOC (loc))
return -1;
- *val = *(unw_word_t *) DWARF_GET_LOC (loc);
- return 0;
+ return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, 0, c->as_arg);
}
static inline int
@@ -157,8 +156,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
{
if (!DWARF_GET_LOC (loc))
return -1;
- *(unw_word_t *) DWARF_GET_LOC (loc) = val;
- return 0;
+ return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, 1, c->as_arg);
}
#else /* !UNW_LOCAL_ONLY */
diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h
index 88ebfb06..c19ed523 100644
--- a/include/tdep-arm/libunwind_i.h
+++ b/include/tdep-arm/libunwind_i.h
@@ -131,8 +131,7 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
{
if (!DWARF_GET_LOC (loc))
return -1;
- *val = *(unw_word_t *) DWARF_GET_LOC (loc);
- return 0;
+ return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, 0, c->as_arg);
}
static inline int
@@ -140,8 +139,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
{
if (!DWARF_GET_LOC (loc))
return -1;
- *(unw_word_t *) DWARF_GET_LOC (loc) = val;
- return 0;
+ return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, 1, c->as_arg);
}
#else /* !UNW_LOCAL_ONLY */
@@ -254,6 +252,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
#define tdep_getcontext_trace unw_getcontext
#define tdep_init_done UNW_OBJ(init_done)
+#define tdep_init_mem_validate UNW_OBJ(init_mem_validate)
#define tdep_init UNW_OBJ(init)
#define arm_find_proc_info UNW_OBJ(find_proc_info)
#define arm_put_unwind_info UNW_OBJ(put_unwind_info)
@@ -294,6 +293,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
extern atomic_bool tdep_init_done;
extern void tdep_init (void);
+extern void tdep_init_mem_validate (void);
extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info,
void *arg);
diff --git a/src/aarch64/Ginit.c b/src/aarch64/Ginit.c
index 2b08feb3..58ff370a 100644
--- a/src/aarch64/Ginit.c
+++ b/src/aarch64/Ginit.c
@@ -25,9 +25,11 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <errno.h>
+#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
+#include <sys/syscall.h>
#include <stdatomic.h>
#include "unwind_i.h"
@@ -88,7 +90,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
static int mem_validate_pipe[2] = {-1, -1};
-
+pthread_mutex_t g_mutex;
#ifdef HAVE_PIPE2
static inline void
do_pipe2 (int pipefd[2])
@@ -129,13 +131,11 @@ open_pipe (void)
do_pipe2 (mem_validate_pipe);
}
-ALWAYS_INLINE
-static int
-write_validate (void *addr)
+ALWAYS_INLINE NO_SANITIZE static int write_validate (void *addr)
{
int ret = -1;
ssize_t bytes = 0;
-
+ pthread_mutex_lock(&g_mutex);
do
{
char buf;
@@ -152,21 +152,17 @@ write_validate (void *addr)
do
{
- ret = write (mem_validate_pipe[1], addr, 1);
+ /* use syscall insteadof write() so that ASAN does not complain */
+ ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1);
}
while ( errno == EINTR );
-
+ pthread_mutex_unlock(&g_mutex);
return ret;
}
static int (*mem_validate_func) (void *addr, size_t len);
static int msync_validate (void *addr, size_t len)
{
- if (msync (addr, len, MS_ASYNC) != 0)
- {
- return -1;
- }
-
return write_validate (addr);
}
@@ -316,8 +312,7 @@ validate_mem (unw_word_t addr)
return 0;
}
-static int
-access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
+NO_SANITIZE static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
{
if (unlikely (write))
@@ -329,8 +324,7 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
{
/* validate address */
const struct cursor *c = (const struct cursor *)arg;
- if (likely (c != NULL) && unlikely (c->validate)
- && unlikely (validate_mem (addr))) {
+ if (unlikely (validate_mem (addr))) {
Debug (16, "mem[%016lx] -> invalid\n", addr);
return -1;
}
diff --git a/src/arm/Gglobal.c b/src/arm/Gglobal.c
index 0700f930..efb3cce5 100644
--- a/src/arm/Gglobal.c
+++ b/src/arm/Gglobal.c
@@ -61,6 +61,7 @@ tdep_init (void)
dwarf_init ();
#ifndef UNW_REMOTE_ONLY
+ tdep_init_mem_validate ();
arm_local_addr_space_init ();
#endif
atomic_store(&tdep_init_done, 1); /* signal that we're initialized... */
diff --git a/src/arm/Ginit.c b/src/arm/Ginit.c
index 0bac0d72..0c67a62c 100644
--- a/src/arm/Ginit.c
+++ b/src/arm/Ginit.c
@@ -22,8 +22,13 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#include <errno.h>
+#include <pthread.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <stdatomic.h>
#include "unwind_i.h"
@@ -74,41 +79,161 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
-/* Cache of already validated addresses */
-#define NLGA 4
-static unw_word_t last_good_addr[NLGA];
-static int lga_victim;
+static int mem_validate_pipe[2] = {-1, -1};
+pthread_mutex_t g_mutex;
+#ifdef HAVE_PIPE2
+static inline void
+do_pipe2 (int pipefd[2])
+{
+ pipe2 (pipefd, O_CLOEXEC | O_NONBLOCK);
+}
+#else
+static inline void
+set_pipe_flags (int fd)
+{
+ int fd_flags = fcntl (fd, F_GETFD, 0);
+ int status_flags = fcntl (fd, F_GETFL, 0);
-static int
-validate_mem (unw_word_t addr)
+ fd_flags |= FD_CLOEXEC;
+ fcntl (fd, F_SETFD, fd_flags);
+
+ status_flags |= O_NONBLOCK;
+ fcntl (fd, F_SETFL, status_flags);
+}
+
+static inline void
+do_pipe2 (int pipefd[2])
{
- int i, victim;
- size_t len;
+ pipe (pipefd);
+ set_pipe_flags(pipefd[0]);
+ set_pipe_flags(pipefd[1]);
+}
+#endif
- if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
- len = PAGE_SIZE;
- else
- len = PAGE_SIZE * 2;
+static inline void
+open_pipe (void)
+{
+ if (mem_validate_pipe[0] != -1)
+ close (mem_validate_pipe[0]);
+ if (mem_validate_pipe[1] != -1)
+ close (mem_validate_pipe[1]);
- addr = PAGE_START(addr);
+ do_pipe2 (mem_validate_pipe);
+}
- if (addr == 0)
+ALWAYS_INLINE NO_SANITIZE static int write_validate (void *addr)
+{
+ int ret = -1;
+ ssize_t bytes = 0;
+ pthread_mutex_lock(&g_mutex);
+
+ do
+ {
+ char buf;
+ bytes = syscall(SYS_read, mem_validate_pipe[0], &buf, 1);
+ }
+ while ( errno == EINTR );
+
+ int valid_read = (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK);
+ if (!valid_read)
+ {
+ // re-open closed pipe
+ open_pipe ();
+ }
+
+ do
+ {
+ ret = syscall(SYS_write, mem_validate_pipe[1], addr, 1);
+ }
+ while ( errno == EINTR );
+ pthread_mutex_unlock(&g_mutex);
+ return ret;
+}
+
+static int (*mem_validate_func) (void *addr, size_t len);
+static int msync_validate (void *addr, size_t len)
+{
+ if (msync (addr, len, MS_ASYNC) != 0)
+ {
+ return -1;
+ }
+
+ return write_validate (addr);
+}
+
+#ifdef HAVE_MINCORE
+static int mincore_validate (void *addr, size_t len)
+{
+ unsigned char mvec[2]; /* Unaligned access may cross page boundary */
+
+ /* mincore could fail with EAGAIN but we conservatively return -1
+ instead of looping. */
+ if (mincore (addr, len, (unsigned char *)mvec) != 0)
+ {
return -1;
+ }
+ return write_validate (addr);
+}
+#endif
+
+/* Initialise memory validation method. On linux kernels <2.6.21,
+ mincore() returns incorrect value for MAP_PRIVATE mappings,
+ such as stacks. If mincore() was available at compile time,
+ check if we can actually use it. If not, use msync() instead. */
+HIDDEN void
+tdep_init_mem_validate (void)
+{
+ open_pipe ();
+
+#ifdef HAVE_MINCORE
+ unsigned char present = 1;
+ unw_word_t addr = PAGE_START((unw_word_t)&present);
+ unsigned char mvec[1];
+ int ret;
+ while ((ret = mincore ((void*)addr, PAGE_SIZE, (unsigned char *)mvec)) == -1 &&
+ errno == EAGAIN) {}
+ if (ret == 0)
+ {
+ Debug(1, "using mincore to validate memory\n");
+ mem_validate_func = mincore_validate;
+ }
+ else
+#endif
+ {
+ Debug(1, "using msync to validate memory\n");
+ mem_validate_func = msync_validate;
+ }
+}
+
+/* Cache of already validated addresses */
+#define NLGA 4
+#if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD
+// thread-local variant
+static _Thread_local unw_word_t last_good_addr[NLGA];
+static _Thread_local int lga_victim;
+
+static int
+is_cached_valid_mem(unw_word_t addr)
+{
+ int i;
for (i = 0; i < NLGA; i++)
{
- if (last_good_addr[i] && (addr == last_good_addr[i]))
+ if (addr == last_good_addr[i])
+ return 1;
+ }
return 0;
}
- if (msync ((void *) addr, len, MS_ASYNC) == -1)
- return -1;
-
+static void
+cache_valid_mem(unw_word_t addr)
+{
+ int i, victim;
victim = lga_victim;
for (i = 0; i < NLGA; i++) {
- if (!last_good_addr[victim]) {
- last_good_addr[victim++] = addr;
- return 0;
+ if (last_good_addr[victim] == 0) {
+ last_good_addr[victim] = addr;
+ return;
}
victim = (victim + 1) % NLGA;
}
@@ -117,12 +242,72 @@ validate_mem (unw_word_t addr)
last_good_addr[victim] = addr;
victim = (victim + 1) % NLGA;
lga_victim = victim;
+}
+
+#else
+// global, thread safe variant
+static _Atomic unw_word_t last_good_addr[NLGA];
+static _Atomic int lga_victim;
+static int
+is_cached_valid_mem(unw_word_t addr)
+{
+ int i;
+ for (i = 0; i < NLGA; i++)
+ {
+ if (addr == atomic_load(&last_good_addr[i]))
+ return 1;
+ }
return 0;
}
+static void
+cache_valid_mem(unw_word_t addr)
+{
+ int i, victim;
+ victim = atomic_load(&lga_victim);
+ unw_word_t zero = 0;
+ for (i = 0; i < NLGA; i++) {
+ if (atomic_compare_exchange_strong(&last_good_addr[victim], &zero, addr)) {
+ return;
+ }
+ victim = (victim + 1) % NLGA;
+ }
+
+ /* All slots full. Evict the victim. */
+ atomic_store(&last_good_addr[victim], addr);
+ victim = (victim + 1) % NLGA;
+ atomic_store(&lga_victim, victim);
+}
+#endif
+
static int
-access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
+validate_mem (unw_word_t addr)
+{
+ size_t len;
+
+ if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
+ len = PAGE_SIZE;
+ else
+ len = PAGE_SIZE * 2;
+
+ addr = PAGE_START(addr);
+
+ if (addr == 0)
+ return -1;
+
+ if (is_cached_valid_mem(addr))
+ return 0;
+
+ if (mem_validate_func ((void *) addr, len) == -1)
+ return -1;
+
+ cache_valid_mem(addr);
+
+ return 0;
+}
+
+NO_SANITIZE static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
{
/* validate address */
diff --git a/src/arm/Gregs.c b/src/arm/Gregs.c
index 0d52f0b2..5d704e94 100644
--- a/src/arm/Gregs.c
+++ b/src/arm/Gregs.c
@@ -35,24 +35,39 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
case UNW_ARM_R15:
if (write)
c->dwarf.ip = *valp; /* update the IP cache */
+ /* fall-through */
case UNW_ARM_R0:
+ /* fall-through */
case UNW_ARM_R1:
+ /* fall-through */
case UNW_ARM_R2:
+ /* fall-through */
case UNW_ARM_R3:
+ /* fall-through */
case UNW_ARM_R4:
+ /* fall-through */
case UNW_ARM_R5:
+ /* fall-through */
case UNW_ARM_R6:
+ /* fall-through */
case UNW_ARM_R7:
+ /* fall-through */
case UNW_ARM_R8:
+ /* fall-through */
case UNW_ARM_R9:
+ /* fall-through */
case UNW_ARM_R10:
+ /* fall-through */
case UNW_ARM_R11:
+ /* fall-through */
case UNW_ARM_R12:
+ /* fall-through */
case UNW_ARM_R14:
loc = c->dwarf.loc[reg - UNW_ARM_R0];
break;
case UNW_ARM_R13:
+ /* fall-through */
case UNW_ARM_CFA:
if (write)
return -UNW_EREADONLYREG;
diff --git a/src/arm/Gtrace.c b/src/arm/Gtrace.c
index 51fc281d..fb6e9eb3 100644
--- a/src/arm/Gtrace.c
+++ b/src/arm/Gtrace.c
@@ -479,6 +479,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
case UNW_ARM_FRAME_GUESSED:
/* Fall thru to standard processing after forcing validation. */
c->validate = 1;
+ /* fall-through */
case UNW_ARM_FRAME_STANDARD:
/* Advance standard traceable frame. */
+77
View File
@@ -0,0 +1,77 @@
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index 1dbcb6a8..eaee5dec 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -175,6 +175,7 @@ target_is_big_endian(void)
#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
#define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
+#define NO_SANITIZE __attribute__((no_sanitize("address"), no_sanitize("hwaddress")))
/* Type of a mask that can be used to inhibit preemption. At the
userlevel, preemption is caused by signals and hence sigset_t is
diff --git a/src/aarch64/Ginit.c b/src/aarch64/Ginit.c
index 6986dbb6..10bec543 100644
--- a/src/aarch64/Ginit.c
+++ b/src/aarch64/Ginit.c
@@ -125,7 +125,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
}
-static int
+NO_SANITIZE static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
{
diff --git a/src/arm/Ginit.c b/src/arm/Ginit.c
index 20071fd0..91676e76 100644
--- a/src/arm/Ginit.c
+++ b/src/arm/Ginit.c
@@ -74,7 +74,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
}
-static int
+NO_SANITIZE static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
{
diff --git a/src/mi/Gaddress_validator.c b/src/mi/Gaddress_validator.c
index a81a0835..85bc4878 100644
--- a/src/mi/Gaddress_validator.c
+++ b/src/mi/Gaddress_validator.c
@@ -98,7 +98,7 @@ _open_pipe (void)
* process's address space and marked as readable. The read will force the page
* to be swapped in if it's not already there.
*/
-static bool
+NO_SANITIZE static bool
_write_validate (unw_word_t addr)
{
int ret = -1;
diff --git a/src/x86/Ginit.c b/src/x86/Ginit.c
index 956d8088..f576db8f 100644
--- a/src/x86/Ginit.c
+++ b/src/x86/Ginit.c
@@ -75,7 +75,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
}
-static int
+NO_SANITIZE static int
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
void *arg)
{
diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c
index ca3c0228..ed4ddd78 100644
--- a/src/x86_64/Ginit.c
+++ b/src/x86_64/Ginit.c
@@ -74,7 +74,7 @@ get_dyn_info_list_addr (unw_addr_space_t as UNUSED, unw_word_t *dyn_info_list_ad
}
-static int
+NO_SANITIZE static int
access_mem (unw_addr_space_t as UNUSED, unw_word_t addr, unw_word_t *val, int write,
void *arg)
{
+95 -50
View File
@@ -1,19 +1,14 @@
From ff95fda912df85087fcc3159a9f2fb662401c531 Mon Sep 17 00:00:00 2001
From: cs1111 <chenshi51@huawei.com>
Date: Thu, 2 Jan 2025 16:33:48 +0800
Subject: [PATCH] ohos-configure
commit 0e3f431fc6b494f8d9361d48e35d2b99dddd2dcf
Author: cs1111 <chenshi51@huawei.com>
Date: Sat May 17 18:01:38 2025 +0800
Signed-off-by: cs1111 <chenshi51@huawei.com>
---
include/config.h | 235 +++++++++++++++++++++++++++++
include/libunwind-common.h | 292 +++++++++++++++++++++++++++++++++++++
2 files changed, 527 insertions(+)
create mode 100644 include/config.h
create mode 100644 include/libunwind-common.h
fix:ohos-configure
Signed-off-by: cs1111 <chenshi51@huawei.com>
diff --git a/include/config.h b/include/config.h
new file mode 100644
index 00000000..816b017f
index 00000000..98fcd1e9
--- /dev/null
+++ b/include/config.h
@@ -0,0 +1,235 @@
@@ -215,13 +210,13 @@ index 00000000..816b017f
+#define PACKAGE "libunwind"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "libunwind-devel@nongnu.org"
+#define PACKAGE_BUGREPORT "https://github.com/libunwind/libunwind"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libunwind"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libunwind 1.6.2"
+#define PACKAGE_STRING "libunwind 1.8.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libunwind"
@@ -230,7 +225,7 @@ index 00000000..816b017f
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.6.2"
+#define PACKAGE_VERSION "1.8.1"
+
+/* The size of `off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
@@ -239,7 +234,7 @@ index 00000000..816b017f
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.6.2"
+#define VERSION "1.8.1"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
@@ -252,12 +247,13 @@ index 00000000..816b017f
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
\ No newline at end of file
diff --git a/include/libunwind-common.h b/include/libunwind-common.h
new file mode 100644
index 00000000..9de37c1d
index 00000000..42fd74b4
--- /dev/null
+++ b/include/libunwind-common.h
@@ -0,0 +1,292 @@
@@ -0,0 +1,344 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2001-2004 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
@@ -284,8 +280,8 @@ index 00000000..9de37c1d
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#define UNW_VERSION_MAJOR 1
+#define UNW_VERSION_MINOR 6
+#define UNW_VERSION_EXTRA 2
+#define UNW_VERSION_MINOR 8
+#define UNW_VERSION_EXTRA 1
+
+#define UNW_VERSION_CODE(maj,min) (((maj) << 16) | (min))
+#define UNW_VERSION UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR)
@@ -361,7 +357,7 @@ index 00000000..9de37c1d
+
+typedef enum
+ {
+ UNW_INIT_SIGNAL_FRAME = 1, /* We know this is a signal frame */
+ UNW_INIT_SIGNAL_FRAME = 1 /* We know this is a signal frame */
+ }
+unw_init_local2_flags_t;
+
@@ -467,6 +463,36 @@ index 00000000..9de37c1d
+ NULL. */
+ int (*get_proc_name) (unw_addr_space_t, unw_word_t, char *, size_t,
+ unw_word_t *, void *);
+
+ /* Optional call back to obtain the name of a elf file where the ip belongs to.
+ This callback is optional and may be set to NULL. */
+ int (*get_elf_filename) (unw_addr_space_t, unw_word_t, char *, size_t,
+ unw_word_t *, void *);
+
+ /* Optional call back to obtain the start and end ip of a procedure.
+ * procedure ip range is [start, end), the range is without end.
+ * This callback is optional and may be set to NULL.
+ */
+ int (*get_proc_ip_range) (unw_addr_space_t, unw_word_t, unw_word_t *,
+ unw_word_t *, void *);
+
+ /* Optional call back to return a mask to be used with pointer
+ * authentication on arm64.
+ *
+ * The on bits in the returned mask indicate which bits in a return address
+ * are part of a pointer authentication code. These are the bits in the
+ * return address to turn off so that the calling frame can be found
+ * for the unwinding to continue.
+ *
+ * The return value must be host-endian. e.g. if the target is big-endian
+ * and the host is little endian, the implementation of this function
+ * must byte swap.
+ *
+ * This callback is optional and may be set to NULL. In this case all
+ * the bits in the return address are used, as if no masking were done.
+ */
+ unw_word_t (*ptrauth_insn_mask) (unw_addr_space_t, void *);
+
+ }
+unw_accessors_t;
+
@@ -491,34 +517,43 @@ index 00000000..9de37c1d
+ }
+unw_save_loc_t;
+
+struct dl_phdr_info;
+typedef int (*unw_iterate_phdr_callback_t) (struct dl_phdr_info *, size_t, void *);
+typedef int (*unw_iterate_phdr_func_t) (unw_iterate_phdr_callback_t, void *);
+
+/* These routines work both for local and remote unwinding. */
+
+#define unw_local_addr_space UNW_OBJ(local_addr_space)
+#define unw_create_addr_space UNW_OBJ(create_addr_space)
+#define unw_destroy_addr_space UNW_OBJ(destroy_addr_space)
+#define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
+#define unw_get_accessors_int UNW_ARCH_OBJ(get_accessors_int)
+#define unw_init_local UNW_OBJ(init_local)
+#define unw_init_local2 UNW_OBJ(init_local2)
+#define unw_init_remote UNW_OBJ(init_remote)
+#define unw_step UNW_OBJ(step)
+#define unw_resume UNW_OBJ(resume)
+#define unw_get_proc_info UNW_OBJ(get_proc_info)
+#define unw_get_proc_info_by_ip UNW_OBJ(get_proc_info_by_ip)
+#define unw_reg_states_iterate UNW_OBJ(reg_states_iterate)
+#define unw_apply_reg_state UNW_OBJ(apply_reg_state)
+#define unw_get_reg UNW_OBJ(get_reg)
+#define unw_set_reg UNW_OBJ(set_reg)
+#define unw_get_fpreg UNW_OBJ(get_fpreg)
+#define unw_set_fpreg UNW_OBJ(set_fpreg)
+#define unw_get_save_loc UNW_OBJ(get_save_loc)
+#define unw_is_signal_frame UNW_OBJ(is_signal_frame)
+#define unw_get_proc_name UNW_OBJ(get_proc_name)
+#define unw_set_caching_policy UNW_OBJ(set_caching_policy)
+#define unw_set_cache_size UNW_OBJ(set_cache_size)
+#define unw_regname UNW_ARCH_OBJ(regname)
+#define unw_flush_cache UNW_ARCH_OBJ(flush_cache)
+#define unw_strerror UNW_ARCH_OBJ(strerror)
+#define unw_local_addr_space UNW_OBJ(local_addr_space)
+#define unw_create_addr_space UNW_OBJ(create_addr_space)
+#define unw_destroy_addr_space UNW_OBJ(destroy_addr_space)
+#define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
+#define unw_get_accessors_int UNW_ARCH_OBJ(get_accessors_int)
+#define unw_init_local UNW_OBJ(init_local)
+#define unw_init_local2 UNW_OBJ(init_local2)
+#define unw_init_remote UNW_OBJ(init_remote)
+#define unw_step UNW_OBJ(step)
+#define unw_resume UNW_OBJ(resume)
+#define unw_get_proc_info UNW_OBJ(get_proc_info)
+#define unw_get_proc_info_by_ip UNW_OBJ(get_proc_info_by_ip)
+#define unw_get_proc_info_in_range UNW_OBJ(get_proc_info_in_range)
+#define unw_reg_states_iterate UNW_OBJ(reg_states_iterate)
+#define unw_apply_reg_state UNW_OBJ(apply_reg_state)
+#define unw_get_reg UNW_OBJ(get_reg)
+#define unw_set_reg UNW_OBJ(set_reg)
+#define unw_get_fpreg UNW_OBJ(get_fpreg)
+#define unw_set_fpreg UNW_OBJ(set_fpreg)
+#define unw_get_save_loc UNW_OBJ(get_save_loc)
+#define unw_is_signal_frame UNW_OBJ(is_signal_frame)
+#define unw_get_proc_name UNW_OBJ(get_proc_name)
+#define unw_get_proc_name_by_ip UNW_OBJ(get_proc_name_by_ip)
+#define unw_get_elf_filename UNW_OBJ(get_elf_filename)
+#define unw_get_elf_filename_by_ip UNW_OBJ(get_elf_filename_by_ip)
+#define unw_set_caching_policy UNW_OBJ(set_caching_policy)
+#define unw_set_cache_size UNW_OBJ(set_cache_size)
+#define unw_set_iterate_phdr_function UNW_OBJ(set_iterate_phdr_function)
+#define unw_regname UNW_ARCH_OBJ(regname)
+#define unw_flush_cache UNW_ARCH_OBJ(flush_cache)
+#define unw_strerror UNW_ARCH_OBJ(strerror)
+
+extern unw_addr_space_t unw_create_addr_space (unw_accessors_t *, int);
+extern void unw_destroy_addr_space (unw_addr_space_t);
@@ -527,6 +562,7 @@ index 00000000..9de37c1d
+extern void unw_flush_cache (unw_addr_space_t, unw_word_t, unw_word_t);
+extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t);
+extern int unw_set_cache_size (unw_addr_space_t, size_t, int);
+extern void unw_set_iterate_phdr_function (unw_addr_space_t, unw_iterate_phdr_func_t);
+extern const char *unw_regname (unw_regnum_t);
+
+extern int unw_init_local (unw_cursor_t *, unw_context_t *);
@@ -537,6 +573,12 @@ index 00000000..9de37c1d
+extern int unw_get_proc_info (unw_cursor_t *, unw_proc_info_t *);
+extern int unw_get_proc_info_by_ip (unw_addr_space_t, unw_word_t,
+ unw_proc_info_t *, void *);
+extern int unw_get_proc_info_in_range (unw_word_t, unw_word_t,
+ unw_word_t, unw_word_t,
+ unw_word_t, unw_word_t,
+ unw_addr_space_t, unw_word_t,
+ unw_proc_info_t *, int,
+ void *);
+extern int unw_reg_states_iterate (unw_cursor_t *, unw_reg_states_callback, void *);
+extern int unw_apply_reg_state (unw_cursor_t *, void *);
+extern int unw_get_reg (unw_cursor_t *, int, unw_word_t *);
@@ -546,10 +588,13 @@ index 00000000..9de37c1d
+extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *);
+extern int unw_is_signal_frame (unw_cursor_t *);
+extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *);
+extern int unw_get_proc_name_by_ip (unw_addr_space_t, unw_word_t, char *,
+ size_t, unw_word_t *, void *);
+extern int unw_get_elf_filename (unw_cursor_t *, char *, size_t, unw_word_t *);
+extern int unw_get_elf_filename_by_ip (unw_addr_space_t, unw_word_t, char *,
+ size_t, unw_word_t *, void *);
+extern const char *unw_strerror (int);
+extern int unw_backtrace (void **, int);
+extern int unw_backtrace2 (void **, int, unw_context_t*, int);
+
+extern unw_addr_space_t unw_local_addr_space;
--
2.34.1
+119
View File
@@ -0,0 +1,119 @@
diff --git a/src/aarch64/Gos-linux.c b/src/aarch64/Gos-linux.c
index 7cd8c879..d0f0cb76 100644
--- a/src/aarch64/Gos-linux.c
+++ b/src/aarch64/Gos-linux.c
@@ -38,63 +38,59 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
{
/* Since there are no signals involved here we restore EH and non scratch
registers only. */
+ unsigned long regs[24];
+ regs[0] = uc->uc_mcontext.regs[0];
+ regs[1] = uc->uc_mcontext.regs[1];
+ regs[2] = uc->uc_mcontext.regs[2];
+ regs[3] = uc->uc_mcontext.regs[3];
+ regs[4] = uc->uc_mcontext.regs[19];
+ regs[5] = uc->uc_mcontext.regs[20];
+ regs[6] = uc->uc_mcontext.regs[21];
+ regs[7] = uc->uc_mcontext.regs[22];
+ regs[8] = uc->uc_mcontext.regs[23];
+ regs[9] = uc->uc_mcontext.regs[24];
+ regs[10] = uc->uc_mcontext.regs[25];
+ regs[11] = uc->uc_mcontext.regs[26];
+ regs[12] = uc->uc_mcontext.regs[27];
+ regs[13] = uc->uc_mcontext.regs[28];
+ regs[14] = uc->uc_mcontext.regs[29]; /* FP */
+ regs[15] = uc->uc_mcontext.regs[30]; /* LR */
+ regs[16] = GET_FPCTX(uc)->vregs[8];
+ regs[17] = GET_FPCTX(uc)->vregs[9];
+ regs[18] = GET_FPCTX(uc)->vregs[10];
+ regs[19] = GET_FPCTX(uc)->vregs[11];
+ regs[20] = GET_FPCTX(uc)->vregs[12];
+ regs[21] = GET_FPCTX(uc)->vregs[13];
+ regs[22] = GET_FPCTX(uc)->vregs[14];
+ regs[23] = GET_FPCTX(uc)->vregs[15];
+ unsigned long sp = uc->uc_mcontext.sp;
+
+ struct regs_overlay {
+ char x[sizeof(regs)];
+ };
+
__asm__ __volatile__ (
- "ldr x0, %[x0]\n\t"
- "ldr x1, %[x1]\n\t"
- "ldr x2, %[x2]\n\t"
- "ldr x3, %[x3]\n\t"
- "ldr x19, %[x19]\n\t"
- "ldr x20, %[x20]\n\t"
- "ldr x21, %[x21]\n\t"
- "ldr x22, %[x22]\n\t"
- "ldr x23, %[x23]\n\t"
- "ldr x24, %[x24]\n\t"
- "ldr x25, %[x25]\n\t"
- "ldr x26, %[x26]\n\t"
- "ldr x27, %[x27]\n\t"
- "ldr x28, %[x28]\n\t"
- "ldr x29, %[x29]\n\t"
- "ldr x30, %[x30]\n\t"
- "ldr d8, %[d8]\n\t"
- "ldr d9, %[d9]\n\t"
- "ldr d10, %[d10]\n\t"
- "ldr d11, %[d11]\n\t"
- "ldr d12, %[d12]\n\t"
- "ldr d13, %[d13]\n\t"
- "ldr d14, %[d14]\n\t"
- "ldr d15, %[d15]\n\t"
- "ldr x5, %[sp]\n\t"
- "mov sp, x5\n\t"
- "ret\n"
+ "mov x4, %0\n"
+ "mov x5, %1\n"
+ "ldp x0, x1, [x4]\n"
+ "ldp x2, x3, [x4,16]\n"
+ "ldp x19, x20, [x4,32]\n"
+ "ldp x21, x22, [x4,48]\n"
+ "ldp x23, x24, [x4,64]\n"
+ "ldp x25, x26, [x4,80]\n"
+ "ldp x27, x28, [x4,96]\n"
+ "ldp x29, x30, [x4,112]\n"
+ "ldp d8, d9, [x4,128]\n"
+ "ldp d10, d11, [x4,144]\n"
+ "ldp d12, d13, [x4,160]\n"
+ "ldp d14, d15, [x4,176]\n"
+ "mov sp, x5\n"
+ "ret \n"
:
- : [x0] "m"(uc->uc_mcontext.regs[0]),
- [x1] "m"(uc->uc_mcontext.regs[1]),
- [x2] "m"(uc->uc_mcontext.regs[2]),
- [x3] "m"(uc->uc_mcontext.regs[3]),
- [x19] "m"(uc->uc_mcontext.regs[19]),
- [x20] "m"(uc->uc_mcontext.regs[20]),
- [x21] "m"(uc->uc_mcontext.regs[21]),
- [x22] "m"(uc->uc_mcontext.regs[22]),
- [x23] "m"(uc->uc_mcontext.regs[23]),
- [x24] "m"(uc->uc_mcontext.regs[24]),
- [x25] "m"(uc->uc_mcontext.regs[25]),
- [x26] "m"(uc->uc_mcontext.regs[26]),
- [x27] "m"(uc->uc_mcontext.regs[27]),
- [x28] "m"(uc->uc_mcontext.regs[28]),
- [x29] "m"(uc->uc_mcontext.regs[29]), /* FP */
- [x30] "m"(uc->uc_mcontext.regs[30]), /* LR */
- [d8] "m"(GET_FPCTX(uc)->vregs[8]),
- [d9] "m"(GET_FPCTX(uc)->vregs[9]),
- [d10] "m"(GET_FPCTX(uc)->vregs[10]),
- [d11] "m"(GET_FPCTX(uc)->vregs[11]),
- [d12] "m"(GET_FPCTX(uc)->vregs[12]),
- [d13] "m"(GET_FPCTX(uc)->vregs[13]),
- [d14] "m"(GET_FPCTX(uc)->vregs[14]),
- [d15] "m"(GET_FPCTX(uc)->vregs[15]),
- [sp] "m"(uc->uc_mcontext.sp)
- : "x0", "x1", "x2", "x3", "x19", "x20", "x21", "x22", "x23", "x24",
- "x25", "x26", "x27", "x28", "x29", "x30"
- );
+ : "r" (regs),
+ "r" (sp),
+ "m" (*(struct regs_overlay *)regs)
+ );
}
else
{