diff --git a/src/coreclr/src/pal/src/exception/seh-unwind.cpp b/src/coreclr/src/pal/src/exception/seh-unwind.cpp index 654e385dec40a6..53c86a0045384f 100644 --- a/src/coreclr/src/pal/src/exception/seh-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/seh-unwind.cpp @@ -111,22 +111,6 @@ static void WinContextToUnwindContext(CONTEXT *winContext, unw_context_t *unwCon unwContext->regs[13] = winContext->Sp; unwContext->regs[14] = winContext->Lr; unwContext->regs[15] = winContext->Pc; -#elif defined(HOST_ARM64) - unwContext->uc_mcontext.pc = winContext->Pc; - unwContext->uc_mcontext.sp = winContext->Sp; - unwContext->uc_mcontext.regs[29] = winContext->Fp; - unwContext->uc_mcontext.regs[30] = winContext->Lr; - - unwContext->uc_mcontext.regs[19] = winContext->X19; - unwContext->uc_mcontext.regs[20] = winContext->X20; - unwContext->uc_mcontext.regs[21] = winContext->X21; - unwContext->uc_mcontext.regs[22] = winContext->X22; - unwContext->uc_mcontext.regs[23] = winContext->X23; - unwContext->uc_mcontext.regs[24] = winContext->X24; - unwContext->uc_mcontext.regs[25] = winContext->X25; - unwContext->uc_mcontext.regs[26] = winContext->X26; - unwContext->uc_mcontext.regs[27] = winContext->X27; - unwContext->uc_mcontext.regs[28] = winContext->X28; #endif } diff --git a/src/coreclr/src/pal/src/libunwind/.gitignore b/src/coreclr/src/pal/src/libunwind/.gitignore index 724a1f4882e2cc..7b7905f0d59815 100644 --- a/src/coreclr/src/pal/src/libunwind/.gitignore +++ b/src/coreclr/src/pal/src/libunwind/.gitignore @@ -75,7 +75,5 @@ tests/[GL]ia64-test-readonly tests/[GL]ia64-test-stack tests/ia64-test-dyn1 tests/ia64-test-sig -tests/[GL]x64-test-dwarf-expressions -tests/x64-unwind-badjmp-signal-frame tests/*.log tests/*.trs diff --git a/src/coreclr/src/pal/src/libunwind/.travis.yml b/src/coreclr/src/pal/src/libunwind/.travis.yml index 7bf0f8d0638efa..4a74b4a1bcb3ed 100644 --- a/src/coreclr/src/pal/src/libunwind/.travis.yml +++ b/src/coreclr/src/pal/src/libunwind/.travis.yml @@ -9,18 +9,6 @@ env: - TARGET=mipsel-unknown-linux-gnu # Currently experiencing build failures here #- TARGET=powerpc64-linux-gnu - -linux-s390x: &linux-s390x - os: linux - arch: s390x - env: TARGET=s390x-linux-gnu - script: - - ./autogen.sh - - ./configure - - make -j32 - - ulimit -c unlimited - - make check -j32 - script: - ./autogen.sh - ./configure --target=$TARGET --host=$HOST @@ -28,7 +16,3 @@ script: - sudo bash -c 'echo core.%p.%p > /proc/sys/kernel/core_pattern' - ulimit -c unlimited - if [ $TARGET == 'x86_64-linux-gnu' ]; then make check -j32; fi - -jobs: - include: - - <<: *linux-s390x diff --git a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt index fc47c89f640cf2..5c66b90fdb0503 100644 --- a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt @@ -13,9 +13,10 @@ elseif(CLR_CMAKE_HOST_ARCH_I386) endif() set(PKG_MAJOR "1") -set(PKG_MINOR "5") -set(PKG_EXTRA "-rc2") +set(PKG_MINOR "3") +set(PKG_EXTRA "-rc1") configure_file(include/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h) configure_file(include/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h) configure_file(include/tdep/libunwind_i.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h) + diff --git a/src/coreclr/src/pal/src/libunwind/Makefile.am b/src/coreclr/src/pal/src/libunwind/Makefile.am index 8132fa4cb952aa..711d9100c75512 100644 --- a/src/coreclr/src/pal/src/libunwind/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/Makefile.am @@ -41,9 +41,6 @@ endif if ARCH_SH include_HEADERS += include/libunwind-sh.h endif -if ARCH_S390X -include_HEADERS += include/libunwind-s390x.h -endif if !REMOTE_ONLY include_HEADERS += include/libunwind.h include/unwind.h @@ -87,8 +84,6 @@ noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \ include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h \ include/tdep-sh/dwarf-config.h \ include/tdep-sh/jmpbuf.h include/tdep-sh/libunwind_i.h \ - include/tdep-s390x/dwarf-config.h \ - include/tdep-s390x/jmpbuf.h include/tdep-s390x/libunwind_i.h \ include/tdep/libunwind_i.h \ include/tdep/jmpbuf.h include/tdep/dwarf-config.h diff --git a/src/coreclr/src/pal/src/libunwind/README b/src/coreclr/src/pal/src/libunwind/README index b6d93ae4a68551..694f600b06dc91 100644 --- a/src/coreclr/src/pal/src/libunwind/README +++ b/src/coreclr/src/pal/src/libunwind/README @@ -1,83 +1,53 @@ -# libunwind +-*- mode: Outline -*- [![Build Status](https://travis-ci.org/libunwind/libunwind.svg?branch=master)](https://travis-ci.org/libunwind/libunwind) -This is version 1.5 of the unwind library. This library supports +This is version 1.3 of the unwind library. This library supports several architecture/operating-system combinations: -| System | Architecture | Status | -| :------ | :----------- | :----- | -| Linux | x86-64 | ✓ | -| Linux | x86 | ✓ | -| Linux | ARM | ✓ | -| Linux | AArch64 | ✓ | -| Linux | PPC64 | ✓ | -| 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 | -| HP-UX | IA-64 | Mostly works, but known to have serious limitations | -| FreeBSD | x86-64 | ✓ | -| FreeBSD | x86 | ✓ | -| FreeBSD | AArch64 | ✓ | -| Solaris | x86-64 | ✓ | - -## Libc Requirements - -libunwind depends on getcontext(), setcontext() functions which are missing -from C libraries like musl-libc because they are considered to be "obsolescent" -API by POSIX document. The following table tries to track current status of -such dependencies - - - r, requires - - p, provides its own implementation - - empty, no requirement - -| Archtecture | getcontext | setcontext | -|--------------|------------|------------| -| aarch64 | p | | -| arm | p | | -| hppa | p | p | -| ia64 | p | r | -| mips | p | | -| ppc32 | r | | -| ppc64 | r | r | -| s390x | p | p | -| sh | r | | -| tilegx | r | r | -| x86 | p | r | -| x86_64 | p | p | - -## General Build Instructions + Linux/x86-64: Works well. + Linux/x86: Works well. + Linux/ARM: Works well. + Linux/IA-64: Works well. + Linux/PARISC: Works well, but C library missing unwind-info. + HP-UX/IA-64: Mostly works but known to have some serious limitations. + MIPS: Newly added. + Linux/AArch64: Works well. + Linux/PPC64: Newly added. + Linux/SuperH: Newly added. + FreeBSD/i386: Works well. + FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64). + Linux/Tilegx: Newly added (64-bit mode only). + +* General Build Instructions In general, this library can be built and installed with the following commands: - $ ./autogen.sh # Needed only for building from git. Depends on libtool. - $ ./configure - $ make - $ make install prefix=PREFIX + $ ./autogen.sh # Needed only for building from git. Depends on libtool. + $ ./configure + $ make + $ make install prefix=PREFIX -where `PREFIX` is the installation prefix. By default, a prefix of -`/usr/local` is used, such that `libunwind.a` is installed in -`/usr/local/lib` and `unwind.h` is installed in `/usr/local/include`. For -testing, you may want to use a prefix of `/usr/local` instead. +where PREFIX is the installation prefix. By default, a prefix of +/usr/local is used, such that libunwind.a is installed in +/usr/local/lib and unwind.h is installed in /usr/local/include. For +testing, you may want to use a prefix of /usr/local instead. -### Building with Intel compiler +* Building with Intel compiler -#### Version 8 and later +** Version 8 and later Starting with version 8, the preferred name for the IA-64 Intel -compiler is `icc` (same name as on x86). Thus, the configure-line +compiler is "icc" (same name as on x86). Thus, the configure-line should look like this: $ ./configure CC=icc CFLAGS="-g -O3 -ip" CXX=icc CCAS=gcc CCASFLAGS=-g \ - LDFLAGS="-L$PWD/src/.libs" + LDFLAGS="-L$PWD/src/.libs" -### Building on HP-UX +* Building on HP-UX For the time being, libunwind must be built with GCC on HP-UX. @@ -85,13 +55,14 @@ libunwind should be configured and installed on HP-UX like this: $ ./configure CFLAGS="-g -O2 -mlp64" CXXFLAGS="-g -O2 -mlp64" -Caveat: Unwinding of 32-bit (ILP32) binaries is not supported at the moment. +Caveat: Unwinding of 32-bit (ILP32) binaries is not supported + at the moment. -### Workaround for older versions of GCC +** Workaround for older versions of GCC -GCC v3.0 and GCC v3.2 ship with a bad version of `sys/types.h`. The +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`: +"configure": $ mkdir $top_dir/include/sys $ cp /usr/include/sys/types.h $top_dir/include/sys @@ -99,141 +70,138 @@ workaround is to issue the following commands before running GCC v3.3.2 or later have been fixed and do not require this workaround. -### Building for PowerPC64 / Linux +* Building for PowerPC64 / Linux For building for power64 you should use: - $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64" + $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64" If your power support altivec registers: - - $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec" + $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec" To check if your processor has support for vector registers (altivec): - cat /proc/cpuinfo | grep altivec - and should have something like this: - cpu : PPC970, altivec supported If libunwind seems to not work (backtracing failing), try to compile -it with `-O0`, without optimizations. There are some compiler problems +it with -O0, without optimizations. There are some compiler problems depending on the version of your gcc. -### Building on FreeBSD +* Building on FreeBSD + +General building instructions apply. To build and execute several tests, +you need libexecinfo library available in ports as devel/libexecinfo. -General building instructions apply. To build and execute several tests -on older versions of FreeBSD, you need libexecinfo library available in -ports as devel/libexecinfo. This port has been removed as of 2017 and is -indeed no longer needed. +Development of the port was done of FreeBSD 8.0-STABLE. The library +was build with the system compiler that is modified version of gcc 4.2.1, +as well as the gcc 4.4.3. -## Regression Testing +* Regression Testing After building the library, you can run a set of regression tests with: - $ make check + $ make check -### Expected results on IA-64 Linux +** 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) + 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. +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 +** Expected results on x86 Linux The following tests are expected to fail on x86 Linux: -* `test-ptrace` + test-ptrace -### Expected results on x86-64 Linux +** Expected results on x86-64 Linux The following tests are expected to fail on x86-64 Linux: -* `run-ptrace-misc` (see - and ) + run-ptrace-misc (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18748 + and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18749) -### Expected results on PARISC 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. +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) -* `Ltest-bt` (likewise) -* `Gtest-resume-sig` (`Gresume.c:my_rt_sigreturn()` is wrong somehow) -* `Ltest-resume-sig` (likewise) -* `Gtest-init` (likewise) -* `Ltest-init` (likewise) -* `Gtest-dyn1` (no dynamic unwind info support yet) -* `Ltest-dyn1` (no dynamic unwind info support yet) -* `test-setjmp` (`longjmp()` not implemented yet) -* `run-check-namespace` (toolchain doesn't support `HIDDEN` yet) + Gtest-bt (backtrace truncated at kill() due to lack of unwind-info) + Ltest-bt (likewise) + Gtest-resume-sig (Gresume.c:my_rt_sigreturn() is wrong somehow) + Ltest-resume-sig (likewise) + Gtest-init (likewise) + Ltest-init (likewise) + Gtest-dyn1 (no dynamic unwind info support yet) + Ltest-dyn1 (no dynamic unwind info support yet) + test-setjmp (longjmp() not implemented yet) + run-check-namespace (toolchain doesn't support HIDDEN yet) -### Expected results on HP-UX +** Expected results on HP-UX -`make check` is currently unsupported for HP-UX. You can try to run +"make check" is currently unsupported for HP-UX. You can try to run it, but most tests will fail (and some may fail to terminate). The only test programs that are known to work at this time are: -* `tests/bt` -* `tests/Gperf-simple` -* `tests/test-proc-info` -* `tests/test-static-link` -* `tests/Gtest-init` -* `tests/Ltest-init` -* `tests/Gtest-resume-sig` -* `tests/Ltest-resume-sig` - -### Expected results on PPC64 Linux + tests/bt + tests/Gperf-simple + tests/test-proc-info + tests/test-static-link + tests/Gtest-init + tests/Ltest-init + tests/Gtest-resume-sig + tests/Ltest-resume-sig -`make check` should run with no more than 10 out of 24 tests failed. +** Expected results on PPC64 Linux -### Expected results on Solaris x86-64 +"make check" should run with no more than 10 out of 24 tests failed. -`make check` is passing 27 out of 33 tests. The following six tests are consistently -failing: -* `Gtest-concurrent` -* `Ltest-concurrent` -* `Ltest-init-local-signal` -* `Lrs-race` -* `test-setjmp` -* `x64-unwind-badjmp-signal-frame` - -## Performance Testing +* Performance Testing This distribution includes a few simple performance tests which give some idea of the basic cost of various libunwind operations. After building the library, you can run these tests with the following commands: - $ cd tests - $ make perf + $ cd tests + $ make perf + +* Contacting the Developers + +Please direct all questions regarding this library to: + + libunwind-devel@nongnu.org + +You can do this by sending a mail to libunwind-request@nongnu.org with +a body of: + + subscribe libunwind-devel -## Contacting the Developers +or you can subscribe and manage your subscription via the +web-interface at: -Please direct all questions regarding this library to . + https://savannah.nongnu.org/mail/?group=libunwind -You can do this by sending an email to with -a body of "subscribe libunwind-devel", or you can subscribe and manage your -subscription via the web-interface at . +Or interact at the gihub page: -You can also interact on our GitHub page: . + https://github.com/libunwind/libunwind diff --git a/src/coreclr/src/pal/src/libunwind/autogen.sh b/src/coreclr/src/pal/src/libunwind/autogen.sh index b08bc831f6447f..aad9de6615c22c 100755 --- a/src/coreclr/src/pal/src/libunwind/autogen.sh +++ b/src/coreclr/src/pal/src/libunwind/autogen.sh @@ -1,6 +1,6 @@ #!/bin/sh -test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=`dirname "${BASH_SOURCE[0]}"` test -n "$srcdir" || srcdir=. ( cd "$srcdir" && diff --git a/src/coreclr/src/pal/src/libunwind/configure.ac b/src/coreclr/src/pal/src/libunwind/configure.ac index 226a10fb35047a..0c5125971f7c6c 100644 --- a/src/coreclr/src/pal/src/libunwind/configure.ac +++ b/src/coreclr/src/pal/src/libunwind/configure.ac @@ -1,5 +1,5 @@ define(pkg_major, 1) -define(pkg_minor, 5) +define(pkg_minor, 3) define(pkg_extra, -rc1) define(pkg_maintainer, libunwind-devel@nongnu.org) define(mkvers, $1.$2$3) @@ -70,7 +70,7 @@ PT_STEP, PT_SYSCALL], [], [], dnl Checks for library functions. AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \ - ttrace mincore pipe2) + ttrace mincore) AC_MSG_CHECKING([if building with AltiVec]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ @@ -147,10 +147,6 @@ AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[Disable tests build]),, [enable_tests=yes]) -AC_ARG_ENABLE(weak-backtrace, - AS_HELP_STRING([--disable-weak-backtrace],[Do not provide the weak 'backtrace' symbol.]),, - [enable_weak_backtrace=yes]) - AC_MSG_CHECKING([if we should build libunwind-setjmp]) AC_MSG_RESULT([$enable_setjmp]) @@ -179,17 +175,15 @@ AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32) AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64) AM_CONDITIONAL(ARCH_SH, test x$target_arch = xsh) AM_CONDITIONAL(ARCH_TILEGX, test x$target_arch = xtilegx) -AM_CONDITIONAL(ARCH_S390X, test x$target_arch = xs390x) AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null) AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null) AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null) AM_CONDITIONAL(OS_QNX, expr x$target_os : xnto-qnx >/dev/null) -AM_CONDITIONAL(OS_SOLARIS, expr x$target_os : xsolaris >/dev/null) AC_MSG_CHECKING([for ELF helper width]) case "${target_arch}" in (arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);; -(aarch64|ia64|ppc64|x86_64|s390x|tilegx) use_elf64=yes; AC_MSG_RESULT([64]);; +(aarch64|ia64|ppc64|x86_64|tilegx) use_elf64=yes; AC_MSG_RESULT([64]);; (mips) use_elfxx=yes; AC_MSG_RESULT([xx]);; *) AC_MSG_ERROR([Unknown ELF target: ${target_arch}]) esac @@ -306,23 +300,6 @@ fi AC_SUBST([LIBLZMA]) AM_CONDITIONAL(HAVE_LZMA, test x$enable_minidebuginfo = xyes) -LIBZ= -AC_MSG_CHECKING([whether to support ZLIB-compressed symbol tables]) -AC_ARG_ENABLE(zlibdebuginfo, -AS_HELP_STRING([--enable-zlibdebuginfo], [Enables support for ZLIB-compressed symbol tables]),, [enable_zlibdebuginfo=auto]) -AC_MSG_RESULT([$enable_zlibdebuginfo]) -if test x$enable_zlibdebuginfo != xno; then - AC_CHECK_LIB([z], [uncompress], - [LIBZ=-lz - AC_DEFINE([HAVE_ZLIB], [1], [Define if you have libz]) - enable_zlibdebuginfo=yes], - [if test x$enable_zlibdebuginfo = xyes; then - AC_MSG_FAILURE([libz not found]) - fi]) -fi -AC_SUBST([LIBZ]) -AM_CONDITIONAL(HAVE_ZLIB, test x$enable_zlibdebuginfo = xyes) - AC_MSG_CHECKING([whether to support UNW_CACHE_PER_THREAD]) AC_ARG_ENABLE([per-thread-cache], AS_HELP_STRING([--enable-per-thread-cache], [build with support for UNW_CACHE_PER_THREAD (which imposes a hight TLS memory usage) (default: disabled)])) @@ -344,14 +321,6 @@ if test x$GCC = xyes -a x$intel_compiler != xyes; then fi AC_MSG_RESULT([$intel_compiler]) -AC_MSG_CHECKING([if building on Solaris then define __EXTENSIONS__ macro]) -if $OS_SOLARIS; then - CFLAGS="${CFLAGS} -D__EXTENSIONS__" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - AC_MSG_CHECKING([for QCC compiler]) AS_CASE([$CC], [qcc*|QCC*], [qcc_compiler=yes], [qcc_compiler=no]) AC_MSG_RESULT([$qcc_compiler]) @@ -467,11 +436,6 @@ if test "x$enable_tests" = "xyes"; then AC_CONFIG_FILES(tests/Makefile tests/check-namespace.sh) fi -AM_CONDITIONAL([CONFIG_WEAK_BACKTRACE], [test "x$enable_weak_backtrace" = xyes]) -AM_COND_IF([CONFIG_WEAK_BACKTRACE], [ - AC_DEFINE([CONFIG_WEAK_BACKTRACE], [1], [Define if the weak 'backtrace' symbol is provided.]) -]) - AC_CONFIG_FILES(Makefile src/Makefile include/libunwind-common.h include/libunwind.h include/tdep/libunwind_i.h) diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h index 96002a1b9d2d23..e03750760c529e 100644 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h @@ -27,7 +27,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define dwarf_eh_h #include "dwarf.h" -#include "libunwind_i.h" /* This header file defines the format of a DWARF exception-header section (.eh_frame_hdr, pointed to by program-header diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf.h b/src/coreclr/src/pal/src/libunwind/include/dwarf.h index 764f6f20ac22ba..fab93c614518e3 100644 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf.h +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf.h @@ -419,7 +419,7 @@ extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t a unw_word_t ip); extern void dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg); -extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, +extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, unw_word_t *valp, int *is_register); extern int diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h index 2716afccb815b3..85812e151d7829 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h @@ -44,13 +44,9 @@ extern "C" { leaving some slack for future expansion. Changing this value will require recompiling all users of this library. Stack allocation is relatively cheap and unwind-state copying is relatively rare, so we - want to err on making it rather too big than too small. + want to err on making it rather too big than too small. */ - Calculation is regs used (64 + 34) * 2 + 40 (bytes of rest of - cursor) + padding -*/ - -#define UNW_TDEP_CURSOR_LEN 250 +#define UNW_TDEP_CURSOR_LEN 512 typedef uint64_t unw_word_t; typedef int64_t unw_sword_t; @@ -173,46 +169,15 @@ typedef struct unw_tdep_save_loc unw_tdep_save_loc_t; -/* On AArch64, we can directly use ucontext_t as the unwind context, - * however, the __reserved struct is quite large: tune it down to only - * the necessary used fields. */ - -struct unw_sigcontext - { - uint64_t fault_address; - uint64_t regs[31]; - uint64_t sp; - uint64_t pc; - uint64_t pstate; - uint8_t __reserved[(66 * 8)] __attribute__((__aligned__(16))); -}; - -typedef struct - { - unsigned long uc_flags; - struct ucontext *uc_link; - stack_t uc_stack; - __sigset_t uc_sigmask; - struct unw_sigcontext uc_mcontext; - } unw_tdep_context_t; - -typedef struct - { - uint32_t _ctx_magic; - uint32_t _ctx_size; - uint32_t fpsr; - uint32_t fpcr; - uint64_t vregs[64]; - } unw_fpsimd_context_t; - - +/* On AArch64, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; #include "libunwind-common.h" #include "libunwind-dynamic.h" #define unw_tdep_getcontext(uc) (({ \ unw_tdep_context_t *unw_ctx = (uc); \ - register uint64_t *unw_base __asm__ ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs; \ + register uint64_t *unw_base asm ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs; \ __asm__ __volatile__ ( \ "stp x0, x1, [%[base], #0]\n" \ "stp x2, x3, [%[base], #16]\n" \ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in index 9dbb415f50441e..8d96ddca2abc30 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in @@ -30,19 +30,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UNW_VERSION_CODE(maj,min) (((maj) << 16) | (min)) #define UNW_VERSION UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR) -#ifdef __sun -// On SmartOS, gcc fails with the following error: -// -// ../include/libunwind-common.h:43:41: error: expected identifier or '(' before numeric constant -// # define UNW_PREFIX UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_) -// ^ -// -// workaround is to undefine _U explicitly. -// see https://github.com/libunwind/libunwind/issues/118 for more details. -// -#undef _U -#endif - #define UNW_PASTE2(x,y) x##y #define UNW_PASTE(x,y) UNW_PASTE2(x,y) #define UNW_OBJ(fn) UNW_PASTE(UNW_PREFIX, fn) @@ -253,6 +240,7 @@ unw_save_loc_t; #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_handle_signal_frame UNW_OBJ(handle_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) @@ -285,6 +273,7 @@ extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *); extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t); 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_handle_signal_frame (unw_cursor_t *); extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *); extern const char *unw_strerror (int); extern int unw_backtrace (void **, int); diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h index ced34b2027af66..97c95e2463ac1f 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h @@ -98,7 +98,7 @@ typedef enum UNW_MIPS_R30, UNW_MIPS_R31, - UNW_MIPS_PC = 64, + UNW_MIPS_PC = 34, /* FIXME: Other registers! */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h deleted file mode 100644 index ebda40d57af9b6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h +++ /dev/null @@ -1,144 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -#ifndef LIBUNWIND_H -#define LIBUNWIND_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include -#include -#include - -#define UNW_TARGET s390x -#define UNW_TARGET_S390X 1 - -#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ - -/* This needs to be big enough to accommodate "struct cursor", while - leaving some slack for future expansion. Changing this value will - require recompiling all users of this library. Stack allocation is - relatively cheap and unwind-state copying is relatively rare, so we - want to err on making it rather too big than too small. */ -#define UNW_TDEP_CURSOR_LEN 384 - -typedef uint64_t unw_word_t; -typedef int64_t unw_sword_t; - -typedef double unw_tdep_fpreg_t; - -typedef enum - { - /* general purpose registers */ - UNW_S390X_R0, - UNW_S390X_R1, - UNW_S390X_R2, - UNW_S390X_R3, - UNW_S390X_R4, - UNW_S390X_R5, - UNW_S390X_R6, - UNW_S390X_R7, - UNW_S390X_R8, - UNW_S390X_R9, - UNW_S390X_R10, - UNW_S390X_R11, - UNW_S390X_R12, - UNW_S390X_R13, - UNW_S390X_R14, - UNW_S390X_R15, - - /* floating point registers */ - UNW_S390X_F0, - UNW_S390X_F1, - UNW_S390X_F2, - UNW_S390X_F3, - UNW_S390X_F4, - UNW_S390X_F5, - UNW_S390X_F6, - UNW_S390X_F7, - UNW_S390X_F8, - UNW_S390X_F9, - UNW_S390X_F10, - UNW_S390X_F11, - UNW_S390X_F12, - UNW_S390X_F13, - UNW_S390X_F14, - UNW_S390X_F15, - - /* PSW */ - UNW_S390X_IP, - - UNW_TDEP_LAST_REG = UNW_S390X_IP, - - /* TODO: access, vector registers */ - - /* frame info (read-only) */ - UNW_S390X_CFA, - - UNW_TDEP_IP = UNW_S390X_IP, - UNW_TDEP_SP = UNW_S390X_R15, - - /* TODO: placeholders */ - UNW_TDEP_EH = UNW_S390X_R0, - } -s390x_regnum_t; - -#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ - -typedef struct unw_tdep_save_loc - { - /* Additional target-dependent info on a save location. */ - char unused; - } -unw_tdep_save_loc_t; - -/* On s390x, we can directly use ucontext_t as the unwind context. */ -typedef ucontext_t unw_tdep_context_t; - -typedef struct - { - /* no s390x-specific auxiliary proc-info */ - char unused; - } -unw_tdep_proc_info_t; - -#include "libunwind-dynamic.h" -#include "libunwind-common.h" - -#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) -#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) - -extern int unw_tdep_getcontext (unw_tdep_context_t *); -extern int unw_tdep_is_fpreg (int); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* LIBUNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in index a13e7767325df1..7a56168c8b2723 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in @@ -25,8 +25,6 @@ # include "libunwind-x86_64.h" #elif defined __tilegx__ # include "libunwind-tilegx.h" -#elif defined __s390x__ -# include "libunwind-s390x.h" #else # error "Unsupported arch" #endif diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h index e0f4540144230e..0fcf32695e2bae 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h @@ -140,7 +140,6 @@ cmpxchg_ptr (void *addr, void *old, void *new) } # define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr) # define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value) -# define atomic_read(ptr) (AO_load(ptr)) /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */ # if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) # define HAVE_CMPXCHG @@ -165,14 +164,10 @@ cmpxchg_ptr (void *addr, void *old, void *new) } # define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1) # define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value) -# define atomic_read(ptr) (__atomic_load_n(ptr,__ATOMIC_RELAXED)) # define HAVE_CMPXCHG # define HAVE_FETCH_AND_ADD #endif - -#ifndef atomic_read #define atomic_read(ptr) (*(ptr)) -#endif #define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn)) #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn) @@ -368,3 +363,4 @@ static inline void invalidate_edi (struct elf_dyn_info *edi) #define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) #endif /* libunwind_i_h */ + diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h index 74b821f5c0d70a..8006d0b8dd4fe2 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h @@ -35,6 +35,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ #define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) +/* Return the size of an address, for DWARF purposes. */ +#define dwarf_addr_size(addr_space) ((addr_space)->addr_size) + /* Convert a pointer to a dwarf_cursor structure to a pointer to unw_cursor_t. */ #define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h index 0c0fd3cf47eb3b..3fe40c0c053195 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h @@ -247,14 +247,6 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) 0, c->as_arg); else if (c->as->abi == UNW_MIPS_ABI_O32) return read_s32 (c, DWARF_GET_LOC (loc), val); - else if (c->as->abi == UNW_MIPS_ABI_N32) { - if (tdep_big_endian(c->as)) - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc) + 4, val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - } else return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, 0, c->as_arg); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h deleted file mode 100644 index ca419bd52acdd3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64 - some consolidation is possible here */ - -#ifndef dwarf_config_h -#define dwarf_config_h - -/* derived from DWARF register mappings in Z ELF ABI */ -#define DWARF_NUM_PRESERVED_REGS 66 -#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 1 - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; - unw_word_t type; /* see S390X_LOC_TYPE_* macros. */ - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h deleted file mode 100644 index 509237525553a1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h +++ /dev/null @@ -1,35 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -#if defined __linux__ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#define JB_SP 9 // __gregs[9] -#define JB_RP 8 // __gregs[8] -#define JB_MASK_SAVED 18 // __mask_was_saved -#define JB_MASK 19 // __saved_mask - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h deleted file mode 100644 index 137a0b8a4f9282..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h +++ /dev/null @@ -1,262 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -#ifndef S390X_LIBUNWIND_I_H -#define S390X_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf64.h" -#include "mempool.h" -#include "dwarf.h" - -struct unw_addr_space - { - struct unw_accessors acc; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - - /* Format of sigcontext structure and address at which it is - stored: */ - enum - { - S390X_SCF_NONE = 0, /* no signal frame encountered */ - S390X_SCF_LINUX_SIGFRAME = 1, /* Linux struct sigcontext */ - S390X_SCF_LINUX_RT_SIGFRAME = 2, /* Linux ucontext_t */ - } - sigcontext_format; - unw_word_t sigcontext_addr; - unw_word_t sigcontext_sp; - unw_word_t sigcontext_pc; - int validate; - ucontext_t *uc; - }; - -static inline ucontext_t * -dwarf_get_uc(const struct dwarf_cursor *cursor) -{ - const struct cursor *c = (struct cursor *) cursor->as_arg; - return c->uc; -} - -#define DWARF_GET_LOC(l) ((l).val) -# define DWARF_LOC_TYPE_MEM (0 << 0) -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_LOC_TYPE_VAL (1 << 2) - -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) -# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) - -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) - -#else /* !UNW_LOCAL_ONLY */ - -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -#endif /* !UNW_LOCAL_ONLY */ - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - /* FPRs may be saved in GPRs */ - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, - 0, c->as_arg); - if (DWARF_IS_MEM_LOC (loc)) - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, - 0, c->as_arg); - assert(DWARF_IS_VAL_LOC (loc)); - *val = *(unw_fpreg_t*) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - assert(!DWARF_IS_VAL_LOC (loc)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - /* FPRs may be saved in GPRs */ - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, - 1, c->as_arg); - - assert(DWARF_IS_MEM_LOC (loc)); - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - if (DWARF_IS_MEM_LOC (loc)) - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - /* GPRs may be saved in FPRs */ - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*)val, - 0, c->as_arg); - assert(DWARF_IS_VAL_LOC (loc)); - *val = DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - assert(!DWARF_IS_VAL_LOC (loc)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - /* GPRs may be saved in FPRs */ - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*) &val, - 1, c->as_arg); - - assert(DWARF_IS_MEM_LOC (loc)); - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#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) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,rs) do {} while(0) -#define tdep_stash_frame(cs,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) -#define tdep_uc_addr UNW_OBJ(uc_addr) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) 1 - -extern int tdep_init_done; - -extern void tdep_init (void); -extern void tdep_init_mem_validate (void); -extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, - unw_dyn_info_t *di, unw_proc_info_t *pi, - int need_unwind_info, void *arg); -extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); - -#endif /* S390X_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h index b2e5332b059661..d57196676db20c 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h @@ -23,10 +23,9 @@ 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. */ -#if defined __linux__ || defined __sun +#if defined __linux__ -/* Use glibc's jump-buffer indices; NPTL peeks at SP: - https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/x86_64/jmpbuf-offsets.h;h=ea94a1f90554deecceaf995ca5ee485ae8bffab7;hb=HEAD */ +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ #define JB_SP 6 #define JB_RP 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h index 6b798c7115f3c9..283525c16a38d5 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h @@ -89,7 +89,6 @@ struct cursor X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */ X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */ X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */ - X86_64_SCF_SOLARIS_SIGFRAME, /* illumos/Solaris signal frame */ } sigcontext_format; unw_word_t sigcontext_addr; @@ -233,11 +232,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_big_endian(as) 0 -#ifdef HAVE_ATOMIC_OPS_H -extern AO_t tdep_init_done; -#else extern int tdep_init_done; -#endif extern void tdep_init (void); extern void tdep_init_mem_validate (void); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in index c47299640e8e66..af05a7fba24f99 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in @@ -25,8 +25,6 @@ # include "tdep-x86_64/libunwind_i.h" #elif defined __tilegx__ # include "tdep-tilegx/libunwind_i.h" -#elif defined __s390x__ -# include "tdep-s390x/libunwind_i.h" #else # error "Unsupported arch" #endif diff --git a/src/coreclr/src/pal/src/libunwind/libunwind-version.txt b/src/coreclr/src/pal/src/libunwind/libunwind-version.txt deleted file mode 100644 index e96a102894ad41..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/libunwind-version.txt +++ /dev/null @@ -1,2 +0,0 @@ -v1.5-rc2 -https://github.com/libunwind/libunwind/releases/tag/v1.5-rc2 diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index 386d8ba3260306..891eadd158fa51 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -14,6 +14,8 @@ add_definitions(-DPACKAGE_STRING="") add_definitions(-DPACKAGE_BUGREPORT="") add_definitions(-D_GNU_SOURCE) +# Ensure that the remote and local unwind code can reside in the same binary without name clashing +add_definitions("-Ddwarf_search_unwind_table_int=UNW_OBJ(dwarf_search_unwind_table_int)") # Disable warning due to incorrect format specifier in debugging printf via the Debug macro add_compile_options(-Wno-format -Wno-format-security) @@ -23,8 +25,6 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") else() add_compile_options(-Wno-unused-value) add_compile_options(-Wno-unused-result) - add_compile_options(-Wno-implicit-function-declaration) - add_compile_options(-Wno-incompatible-pointer-types) endif() if(CLR_CMAKE_HOST_ARCH_ARM) @@ -51,10 +51,6 @@ elseif(CLR_CMAKE_HOST_ARCH_ARM64) # Disable warning due to labs function called on unsigned argument add_compile_options(-Wno-absolute-value) endif() - # Issue https://github.com/libunwind/libunwind/issues/176 - if (CLR_CMAKE_HOST_ALPINE_LINUX) - add_definitions("-D__sigset_t=sigset_t") - endif() # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension add_definitions(-Dasm=__asm__) elseif(CLR_CMAKE_HOST_ARCH_I386) @@ -119,14 +115,6 @@ SET(libunwind_la_SOURCES_os_freebsd_local # Nothing ) -SET(libunwind_la_SOURCES_os_solaris - os-solaris.c -) - -SET(libunwind_la_SOURCES_os_solaris_local -# Nothing -) - if(CLR_CMAKE_HOST_LINUX) SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_linux}) SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_linux_local}) @@ -149,11 +137,6 @@ elseif(CLR_CMAKE_HOST_FREEBSD) SET(libunwind_la_SOURCES_arm_os arm/Gos-freebsd.c) SET(libunwind_la_SOURCES_arm_os_local arm/Los-freebsd.c) list(APPEND libunwind_coredump_la_SOURCES coredump/_UCD_access_reg_freebsd.c) -elseif(CLR_CMAKE_HOST_SUNOS) - SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_solaris}) - SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_solaris_local}) - SET(libunwind_la_SOURCES_x86_64_os x86_64/Gos-solaris.c) - SET(libunwind_la_SOURCES_x86_64_os_local x86_64/Los-solaris.c) endif() # List of arch-independent files needed by both local-only and generic diff --git a/src/coreclr/src/pal/src/libunwind/src/Makefile.am b/src/coreclr/src/pal/src/libunwind/src/Makefile.am index ff977446a7c2b8..a557d8d1f4fb31 100644 --- a/src/coreclr/src/pal/src/libunwind/src/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/src/Makefile.am @@ -68,7 +68,7 @@ libunwind_coredump_la_SOURCES = \ coredump/_UPT_resume.c libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ -version-info $(COREDUMP_SO_VERSION) -libunwind_coredump_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_coredump_la_LIBADD = $(LIBLZMA) noinst_HEADERS += coredump/_UCD_internal.h coredump/_UCD_lib.h ### libunwind-setjmp: @@ -154,8 +154,6 @@ libunwind_la_SOURCES_os_freebsd = os-freebsd.c libunwind_la_SOURCES_os_qnx = os-qnx.c -libunwind_la_SOURCES_os_solaris = os-solaris.c - libunwind_dwarf_common_la_SOURCES = dwarf/global.c libunwind_dwarf_local_la_SOURCES = \ @@ -183,9 +181,9 @@ noinst_HEADERS += elf32.h elf64.h elfxx.h libunwind_elf32_la_SOURCES = elf32.c libunwind_elf64_la_SOURCES = elf64.c libunwind_elfxx_la_SOURCES = elfxx.c -libunwind_elf32_la_LIBADD = $(LIBLZMA) $(LIBZ) -libunwind_elf64_la_LIBADD = $(LIBLZMA) $(LIBZ) -libunwind_elfxx_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_elf32_la_LIBADD = $(LIBLZMA) +libunwind_elf64_la_LIBADD = $(LIBLZMA) +libunwind_elfxx_la_LIBADD = $(LIBLZMA) noinst_LTLIBRARIES += $(LIBUNWIND_ELF) libunwind_la_LIBADD += $(LIBUNWIND_ELF) @@ -465,30 +463,6 @@ libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \ sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c -# The list of files that go both into libunwind and libunwind-s390x: -noinst_HEADERS += s390x/init.h s390x/unwind_i.h -libunwind_la_SOURCES_s390x_common = $(libunwind_la_SOURCES_common) \ - s390x/is_fpreg.c s390x/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ - $(libunwind_la_SOURCES_local) \ - s390x/Lapply_reg_state.c s390x/Lreg_states_iterate.c \ - s390x/Lcreate_addr_space.c s390x/Lget_save_loc.c s390x/Lglobal.c \ - s390x/Linit.c s390x/Linit_local.c s390x/Linit_remote.c \ - s390x/Lget_proc_info.c s390x/Lregs.c s390x/Lresume.c \ - s390x/Lis_signal_frame.c s390x/Lstep.c \ - s390x/getcontext.S s390x/setcontext.S - -# The list of files that go into libunwind-s390x: -libunwind_s390x_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ - $(libunwind_la_SOURCES_generic) \ - s390x/Gapply_reg_state.c s390x/Greg_states_iterate.c \ - s390x/Gcreate_addr_space.c s390x/Gget_save_loc.c s390x/Gglobal.c \ - s390x/Ginit.c s390x/Ginit_local.c s390x/Ginit_remote.c \ - s390x/Gget_proc_info.c s390x/Gregs.c s390x/Gresume.c \ - s390x/Gis_signal_frame.c s390x/Gstep.c - if REMOTE_ONLY install-exec-hook: # Nothing to do here.... @@ -540,12 +514,6 @@ if OS_FREEBSD libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c endif -if OS_SOLARIS - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_solaris) - libunwind_la_SOURCES_x86_64_os = x86_64/Gos-solaris.c - libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-solaris.c -endif - if OS_QNX libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_qnx) libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_qnx_local) @@ -694,19 +662,7 @@ if !REMOTE_ONLY libunwind_sh_la_LIBADD += libunwind.la -lc endif libunwind_setjmp_la_SOURCES += sh/siglongjmp.S -else -if ARCH_S390X - lib_LTLIBRARIES += libunwind-s390x.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_s390x) - libunwind_s390x_la_SOURCES = $(libunwind_s390x_la_SOURCES_s390x) - libunwind_s390x_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_s390x_la_LIBADD = libunwind-dwarf-generic.la - libunwind_s390x_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_s390x_la_LIBADD += libunwind.la -lc -endif -endif # ARCH_S390X endif # ARCH_SH endif # ARCH_PPC64 endif # ARCH_PPC32 @@ -732,7 +688,7 @@ endif libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \ $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION) libunwind_la_LIBADD += -lc $(LIBCRTS) -libunwind_la_LIBADD += $(LIBLZMA) $(LIBZ) +libunwind_la_LIBADD += $(LIBLZMA) AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. AM_CCASFLAGS = $(AM_CPPFLAGS) @@ -749,7 +705,6 @@ EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ $(libunwind_la_SOURCES_os_linux) \ $(libunwind_la_SOURCES_os_hpux) \ $(libunwind_la_SOURCES_os_qnx) \ - $(libunwind_la_SOURCES_os_solaris) \ $(libunwind_la_SOURCES_common) \ $(libunwind_la_SOURCES_local) \ $(libunwind_la_SOURCES_generic) \ diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c index 35389762f27ed4..9c4eae8298ee31 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c @@ -41,7 +41,7 @@ static struct unw_addr_space local_addr_space; unw_addr_space_t unw_local_addr_space = &local_addr_space; static inline void * -uc_addr (unw_tdep_context_t *uc, int reg) +uc_addr (ucontext_t *uc, int reg) { if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0) return &uc->uc_mcontext.regs[reg]; @@ -54,13 +54,20 @@ uc_addr (unw_tdep_context_t *uc, int reg) # ifdef UNW_LOCAL_ONLY HIDDEN void * -tdep_uc_addr (unw_tdep_context_t *uc, int reg) +tdep_uc_addr (ucontext_t *uc, int reg) { return uc_addr (uc, reg); } # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -71,13 +78,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } @@ -103,7 +104,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, void *arg) { unw_word_t *addr; - unw_tdep_context_t *uc = arg; + ucontext_t *uc = arg; if (unw_is_fpreg (reg)) goto badreg; @@ -132,7 +133,7 @@ static int access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, int write, void *arg) { - unw_tdep_context_t *uc = arg; + ucontext_t *uc = arg; unw_fpreg_t *addr; if (!unw_is_fpreg (reg)) diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c index 69d4ed3861db9b..cd60ca840f5085 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c @@ -59,7 +59,7 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) } int -unw_init_local2 (unw_cursor_t *cursor, unw_tdep_context_t *uc, int flag) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { if (!flag) { diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c index 2cc161360ef537..3d82739293e11a 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c @@ -71,7 +71,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - __asm__ __volatile__ ( + asm volatile ( "mov x4, %0\n" "mov x5, %1\n" "ldp x0, x1, [x4]\n" @@ -134,7 +134,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) sc->pc = uc->uc_mcontext.pc; sc->pstate = uc->uc_mcontext.pstate; - __asm__ __volatile__ ( + asm volatile ( "mov sp, %0\n" "ret %1\n" : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h index db7e29dd722e91..3d324c2b08bd54 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h @@ -59,6 +59,6 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, } while (0) #endif -#define GET_FPCTX(uc) ((unw_fpsimd_context_t *)(&uc->uc_mcontext.__reserved)) +#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved)) #endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c index d6573a65e0c7d9..e79903cd87d3fe 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c @@ -152,13 +152,12 @@ HIDDEN int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c) { #define READ_OP() *buf++ + assert(buf != NULL); + assert(len > 0); const uint8_t *end = buf + len; int ret; struct arm_exbuf_data edata; - assert(buf != NULL); - assert(len > 0); - while (buf < end) { uint8_t op = READ_OP (); diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c index 0bac0d72da6fe6..2720d063a2424f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c @@ -57,17 +57,18 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c index 3b9dfb33e60a7b..a8288628a6cd61 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c @@ -56,7 +56,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - __asm__ __volatile__ ( + asm __volatile__ ( "ldmia %0, {r4-r12, lr}\n" "mov sp, r12\n" "bx lr\n" @@ -90,7 +90,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) /* Set the SP and the PC in order to continue execution at the modified trampoline which restores the signal mask and the registers. */ - __asm__ __volatile__ ( + asm __volatile__ ( "mov sp, %0\n" "bx %1\n" : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c index 895e8a892afce0..516c9f4d1837d1 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c @@ -46,8 +46,7 @@ arm_exidx_step (struct cursor *c) c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; unw_word_t ip = c->dwarf.ip; if (c->dwarf.use_prev_instr) - /* The least bit denotes thumb/arm mode, clear it. */ - ip = (ip & ~(unw_word_t)0x1) - 1; + --ip; /* check dynamic info first --- it overrides everything else */ ret = unwi_find_dynamic_proc_info (c->dwarf.as, ip, &c->dwarf.pi, 1, @@ -107,20 +106,17 @@ unw_step (unw_cursor_t *cursor) else if (unlikely (ret == -UNW_ESTOPUNWIND)) return ret; - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } } #endif /* CONFIG_DEBUG_FRAME */ /* Next, try extbl-based unwinding. */ if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) { - Debug (13, "%s(ret=%d), trying extbl\n", - UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() failed " : "", - ret); ret = arm_exidx_step (c); if (ret > 0) return 1; @@ -138,12 +134,7 @@ unw_step (unw_cursor_t *cursor) { if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) { - Debug (13, "%s%s%s%s(ret=%d), trying frame-chain\n", - UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() " : "", - (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) && UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "and " : "", - UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) ? "arm_exidx_step() " : "", - (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) || UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "failed " : "", - ret); + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); ret = UNW_ESUCCESS; /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ unw_word_t instr, i; diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c index 930a1148e4f442..0e3a83bdc6ca39 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c @@ -129,26 +129,6 @@ _UCD_access_reg (unw_addr_space_t as, return -UNW_EINVAL; } } -#elif defined(UNW_TARGET_AARCH64) - if (regnum >= UNW_AARCH64_X0 && regnum < UNW_AARCH64_X30) { - *valp = ui->prstatus->pr_reg.x[regnum]; - } else { - switch (regnum) { - case UNW_AARCH64_SP: - *valp = ui->prstatus->pr_reg.sp; - break; - case UNW_AARCH64_X30: - *valp = ui->prstatus->pr_reg.lr; - break; - case UNW_AARCH64_PC: - *valp = ui->prstatus->pr_reg.elr; - break; - default: - Debug(0, "bad regnum:%d\n", regnum); - return -UNW_EINVAL; - } - } - #else #error Port me #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c index 43792f849b3d7a..208d8d27b6581f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c @@ -54,9 +54,6 @@ _UCD_access_reg (unw_addr_space_t as, #elif defined(UNW_TARGET_TILEGX) if (regnum > UNW_TILEGX_CFA) goto badreg; -#elif defined(UNW_TARGET_S390X) - if (regnum > UNW_S390X_R15) - goto badreg; #else #if defined(UNW_TARGET_MIPS) static const uint8_t remap_regs[] = diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c index 4c430efb27b53c..62f6ee05c793b1 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c @@ -259,13 +259,9 @@ _UCD_create(const char *filename) cur->p_flags ); if (cur->p_filesz < cur->p_memsz) - { - Debug(2, " partial"); - } + Debug(2, " partial"); if (cur->p_flags & PF_X) - { - Debug(2, " executable"); - } + Debug(2, " executable"); } Debug(2, "\n"); i++; @@ -342,10 +338,7 @@ int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const cha phdr->backing_filesize = (uoff_t)statbuf.st_size; if (phdr->p_flags != (PF_X | PF_R)) - { - Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", - phdr_no, phdr->p_flags); - } + Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", phdr_no, phdr->p_flags); if (phdr->backing_filesize > phdr->p_memsz) { diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c index 3a4c9b8213c6db..00096c48d0770c 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c @@ -36,10 +36,6 @@ elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t i unsigned long segbase, mapoff; int ret; - /* We're about to map an elf image. If there is an elf image currently mapped, - then make sure to unmap it. */ - invalidate_edi(&ui->edi); - /* Used to be tdep_get_elf_image() in ptrace unwinding code */ coredump_phdr_t *cphdr = _UCD_get_elf_image(ui, ip); if (!cphdr) diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c index 739ed0569b9e6f..0d11905566c30a 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c @@ -74,11 +74,6 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, #else -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static inline int get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, int *countp) diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c index 2af454332dd825..f63c3d220c6bde 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c @@ -60,8 +60,6 @@ static const uint8_t operands[256] = [DW_OP_const4s] = OPND1 (VAL32), [DW_OP_const8u] = OPND1 (VAL64), [DW_OP_const8s] = OPND1 (VAL64), - [DW_OP_constu] = OPND1 (ULEB128), - [DW_OP_consts] = OPND1 (SLEB128), [DW_OP_pick] = OPND1 (VAL8), [DW_OP_plus_uconst] = OPND1 (ULEB128), [DW_OP_skip] = OPND1 (VAL16), @@ -237,8 +235,8 @@ dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, } HIDDEN int -dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, - unw_word_t len, unw_word_t *valp, int *is_register) +dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, + unw_word_t *valp, int *is_register) { unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr; uint8_t opcode, operands_signature, u8; @@ -287,14 +285,10 @@ do { \ end_addr = *addr + len; *is_register = 0; - Debug (14, "len=%lu, pushing initial value=0x%lx\n", - (unsigned long) len, (unsigned long) stack_val); + Debug (14, "len=%lu, pushing cfa=0x%lx\n", + (unsigned long) len, (unsigned long) c->cfa); - /* The DWARF standard requires the current CFA to be pushed onto the stack */ - /* before evaluating DW_CFA_expression and DW_CFA_val_expression programs. */ - /* DW_CFA_def_cfa_expressions do not take an initial value, but we push on */ - /* a dummy value to keep this logic consistent. */ - push (stack_val); + push (c->cfa); /* push current CFA as required by DWARF spec */ while (*addr < end_addr) { diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c index 0cfb4d4faea051..509ceff47cbe38 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c @@ -34,10 +34,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf-eh.h" #include "libunwind_i.h" -#ifdef HAVE_ZLIB -#include -#endif /* HAVE_ZLIB */ - struct table_entry { int32_t start_ip_offset; @@ -50,17 +46,12 @@ struct table_entry #include "os-linux.h" #endif -#ifndef __clang__ static ALIAS(dwarf_search_unwind_table) int dwarf_search_unwind_table_int (unw_addr_space_t as, unw_word_t ip, unw_dyn_info_t *di, unw_proc_info_t *pi, int need_unwind_info, void *arg); -#else -#define dwarf_search_unwind_table_int dwarf_search_unwind_table -#endif - static int linear_search (unw_addr_space_t as, unw_word_t ip, unw_word_t eh_frame_start, unw_word_t eh_frame_end, @@ -127,48 +118,14 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) return 1; } - if (shdr->sh_flags & SHF_COMPRESSED) - { - unsigned long destSize; - Elf_W (Chdr) *chdr = (shdr->sh_offset + ei.image); -#ifdef HAVE_ZLIB - if (chdr->ch_type == ELFCOMPRESS_ZLIB) - { - *bufsize = destSize = chdr->ch_size; - GET_MEMORY(*buf, *bufsize); - ret = uncompress((unsigned char *)*buf, &destSize, - shdr->sh_offset + ei.image + sizeof(*chdr), - shdr->sh_size - sizeof(*chdr)); - if (ret != Z_OK) - { - Debug (2, "failed to decompress zlib .debug_frame, skipping\n"); - munmap(*buf, *bufsize); - munmap(ei.image, ei.size); - return 1; - } - - Debug (4, "read %zd->%zd bytes of .debug_frame from offset %zd\n", - shdr->sh_size, *bufsize, shdr->sh_offset); - } - else -#endif /* HAVE_ZLIB */ - { - Debug (2, "unknown compression type %d, skipping\n", - chdr->ch_type); - munmap(ei.image, ei.size); - return 1; - } - } - else - { - *bufsize = shdr->sh_size; - GET_MEMORY(*buf, *bufsize); + *bufsize = shdr->sh_size; + *buf = malloc (*bufsize); - memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); + memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); + + Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", + *bufsize, shdr->sh_offset); - Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", - *bufsize, shdr->sh_offset); - } munmap(ei.image, ei.size); return 0; } @@ -251,7 +208,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, if (!err) { - GET_MEMORY(fdesc, sizeof (struct unw_debug_frame_list)); + fdesc = malloc (sizeof (struct unw_debug_frame_list)); fdesc->start = start; fdesc->end = end; @@ -266,131 +223,66 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, return fdesc; } -static size_t -debug_frame_index_make (struct unw_debug_frame_list *fdesc) +struct debug_frame_tab + { + struct table_entry *tab; + uint32_t length; + uint32_t size; + }; + +static void +debug_frame_tab_append (struct debug_frame_tab *tab, + unw_word_t fde_offset, unw_word_t start_ip) { - unw_accessors_t *a = unw_get_accessors_int (unw_local_addr_space); - char *buf = fdesc->debug_frame; - size_t bufsize = fdesc->debug_frame_size; - unw_word_t addr = (unw_word_t) (uintptr_t) buf; - size_t count = 0; + unsigned int length = tab->length; - while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) + if (length == tab->size) { - unw_word_t item_start = addr, item_end = 0; - uint32_t u32val = 0; - uint64_t cie_id = 0; - uint64_t id_for_cie; - - dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); - - if (u32val == 0) - break; - - if (u32val != 0xffffffff) - { - uint32_t cie_id32 = 0; - - item_end = addr + u32val; - dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, NULL); - cie_id = cie_id32; - id_for_cie = 0xffffffff; - } - else - { - uint64_t u64val = 0; - - /* Extended length. */ - dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); - item_end = addr + u64val; - - dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); - id_for_cie = 0xffffffffffffffffull; - } - - /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ - - if (cie_id == id_for_cie) - { - ; - /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ - } - else - { - unw_word_t fde_addr = item_start; - unw_proc_info_t this_pi; - int err; - - /*Debug (1, "Found FDE at %.8x\n", item_start);*/ - - err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, - a, &fde_addr, - &this_pi, - (uintptr_t) buf, 0, 1, - NULL); - - if (!err) - { - Debug (15, "start_ip = %lx, end_ip = %lx\n", - (long) this_pi.start_ip, (long) this_pi.end_ip); - - if (fdesc->index) - { - struct table_entry *e = &fdesc->index[count]; - - e->fde_offset = item_start - (unw_word_t) (uintptr_t) buf; - e->start_ip_offset = this_pi.start_ip; - } + tab->size *= 2; + tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size); + } - count++; - } - /*else - Debug (1, "FDE parse failed\n");*/ - } + tab->tab[length].fde_offset = fde_offset; + tab->tab[length].start_ip_offset = start_ip; - addr = item_end; - } - return count; + tab->length = length + 1; } static void -debug_frame_index_sort (struct unw_debug_frame_list *fdesc) +debug_frame_tab_shrink (struct debug_frame_tab *tab) { - size_t i, j, k, n = fdesc->index_size / sizeof (*fdesc->index); - struct table_entry *a = fdesc->index; - struct table_entry t; - - /* Use a simple Shell sort as it relatively fast and - * does not require additional memory. */ - - for (k = n / 2; k > 0; k /= 2) + if (tab->size > tab->length) { - for (i = k; i < n; i++) - { - t = a[i]; - - for (j = i; j >= k; j -= k) - { - if (t.start_ip_offset >= a[j - k].start_ip_offset) - break; + tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->length); + tab->size = tab->length; + } +} - a[j] = a[j - k]; - } +static int +debug_frame_tab_compare (const void *a, const void *b) +{ + const struct table_entry *fa = a, *fb = b; - a[j] = t; - } - } + if (fa->start_ip_offset > fb->start_ip_offset) + return 1; + else if (fa->start_ip_offset < fb->start_ip_offset) + return -1; + else + return 0; } -int +HIDDEN int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, unw_word_t segbase, const char* obj_name, unw_word_t start, unw_word_t end) { - unw_dyn_info_t *di = di_debug; - struct unw_debug_frame_list *fdesc; + unw_dyn_info_t *di; + struct unw_debug_frame_list *fdesc = 0; + unw_accessors_t *a; + unw_word_t addr; Debug (15, "Trying to find .debug_frame for %s\n", obj_name); + di = di_debug; fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end); @@ -399,69 +291,130 @@ dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, Debug (15, "couldn't load .debug_frame\n"); return found; } - - Debug (15, "loaded .debug_frame\n"); - - if (fdesc->debug_frame_size == 0) - { - Debug (15, "zero-length .debug_frame\n"); - return found; - } - - /* Now create a binary-search table, if it does not already exist. */ - - if (!fdesc->index) + else { - /* Find all FDE entries in debug_frame, and make into a sorted - index. First determine an index element count. */ + char *buf; + size_t bufsize; + unw_word_t item_start, item_end = 0; + uint32_t u32val = 0; + uint64_t cie_id = 0; + struct debug_frame_tab tab; - size_t count = debug_frame_index_make (fdesc); + Debug (15, "loaded .debug_frame\n"); - if (!count) - { - Debug (15, "no CIE/FDE found in .debug_frame\n"); - return found; - } + buf = fdesc->debug_frame; + bufsize = fdesc->debug_frame_size; - fdesc->index_size = count * sizeof (*fdesc->index); - GET_MEMORY (fdesc->index, fdesc->index_size); + if (bufsize == 0) + { + Debug (15, "zero-length .debug_frame\n"); + return found; + } + /* Now create a binary-search table, if it does not already exist. */ if (!fdesc->index) - { - Debug (15, "couldn't allocate a frame index table\n"); - fdesc->index_size = 0; - return found; - } - - /* Then fill and sort the index. */ - - debug_frame_index_make (fdesc); - debug_frame_index_sort (fdesc); - - /*for (i = 0; i < count; i++) - { - const struct table_entry *e = &fdesc->index[i]; - - Debug (15, "ip %x, FDE offset %x\n", - e->start_ip_offset, e->fde_offset); - }*/ + { + addr = (unw_word_t) (uintptr_t) buf; + + a = unw_get_accessors_int (unw_local_addr_space); + + /* Find all FDE entries in debug_frame, and make into a sorted + index. */ + + tab.length = 0; + tab.size = 16; + tab.tab = calloc (tab.size, sizeof (struct table_entry)); + + while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) + { + uint64_t id_for_cie; + item_start = addr; + + dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); + + if (u32val == 0) + break; + else if (u32val != 0xffffffff) + { + uint32_t cie_id32 = 0; + item_end = addr + u32val; + dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, + NULL); + cie_id = cie_id32; + id_for_cie = 0xffffffff; + } + else + { + uint64_t u64val = 0; + /* Extended length. */ + dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); + item_end = addr + u64val; + + dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); + id_for_cie = 0xffffffffffffffffull; + } + + /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ + + if (cie_id == id_for_cie) + ; + /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ + else + { + unw_word_t fde_addr = item_start; + unw_proc_info_t this_pi; + int err; + + /*Debug (1, "Found FDE at %.8x\n", item_start);*/ + + err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, + a, &fde_addr, + &this_pi, + (uintptr_t) buf, 0, 1, + NULL); + if (err == 0) + { + Debug (15, "start_ip = %lx, end_ip = %lx\n", + (long) this_pi.start_ip, (long) this_pi.end_ip); + debug_frame_tab_append (&tab, + item_start - (unw_word_t) (uintptr_t) buf, + this_pi.start_ip); + } + /*else + Debug (1, "FDE parse failed\n");*/ + } + + addr = item_end; + } + + debug_frame_tab_shrink (&tab); + qsort (tab.tab, tab.length, sizeof (struct table_entry), + debug_frame_tab_compare); + /* for (i = 0; i < tab.length; i++) + { + fprintf (stderr, "ip %x, fde offset %x\n", + (int) tab.tab[i].start_ip_offset, + (int) tab.tab[i].fde_offset); + }*/ + fdesc->index = tab.tab; + fdesc->index_size = tab.length; + } + + di->format = UNW_INFO_FORMAT_TABLE; + di->start_ip = fdesc->start; + di->end_ip = fdesc->end; + di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; + di->u.ti.table_data = (unw_word_t *) fdesc; + di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); + di->u.ti.segbase = segbase; + + found = 1; + Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " + "gp=0x%lx, table_data=0x%lx\n", + (char *) (uintptr_t) di->u.ti.name_ptr, + (long) di->u.ti.segbase, (long) di->u.ti.table_len, + (long) di->gp, (long) di->u.ti.table_data); } - - di->format = UNW_INFO_FORMAT_TABLE; - di->start_ip = fdesc->start; - di->end_ip = fdesc->end; - di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; - di->u.ti.table_data = (unw_word_t *) fdesc; - di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); - di->u.ti.segbase = segbase; - - found = 1; - Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " - "gp=0x%lx, table_data=0x%lx\n", - (char *) (uintptr_t) di->u.ti.name_ptr, - (long) di->u.ti.segbase, (long) di->u.ti.table_len, - (long) di->gp, (long) di->u.ti.table_data); - return found; } @@ -572,10 +525,6 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) } else if (phdr->p_type == PT_GNU_EH_FRAME) p_eh_hdr = phdr; -#if defined __sun - else if (phdr->p_type == PT_SUNW_UNWIND) - p_eh_hdr = phdr; -#endif else if (phdr->p_type == PT_DYNAMIC) p_dynamic = phdr; } @@ -657,15 +606,11 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) /* If there is no search table or it has an unsupported encoding, fall back on linear search. */ if (hdr->table_enc == DW_EH_PE_omit) - { - Debug (4, "table `%s' lacks search table; doing linear search\n", - info->dlpi_name); - } + Debug (4, "table `%s' lacks search table; doing linear search\n", + info->dlpi_name); else - { - Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", - info->dlpi_name, hdr->table_enc); - } + Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", + info->dlpi_name, hdr->table_enc); eh_frame_end = max_load_addr; /* XXX can we do better? */ @@ -898,7 +843,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, endianness is the target one. */ as = unw_local_addr_space; table = fdesc->index; - table_len = fdesc->index_size; + table_len = fdesc->index_size * sizeof (struct table_entry); debug_frame_base = (uintptr_t) fdesc->debug_frame; #endif } diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c index f5f7ad06c3b671..6a2ad504078af2 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c @@ -80,9 +80,6 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, break; case PT_GNU_EH_FRAME: -#if defined __sun - case PT_SUNW_UNWIND: -#endif peh_hdr = phdr + i; break; diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c index 28fd73c6b0f7f7..7d255aeeaf3c92 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c @@ -440,15 +440,8 @@ fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip) continue, and it's important we get this right, as 'ip' could be right at the function entry and hence FDE edge, or at instruction that manipulates CFA (push/pop). */ - if (c->use_prev_instr) - { -#if defined(__arm__) - /* On arm, the least bit denotes thumb/arm mode, clear it. */ - ip &= ~(unw_word_t)0x1; -#endif - --ip; - } + --ip; memset (&c->pi, 0, sizeof (c->pi)); @@ -741,7 +734,7 @@ create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, } static inline int -eval_location_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_addr_space_t as, +eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, dwarf_loc_t *locp, void *arg) { @@ -753,7 +746,7 @@ eval_location_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_addr_space return ret; /* evaluate the expression: */ - if ((ret = dwarf_eval_expr (c, stack_val, &addr, len, &val, &is_register)) < 0) + if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0) return ret; if (is_register) @@ -811,10 +804,7 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) assert (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR); addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; - /* The dwarf standard doesn't specify an initial value to be pushed on */ - /* the stack before DW_CFA_def_cfa_expression evaluation. We push on a */ - /* dummy value (0) to keep the eval_location_expr function consistent. */ - if ((ret = eval_location_expr (c, 0, as, a, addr, &cfa_loc, arg)) < 0) + if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) return ret; /* the returned location better be a memory location... */ if (DWARF_IS_REG_LOC (cfa_loc)) @@ -841,30 +831,18 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) break; case DWARF_WHERE_REG: -#ifdef __s390x__ - /* GPRs can be saved in FPRs on s390x */ - if (unw_is_fpreg (dwarf_to_unw_regnum (rs->reg.val[i]))) - { - new_loc[i] = DWARF_FPREG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); - break; - } -#endif - new_loc[i] = new_loc[rs->reg.val[i]]; + new_loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); break; case DWARF_WHERE_EXPR: addr = rs->reg.val[i]; - /* The dwarf standard requires the current CFA to be pushed on the */ - /* stack before DW_CFA_expression evaluation. */ - if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) + if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) return ret; break; case DWARF_WHERE_VAL_EXPR: addr = rs->reg.val[i]; - /* The dwarf standard requires the current CFA to be pushed on the */ - /* stack before DW_CFA_val_expression evaluation. */ - if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) + if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) return ret; new_loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (new_loc[i])); break; @@ -946,6 +924,7 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) unsigned short index = -1; if (cache) { + put_rs_cache (c->as, cache, &saved_mask); if (rs) { index = rs - cache->buckets; @@ -953,7 +932,6 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) cache->links[c->prev_rs].hint = index + 1; c->prev_rs = index; } - put_rs_cache (c->as, cache, &saved_mask); } if (ret < 0) return ret; diff --git a/src/coreclr/src/pal/src/libunwind/src/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/elfxx.c index 2589a3d43b628b..b03dfcb734cdaa 100644 --- a/src/coreclr/src/pal/src/libunwind/src/elfxx.c +++ b/src/coreclr/src/pal/src/libunwind/src/elfxx.c @@ -28,7 +28,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#include #ifdef HAVE_LZMA #include diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c index 265455a68c82a1..461e4b93da65fb 100644 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c @@ -64,6 +64,13 @@ _Uhppa_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -74,13 +81,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c index 8601bb3ca885f3..b09a2ad57c7a72 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c @@ -68,7 +68,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, if (!_U_dyn_info_list_addr) return -UNW_ENOINFO; #endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c index 2e7c62e5e8623e..98d35012861cf6 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c @@ -49,7 +49,6 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, return -UNW_ENOINFO; #endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr (); for (di = list->first; di; di = di->next) if (ip >= di->start_ip && ip < di->end_ip) diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c index 0b77fa59523cd7..840d9007f4c1d7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c @@ -106,15 +106,7 @@ unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, ip = tdep_get_ip (c); #if !defined(__ia64__) if (c->dwarf.use_prev_instr) - { -#if defined(__arm__) - /* On arm, the least bit denotes thumb/arm mode, clear it. */ - ip &= ~(unw_word_t)0x1; -#endif - --ip; - } - - + --ip; #endif error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, tdep_get_as_arg (c)); diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c index b28151370cdccb..c7aa2bdcdcbf0d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c @@ -23,9 +23,9 @@ 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. */ -#if !defined(UNW_REMOTE_ONLY) && !defined(UNW_LOCAL_ONLY) -#define UNW_LOCAL_ONLY +#ifndef UNW_REMOTE_ONLY +#define UNW_LOCAL_ONLY #include #include #include @@ -75,9 +75,7 @@ unw_backtrace (void **buffer, int size) return n; } -#ifdef CONFIG_WEAK_BACKTRACE extern int backtrace (void **buffer, int size) WEAK ALIAS(unw_backtrace); -#endif #endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c index f2b01158a0ec7b..cbd93e1a11cff8 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c @@ -30,24 +30,21 @@ unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) { #if !UNW_TARGET_IA64 struct unw_debug_frame_list *w = as->debug_frames; +#endif - while (w) - { - struct unw_debug_frame_list *n = w->next; + /* clear dyn_info_list_addr cache: */ + as->dyn_info_list_addr = 0; +#if !UNW_TARGET_IA64 + for (; w; w = w->next) + { if (w->index) - munmap (w->index, w->index_size); - - munmap (w->debug_frame, w->debug_frame_size); - munmap (w, sizeof (*w)); - w = n; + free (w->index); + free (w->debug_frame); } as->debug_frames = NULL; #endif - /* clear dyn_info_list_addr cache: */ - as->dyn_info_list_addr = 0; - /* This lets us flush caches lazily. The implementation currently ignores the flush range arguments (lo-hi). This is OK because unw_flush_cache() is allowed to flush more than the requested diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c index 24e0d3b1536a24..493d03db662b94 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c @@ -58,15 +58,8 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order) as->big_endian = (byte_order == __BIG_ENDIAN); /* FIXME! There is no way to specify the ABI. */ -#if _MIPS_SIM == _ABIO32 as->abi = UNW_MIPS_ABI_O32; -#elif _MIPS_SIM == _ABIN32 - as->abi = UNW_MIPS_ABI_N32; -#elif _MIPS_SIM == _ABI64 - as->abi = UNW_MIPS_ABI_N64; -#else -# error Unsupported ABI -#endif + as->addr_size = 4; return as; #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c index 04c4326d45c691..7b84be87b917db 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c @@ -30,14 +30,11 @@ unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) struct cursor *c = (struct cursor *) cursor; int ret; + /* We can only unwind using Dwarf into on MIPS: return failure code + if it's not present. */ ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) { - /* Construct a dummy proc info if Dwarf failed */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 4; - return 0; - } + if (ret < 0) + return ret; *pi = c->dwarf.pi; return 0; diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c index bf7a8f5a8f4447..3df170c754934f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c @@ -69,6 +69,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -79,13 +86,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c index e967324d67d6e0..95194022d2be1f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c @@ -63,7 +63,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, case UNW_MIPS_R26: case UNW_MIPS_R27: case UNW_MIPS_R28: - + case UNW_MIPS_R29: case UNW_MIPS_R30: case UNW_MIPS_R31: loc = c->dwarf.loc[reg - UNW_MIPS_R0]; @@ -75,7 +75,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, loc = c->dwarf.loc[reg]; break; - case UNW_MIPS_R29: case UNW_MIPS_CFA: if (write) return -UNW_EREADONLYREG; diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c index 0235d523f03991..937136aef1f76c 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c @@ -110,96 +110,6 @@ mips_handle_signal_frame (unw_cursor_t *cursor) return 1; } - - -static inline -int is_valid_fp_val(unw_word_t cfa_val, unw_word_t fp_val) -{ - return fp_val > 0 && cfa_val > 0 && fp_val >cfa_val && (fp_val - cfa_val < 0x4000); -} - -static int _step_n64(struct cursor *c) -{ - #define FP_REG UNW_MIPS_R30 - #define SP_REG UNW_MIPS_R29 - #define RA_REG UNW_MIPS_R31 - - //TODO:handle plt entry - int ret; - unw_word_t current_fp_val = 0; - unw_word_t current_ra_val = 0; - unw_word_t current_sp_val = 0; - struct dwarf_loc up_fp_loc = DWARF_NULL_LOC; - struct dwarf_loc up_ra_loc = DWARF_NULL_LOC; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[SP_REG], ¤t_sp_val); - if (ret < 0) - { - Debug (2, "returning %d [SP=0x%lx]\n", ret, - DWARF_GET_LOC (c->dwarf.loc[FP_REG])); - return ret; - } - ret = dwarf_get (&c->dwarf, c->dwarf.loc[FP_REG], ¤t_fp_val); - if (ret < 0) - { - Debug (2, "returning %d [FP=0x%lx]\n", ret, - DWARF_GET_LOC (c->dwarf.loc[FP_REG])); - return ret; - } - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RA_REG], ¤t_ra_val); - if (ret < 0) - { - Debug (2, "returning %d [RA=0x%lx]\n", ret, - DWARF_GET_LOC (c->dwarf.loc[RA_REG])); - return ret; - } - - Debug(2, "BEGIN GUESSING WITH SP:%p FP:%p CFA:%p at %p, RA:%p\n", - current_sp_val, current_fp_val, c->dwarf.cfa, - c->dwarf.ip, current_ra_val - ); - - if (current_fp_val == current_sp_val) { - // Don't adjust FP - up_fp_loc = c->dwarf.loc[FP_REG]; - up_ra_loc = c->dwarf.loc[RA_REG]; - } else if (is_valid_fp_val(c->dwarf.cfa, current_fp_val)) { - /* Heuristic to determine incorrect guess. For FP to be a - valid frame it needs to be above current CFA, but don't - let it go more than a little. Note that we can't deduce - anything about new FP (fp1) since it may not be a frame - pointer in the frame above. Just check we get the value. */ - up_fp_loc = DWARF_MEM_LOC (c, current_fp_val+16); - up_ra_loc = DWARF_MEM_LOC (c, current_fp_val+24); - unw_word_t up_fp_val = 0; - ret = dwarf_get (&c->dwarf, up_fp_loc, &up_fp_val); - if (ret > 0 && is_valid_fp_val(current_fp_val, up_fp_val)) { - c->dwarf.loc[FP_REG] = up_fp_loc; - } - } - - if (DWARF_IS_NULL_LOC (up_fp_loc)) - { - ret = 0; - Debug (2, "NULL %%fp loc, returning %d\n", ret); - return ret; - } - - c->dwarf.loc[UNW_MIPS_PC] = c->dwarf.loc[RA_REG]; - c->dwarf.loc[RA_REG] = up_ra_loc; - c->dwarf.loc[SP_REG] = up_fp_loc; - c->dwarf.loc[FP_REG] = up_fp_loc; - c->dwarf.use_prev_instr = 1; - - if (c->dwarf.ip == current_ra_val && current_fp_val == current_sp_val) { - // Backtrace stopped: frame did not save the PC - c->dwarf.ip = 0; - } else { - c->dwarf.ip = current_ra_val; - } - return (c->dwarf.ip == 0) ? 0 : 1; -} - int unw_step (unw_cursor_t *cursor) { @@ -214,11 +124,9 @@ unw_step (unw_cursor_t *cursor) if (unlikely (ret == -UNW_ESTOPUNWIND)) return ret; -#if _MIPS_SIM == _ABI64 + /* Dwarf unwinding didn't work, stop. */ if (unlikely (ret < 0)) - { - return _step_n64(c); - } -#endif + return 0; + return (c->dwarf.ip == 0) ? 0 : 1; } diff --git a/src/coreclr/src/pal/src/libunwind/src/os-solaris.c b/src/coreclr/src/pal/src/libunwind/src/os-solaris.c deleted file mode 100644 index 3c140ef29c93e9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/os-solaris.c +++ /dev/null @@ -1,73 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 -#include - -#include "libunwind_i.h" -#include "os-linux.h" // using linux header for map_iterator implementation - -int -tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen) -{ - struct map_iterator mi; - int found = 0, rc; - unsigned long hi; - - if (maps_init (&mi, pid) < 0) - return -1; - - while (maps_next (&mi, segbase, &hi, mapoff)) - if (ip >= *segbase && ip < hi) - { - found = 1; - break; - } - - if (!found) - { - maps_close (&mi); - return -1; - } - if (path) - { - strncpy(path, mi.path, pathlen); - } - rc = elf_map_image (ei, mi.path); - maps_close (&mi); - return rc; -} - -#ifndef UNW_REMOTE_ONLY - -void -tdep_get_exe_image_path (char *path) -{ - strcpy(path, getexecname()); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c index 7b45455807c89c..ba302448a314b6 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c @@ -91,6 +91,9 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -101,13 +104,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c index 7bfb395a7923c0..4c88cd6e77ff0d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c @@ -95,6 +95,9 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -105,13 +108,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c index 37cd4ffe1c2f77..2b92462fa927f8 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c @@ -84,9 +84,6 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, #elif defined(__arm__) if ((unsigned) reg < UNW_ARM_F0 || (unsigned) reg > UNW_ARM_F7) return -UNW_EBADREG; -#elif defined(__aarch64__) - if ((unsigned) reg < UNW_AARCH64_V0 || (unsigned) reg > UNW_AARCH64_V31) - return -UNW_EBADREG; #else #error Fix me #endif @@ -102,8 +99,6 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); #elif defined(__arm__) memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); -#elif defined(__aarch64__) - memcpy(&fpreg.fp_q[reg], val, sizeof(unw_fpreg_t)); #else #error Fix me #endif @@ -116,8 +111,6 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); #elif defined(__arm__) memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t)); -#elif defined(__aarch64__) - memcpy(val, &fpreg.fp_q[reg], sizeof(unw_fpreg_t)); #else #error Fix me #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c index 16671d453e1f2a..cc5ed0441865ea 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c @@ -71,11 +71,6 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, #else -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static inline int get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, int *countp) diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c index 52be799980db30..c82d1c9887295b 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c @@ -632,40 +632,6 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] = [UNW_TILEGX_R54] = 0x1b0, [UNW_TILEGX_R55] = 0x1b8, [UNW_TILEGX_PC] = 0x1a0 -#elif defined(UNW_TARGET_S390X) - [UNW_S390X_R0] = 0x10, - [UNW_S390X_R1] = 0x18, - [UNW_S390X_R2] = 0x20, - [UNW_S390X_R3] = 0x28, - [UNW_S390X_R4] = 0x30, - [UNW_S390X_R5] = 0x38, - [UNW_S390X_R6] = 0x40, - [UNW_S390X_R7] = 0x48, - [UNW_S390X_R8] = 0x50, - [UNW_S390X_R9] = 0x58, - [UNW_S390X_R10] = 0x60, - [UNW_S390X_R11] = 0x68, - [UNW_S390X_R12] = 0x70, - [UNW_S390X_R13] = 0x78, - [UNW_S390X_R14] = 0x80, - [UNW_S390X_R15] = 0x88, - [UNW_S390X_F0] = 0xe0, - [UNW_S390X_F1] = 0xe8, - [UNW_S390X_F2] = 0xf0, - [UNW_S390X_F3] = 0xf8, - [UNW_S390X_F4] = 0x100, - [UNW_S390X_F5] = 0x108, - [UNW_S390X_F6] = 0x110, - [UNW_S390X_F7] = 0x118, - [UNW_S390X_F8] = 0x120, - [UNW_S390X_F9] = 0x128, - [UNW_S390X_F10] = 0x130, - [UNW_S390X_F11] = 0x138, - [UNW_S390X_F12] = 0x140, - [UNW_S390X_F13] = 0x148, - [UNW_S390X_F14] = 0x150, - [UNW_S390X_F15] = 0x150, - [UNW_S390X_IP] = 0x08 #else # error Fix me. #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c deleted file mode 100644 index d411454932bc4f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c +++ /dev/null @@ -1,62 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Copyright (C) 2012 Tommi Rantala - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 - -#include "unwind_i.h" - -#if defined(_BIG_ENDIAN) && !defined(__BIG_ENDIAN) -#define __BIG_ENDIAN _BIG_ENDIAN -#endif - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * s390x supports only big-endian. - */ - if (byte_order != 0 && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c deleted file mode 100644 index 50de1e423c2c9e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - - if (dwarf_make_proc_info (&c->dwarf) < 0) - { - /* On x86-64, some key routines such as _start() and _dl_start() - are missing DWARF unwind info. We don't want to fail in that - case, because those frames are uninteresting and just mark - the end of the frame-chain anyhow. */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 1; - return 0; - } - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c deleted file mode 100644 index dc462c966e5673..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c +++ /dev/null @@ -1,86 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - - switch (reg) - { - case UNW_S390X_R6: - case UNW_S390X_R7: - case UNW_S390X_R8: - case UNW_S390X_R9: - case UNW_S390X_R10: - case UNW_S390X_R11: - case UNW_S390X_R12: - case UNW_S390X_R13: - case UNW_S390X_R15: - case UNW_S390X_F8: - case UNW_S390X_F9: - case UNW_S390X_F10: - case UNW_S390X_F11: - case UNW_S390X_F12: - case UNW_S390X_F13: - case UNW_S390X_F14: - case UNW_S390X_F15: - loc = c->dwarf.loc[reg]; - break; - - default: - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c deleted file mode 100644 index e2abe89d30743a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c +++ /dev/null @@ -1,101 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "config.h" -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (s390x_lock); -HIDDEN int tdep_init_done; - -/* The API register numbers are exactly the same as the .eh_frame - registers, for now at least. */ -HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_NUM_PRESERVED_REGS] = - { - UNW_S390X_R0, - UNW_S390X_R1, - UNW_S390X_R2, - UNW_S390X_R3, - UNW_S390X_R4, - UNW_S390X_R5, - UNW_S390X_R6, - UNW_S390X_R7, - UNW_S390X_R8, - UNW_S390X_R9, - UNW_S390X_R10, - UNW_S390X_R11, - UNW_S390X_R12, - UNW_S390X_R13, - UNW_S390X_R14, - UNW_S390X_R15, - - UNW_S390X_F0, - UNW_S390X_F2, - UNW_S390X_F4, - UNW_S390X_F6, - UNW_S390X_F1, - UNW_S390X_F3, - UNW_S390X_F5, - UNW_S390X_F7, - UNW_S390X_F8, - UNW_S390X_F10, - UNW_S390X_F12, - UNW_S390X_F14, - UNW_S390X_F9, - UNW_S390X_F11, - UNW_S390X_F13, - UNW_S390X_F15, - }; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&s390x_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - - tdep_init_mem_validate (); - -#ifndef UNW_REMOTE_ONLY - s390x_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&s390x_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c deleted file mode 100644 index db01743c062763..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c +++ /dev/null @@ -1,365 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - if (reg >= UNW_S390X_R0 && reg <= UNW_S390X_R15) - return &uc->uc_mcontext.gregs[reg - UNW_S390X_R0]; - if (reg >= UNW_S390X_F0 && reg <= UNW_S390X_F15) - return &uc->uc_mcontext.fpregs.fprs[reg - UNW_S390X_F0]; - if (reg == UNW_S390X_IP) - return &uc->uc_mcontext.psw.addr; - - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); - return 0; -} - -#define PAGE_SIZE 4096 -#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) - -static int mem_validate_pipe[2] = {-1, -1}; - -static inline void -open_pipe (void) -{ - /* ignore errors for closing invalid fd's */ - close (mem_validate_pipe[0]); - close (mem_validate_pipe[1]); - - pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); -} - -ALWAYS_INLINE -static int -write_validate (void *addr) -{ - int ret = -1; - ssize_t bytes = 0; - - do - { - char buf; - bytes = 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 - { - /* use syscall insteadof write() so that ASAN does not complain */ - ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1); - } - while ( errno == EINTR ); - - 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 */ - size_t i; - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ - if (mincore (addr, len, mvec) != 0) - { - return -1; - } - - for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) - { - if (!(mvec[i] & 1)) 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, mvec)) == -1 && - errno == EAGAIN) {} - if (ret == 0 && (mvec[0] & 1)) - { - 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 -static unw_word_t last_good_addr[NLGA]; -static int lga_victim; - -static int -validate_mem (unw_word_t addr) -{ - int i, victim; - 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; - - for (i = 0; i < NLGA; i++) - { - if (last_good_addr[i] && (addr == last_good_addr[i])) - return 0; - } - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - - victim = lga_victim; - for (i = 0; i < NLGA; i++) { - if (!last_good_addr[victim]) { - last_good_addr[victim++] = addr; - return 0; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; - - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (unlikely (write)) - { - Debug (16, "mem[%016lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - /* validate address */ - const struct cursor *c = (const struct cursor *)arg; - if (likely (c != NULL) && unlikely (c->validate) - && unlikely (validate_mem (addr))) { - Debug (16, "mem[%016lx] -> invalid\n", addr); - return -1; - } - *val = *(unw_word_t *) addr; - Debug (16, "mem[%016lx] -> %lx\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = ((struct cursor *)arg)->uc; - - if (unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = ((struct cursor *)arg)->uc; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -s390x_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = s390x_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); - - memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); - lga_victim = 0; -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c deleted file mode 100644 index 5eaead0f840bb2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c +++ /dev/null @@ -1,81 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (unlikely (!tdep_init_done)) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = c; - c->uc = uc; - c->validate = 0; - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c deleted file mode 100644 index efd61d64d4b8f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c +++ /dev/null @@ -1,57 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - if (as == unw_local_addr_space) - { - c->dwarf.as_arg = c; - c->uc = as_arg; - } - else - { - c->dwarf.as_arg = as_arg; - c->uc = NULL; - } - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c deleted file mode 100644 index 7ed91e3ccfc027..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c +++ /dev/null @@ -1,77 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - Copyright (C) 2013 Linaro Limited - Copyright (C) 2017 IBM - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -/* The restorer stub will be a system call: - - rt_sigreturn: svc 173 (0x0aad) - - sigreturn: svc 119 (0x0a77) -*/ - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret, shift = 48; - - as = c->dwarf.as; - a = unw_get_accessors (as); - arg = c->dwarf.as_arg; - - /* Align the instruction pointer to 8 bytes so that we guarantee - an 8 byte read from it won't cross a page boundary. - Instructions on s390x are 2 byte aligned. */ - ip = c->dwarf.ip & ~7; - shift -= (c->dwarf.ip - ip) * 8; - - ret = (*a->access_mem) (as, ip, &w0, 0, arg); - if (ret < 0) - return ret; - - /* extract first 2 bytes of the next instruction */ - w0 = (w0 >> shift) & 0xffff; - - /* sigreturn */ - if (w0 == 0x0a77) - return 1; - - /* rt_sigreturn */ - if (w0 == 0x0aad) - return 2; - - return 0; - -#else - return -UNW_ENOINFO; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c deleted file mode 100644 index 1a48833d56e733..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c +++ /dev/null @@ -1,116 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_S390X_CFA: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - case UNW_S390X_R0: - case UNW_S390X_R1: - case UNW_S390X_R2: - case UNW_S390X_R3: - case UNW_S390X_R4: - case UNW_S390X_R5: - case UNW_S390X_R6: - case UNW_S390X_R7: - case UNW_S390X_R8: - case UNW_S390X_R9: - case UNW_S390X_R10: - case UNW_S390X_R11: - case UNW_S390X_R12: - case UNW_S390X_R13: - case UNW_S390X_R14: - case UNW_S390X_IP: - loc = c->dwarf.loc[reg]; - break; - - case UNW_S390X_R15: - if (write) - return -UNW_EREADONLYREG; - loc = c->dwarf.loc[reg]; - break; - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_S390X_F0: - case UNW_S390X_F1: - case UNW_S390X_F2: - case UNW_S390X_F3: - case UNW_S390X_F4: - case UNW_S390X_F5: - case UNW_S390X_F6: - case UNW_S390X_F7: - case UNW_S390X_F8: - case UNW_S390X_F9: - case UNW_S390X_F10: - case UNW_S390X_F11: - case UNW_S390X_F12: - case UNW_S390X_F13: - case UNW_S390X_F14: - case UNW_S390X_F15: - loc = c->dwarf.loc[reg]; - break; - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_putfp (&c->dwarf, loc, *valp); - else - return dwarf_getfp (&c->dwarf, loc, valp); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c deleted file mode 100644 index fd9d13027e2a85..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c +++ /dev/null @@ -1,160 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 - -#include "unwind_i.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - struct cursor *c = (struct cursor *) cursor; - ucontext_t uc = *c->uc; - ucontext_t *rt = NULL; - struct sigcontext *sc = NULL; - int i; - unw_word_t sp, ip; - uc.uc_mcontext.psw.addr = c->dwarf.ip; - - /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to - be missing DWARF unwind info. We don't want to fail in that - case, because the frame-chain still would let us do a backtrace - at least. */ - dwarf_make_proc_info (&c->dwarf); - - switch (c->sigcontext_format) - { - case S390X_SCF_NONE: - Debug (8, "resuming at ip=%llx via setcontext()\n", - (unsigned long long) c->dwarf.ip); - setcontext (&uc); - abort(); /* unreachable */ - case S390X_SCF_LINUX_SIGFRAME: - Debug (8, "resuming at ip=%llx via signal trampoline\n", - (unsigned long long) c->dwarf.ip); - sc = (struct sigcontext*)c->sigcontext_addr; - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) - sc->sregs->regs.gprs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) - sc->sregs->fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0].d; - sc->sregs->regs.psw.addr = uc.uc_mcontext.psw.addr; - - sp = c->sigcontext_sp; - ip = c->sigcontext_pc; - __asm__ __volatile__ ( - "lgr 15, %[sp]\n" - "br %[ip]\n" - : : [sp] "r" (sp), [ip] "r" (ip) - ); - abort(); /* unreachable */ - case S390X_SCF_LINUX_RT_SIGFRAME: - Debug (8, "resuming at ip=%llx via signal trampoline\n", - (unsigned long long) c->dwarf.ip); - rt = (ucontext_t*)c->sigcontext_addr; - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) - rt->uc_mcontext.gregs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) - rt->uc_mcontext.fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0]; - rt->uc_mcontext.psw.addr = uc.uc_mcontext.psw.addr; - - sp = c->sigcontext_sp; - ip = c->sigcontext_pc; - __asm__ __volatile__ ( - "lgr 15, %[sp]\n" - "br %[ip]\n" - : : [sp] "r" (sp), [ip] "r" (ip) - ); - abort(); /* unreachable */ - } - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -/* This routine is responsible for copying the register values in - cursor C and establishing them as the current machine state. */ - -static inline int -establish_machine_state (struct cursor *c) -{ - int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, - int write, void *); - int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, - int write, void *); - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - access_reg = as->acc.access_reg; - access_fpreg = as->acc.access_fpreg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - (*access_fpreg) (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - (*access_reg) (as, reg, &val, 1, arg); - } - } - - if (c->dwarf.args_size) - { - if (tdep_access_reg (c, UNW_S390X_R15, &val, 0) >= 0) - { - val += c->dwarf.args_size; - (*access_reg) (as, UNW_S390X_R15, &val, 1, arg); - } - } - return 0; -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if ((ret = establish_machine_state (c)) < 0) - return ret; - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c deleted file mode 100644 index 0b79580b256bc2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c +++ /dev/null @@ -1,146 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" -#include - -static int -s390x_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret, i; - unw_word_t sc_addr, sp, *gprs, *fprs, *psw; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &sp); - if (ret < 0) - return ret; - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = sp; - c->sigcontext_pc = c->dwarf.ip; - switch (c->sigcontext_format) - { - case S390X_SCF_LINUX_SIGFRAME: /* sigreturn */ - sc_addr = sp + 160; - gprs = ((struct sigcontext*)sc_addr)->sregs->regs.gprs; - fprs = (unw_word_t*)((struct sigcontext*)sc_addr)->sregs->fpregs.fprs; - psw = &((struct sigcontext*)sc_addr)->sregs->regs.psw.addr; - break; - case S390X_SCF_LINUX_RT_SIGFRAME: /* rt_sigreturn */ - sc_addr = sp + sizeof(siginfo_t) + 8 + 160; - gprs = ((ucontext_t*)sc_addr)->uc_mcontext.gregs; - fprs = (unw_word_t*)((ucontext_t*)sc_addr)->uc_mcontext.fpregs.fprs; - psw = &((ucontext_t*)sc_addr)->uc_mcontext.psw.addr; - break; - default: - return -UNW_EUNSPEC; - } - - c->sigcontext_addr = sc_addr; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) - c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &gprs[i-UNW_S390X_R0]); - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) - c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &fprs[i-UNW_S390X_F0]); - - c->dwarf.loc[UNW_S390X_IP] = DWARF_MEM_LOC (c, (unw_word_t) psw); - - /* Set SP/CFA and PC/IP. - Normally the default CFA on s390x is r15+160. We do not add that offset - here because dwarf_step will add the offset. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); - - c->dwarf.pi_valid = 0; - c->dwarf.use_prev_instr = 0; - - return 1; -} - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret = 0, val = c->validate, sig; - -#if CONSERVATIVE_CHECKS - c->validate = 1; -#endif - - Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", - c, c->dwarf.ip, c->dwarf.cfa); - - /* Try DWARF-based unwinding... */ - c->sigcontext_format = S390X_SCF_NONE; - ret = dwarf_step (&c->dwarf); - -#if CONSERVATIVE_CHECKS - c->validate = val; -#endif - - if (unlikely (ret == -UNW_ENOINFO)) - { - /* GCC doesn't currently emit debug information for signal - trampolines on s390x so we check for them explicitly. - - If there isn't debug information available we could also - try using the backchain (if available). - - Other platforms also detect PLT entries here. That's - tricky to do reliably on s390x so I've left it out for - now. */ - - /* Memory accesses here are quite likely to be unsafe. */ - c->validate = 1; - - /* Check if this is a signal frame. */ - sig = unw_is_signal_frame (cursor); - if (sig > 0) - { - c->sigcontext_format = sig; - ret = s390x_handle_signal_frame (cursor); - } - else - { - c->dwarf.ip = 0; - ret = 0; - } - - c->validate = val; - return ret; - } - - if (unlikely (ret > 0 && c->dwarf.ip == 0)) - return 0; - - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c deleted file mode 100644 index 8c43a67c0fff23..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c +++ /dev/null @@ -1,6 +0,0 @@ -#define UNW_LOCAL_ONLY -#include "config.h" -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S deleted file mode 100644 index d35a3cf3a953d6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S +++ /dev/null @@ -1,74 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 Google, Inc - Contributed by Paul Pluzhnikov - Copyright (C) 2010 Konstantin Belousov - Copyright (C) 2017 IBM - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -// int _Us390x_getcontext (unw_tdep_context_t *ucp) - - .global _Us390x_getcontext - .type _Us390x_getcontext, @function -_Us390x_getcontext: - .cfi_startproc - - // Save the minimal set of registers required to restore the - // context. Generally speaking this is just the preserved - // registers but we've also saved the parameter registers - // so that return values can be modified too. - - // save PSW address - // (not strictly needed but makes other code simpler) - stg %r14,0x30(%r2) - - // floating point parameters (not strictly needed) - std %f0,0x100(%r2) - std %f2,0x110(%r2) - std %f4,0x120(%r2) - std %f6,0x130(%r2) - - // floating point preserved registers - stfpc 0xf8(%r2) - std %f8,0x140(%r2) - std %f9,0x148(%r2) - std %f10,0x150(%r2) - std %f11,0x158(%r2) - std %f12,0x160(%r2) - std %f13,0x168(%r2) - std %f14,0x170(%r2) - std %f15,0x178(%r2) - - // preserved registers and parameters - lgr %r1,%r2 - lghi %r2,0 - stmg %r2,%r15,0x48(%r1) - - br %r14 - - .cfi_endproc - .size _Us390x_getcontext, . - _Us390x_getcontext - - // We do not need executable stack. - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/init.h b/src/coreclr/src/pal/src/libunwind/src/s390x/init.h deleted file mode 100644 index 86ced38f66ca55..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/init.h +++ /dev/null @@ -1,71 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret; - int i; - - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) { - c->dwarf.loc[i] = DWARF_REG_LOC(&c->dwarf, i); - } - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) { - c->dwarf.loc[i] = DWARF_FPREG_LOC(&c->dwarf, i); - } - /* IP isn't a real register, it is encoded in the PSW */ - c->dwarf.loc[UNW_S390X_IP] = DWARF_REG_LOC(&c->dwarf, UNW_S390X_IP); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); - if (ret < 0) - return ret; - - /* Normally the CFA offset on s390x is biased, however this is taken - into account by the CFA offset in dwarf_step, so here we just mark - make it equal to the stack pointer. */ - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_S390X_R15), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = S390X_SCF_NONE; - c->sigcontext_addr = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - c->dwarf.eh_valid_mask = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c deleted file mode 100644 index bc31f3e917011b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c +++ /dev/null @@ -1,36 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ - /* vector registers? */ - return regnum >= UNW_S390X_F0 && regnum <= UNW_S390X_F15; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c b/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c deleted file mode 100644 index 2421b37ebb0d35..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c +++ /dev/null @@ -1,57 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Contributed by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" - -static const char *regname[] = - { - [UNW_S390X_R0]="R0", - [UNW_S390X_R1]="R1", - [UNW_S390X_R2]="R2", - [UNW_S390X_R3]="R3", - [UNW_S390X_R4]="R4", - [UNW_S390X_R5]="R5", - [UNW_S390X_R6]="R6", - [UNW_S390X_R7]="R7", - [UNW_S390X_R8]="R8", - [UNW_S390X_R9]="R9", - [UNW_S390X_R10]="R10", - [UNW_S390X_R11]="R11", - [UNW_S390X_R12]="R12", - [UNW_S390X_R13]="R13", - [UNW_S390X_R14]="R14", - [UNW_S390X_R15]="R15", - - [UNW_S390X_IP]="IP" - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S deleted file mode 100644 index 6cf55688aa436f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S +++ /dev/null @@ -1,76 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 Google, Inc - Contributed by Paul Pluzhnikov - Copyright (C) 2010 Konstantin Belousov - Copyright (C) 2017 IBM - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -// int _Us390x_setcontext (const ucontext_t *ucp) - - .global _Us390x_setcontext - .type _Us390x_setcontext, @function -_Us390x_setcontext: - .cfi_startproc - - // Must only restore registers saved by getcontext, other fields - // in the ucontext_t might be uninitialised. - - // Stop this function being unwound. We are clobbering callee-save - // registers in this function so unwinding it is unsafe. - // Ideally we'd save callee-save registers, update the CFI for them - // and then switch to the new CFI once the context switch is - // complete. - .cfi_undefined %r14 - - // floating point parameters - ld %f0,0x100(%r2) - ld %f2,0x110(%r2) - ld %f4,0x120(%r2) - ld %f6,0x130(%r2) - - // floating point preserved registers - lfpc 0xf8(%r2) - ld %f8,0x140(%r2) - ld %f9,0x148(%r2) - ld %f10,0x150(%r2) - ld %f11,0x158(%r2) - ld %f12,0x160(%r2) - ld %f13,0x168(%r2) - ld %f14,0x170(%r2) - ld %f15,0x178(%r2) - - // preserved registers and parameters - lgr %r1,%r2 - lmg %r2,%r15,0x48(%r1) - - // restore PSW address - lg %r1,0x30(%r1) - br %r1 - - .cfi_endproc - .size _Us390x_setcontext, . - _Us390x_setcontext - - // We do not need executable stack. - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h deleted file mode 100644 index 6e4b99baaa8dac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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. */ - -#ifndef unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" -#include - -#define s390x_lock UNW_OBJ(lock) -#define s390x_local_resume UNW_OBJ(local_resume) -#define s390x_local_addr_space_init UNW_OBJ(local_addr_space_init) -#define setcontext UNW_ARCH_OBJ(setcontext) - -extern void s390x_local_addr_space_init (void); -extern int s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg); -extern int setcontext (const ucontext_t *ucp); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c index dd330ce9e19db6..0e286f6f0851cc 100644 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c @@ -31,12 +31,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "jmpbuf.h" #include "setjmp_i.h" -#if !defined(_NSIG) -# if defined(_SIG_MAXSIG) -# define _NSIG (_SIG_MAXSIG - 1) -# elif defined(NSIG) -# define _NSIG NSIG -# endif +#if !defined(_NSIG) && defined(_SIG_MAXSIG) +# define _NSIG (_SIG_MAXSIG - 1) #endif #if defined(__GLIBC__) @@ -96,7 +92,7 @@ siglongjmp (sigjmp_buf env, int val) if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) { /* sigmask was saved */ -#if defined(__linux__) || defined(__sun) +#if defined(__linux__) if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t)) /* signal mask doesn't fit into EH arguments and we can't put it on the stack without overwriting something diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c index 9fe96d2bd4d8eb..52988a721e9d70 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c @@ -58,6 +58,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -68,13 +75,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c index 45631306bcd814..99ddb36fb3e33f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c @@ -37,7 +37,7 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) #else /* !UNW_REMOTE_ONLY */ static int -unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) { struct cursor *c = (struct cursor *) cursor; diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c index 5590bafa61242b..a263c92718a0b4 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c @@ -55,7 +55,7 @@ sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - __asm__ __volatile__ ( + asm volatile ( "mov.l @%0+, r8\n" "mov.l @%0+, r9\n" "mov.l @%0+, r10\n" @@ -99,7 +99,7 @@ sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) /* Set the SP and the PC in order to continue execution at the modified trampoline which restores the signal mask and the registers. */ - __asm__ __volatile__ ( + asm __volatile__ ( "mov %0, r15\n" "lds %1, pr\n" "rts\n" diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c index 925e6413246bed..7564a558be4362 100644 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c @@ -64,6 +64,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -74,13 +81,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in index 9a65faf39e1255..1505c5d6f67d35 100644 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in @@ -7,5 +7,5 @@ Name: libunwind Description: libunwind base library Version: @VERSION@ Libs: -L${libdir} -lunwind -Libs.private: @LIBLZMA@ @LIBZ@ +Libs.private: @LIBLZMA@ Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c index 3cec74a216b1fa..f6b8dc27d49345 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c @@ -54,6 +54,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -64,13 +71,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c index 40568700e0e401..0057c62d648bf3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c @@ -44,7 +44,6 @@ unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; - case UNW_X86_64_RIP: loc = c->dwarf.loc[RIP]; break; default: break; diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c index 9a7b1957eb8d99..8d1fbb4b0a9910 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c @@ -30,11 +30,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf_i.h" HIDDEN define_lock (x86_64_lock); -#ifdef HAVE_ATOMIC_OPS_H - HIDDEN AO_t tdep_init_done; -#else - HIDDEN int tdep_init_done; -#endif +HIDDEN int tdep_init_done; /* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ @@ -81,17 +77,15 @@ HIDDEN void tdep_init (void) { intrmask_t saved_mask; - intrmask_t full_mask; - sigfillset (&full_mask); - SIGPROCMASK (SIG_SETMASK, &full_mask, &saved_mask); - mutex_lock (&x86_64_lock); + sigfillset (&unwi_full_mask); + + lock_acquire (&x86_64_lock, saved_mask); { - if (atomic_read(&tdep_init_done)) + if (tdep_init_done) /* another thread else beat us to it... */ goto out; - sigfillset (&unwi_full_mask); mi_init (); dwarf_init (); @@ -101,9 +95,8 @@ tdep_init (void) #ifndef UNW_REMOTE_ONLY x86_64_local_addr_space_init (); #endif - fetch_and_add1(&tdep_init_done); /* signal that we're initialized... */ + tdep_init_done = 1; /* signal that we're initialized... */ } out: - mutex_unlock(&x86_64_lock); - SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + lock_release (&x86_64_lock, saved_mask); } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c index fd8d418b1a5762..2a84a1eec75e73 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c @@ -49,6 +49,13 @@ static struct unw_addr_space local_addr_space; unw_addr_space_t unw_local_addr_space = &local_addr_space; +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -59,13 +66,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } @@ -74,44 +75,14 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, static int mem_validate_pipe[2] = {-1, -1}; -#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); - - 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]) -{ - pipe (pipefd); - set_pipe_flags(pipefd[0]); - set_pipe_flags(pipefd[1]); -} -#endif - 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]); + /* ignore errors for closing invalid fd's */ + close (mem_validate_pipe[0]); + close (mem_validate_pipe[1]); - do_pipe2 (mem_validate_pipe); + pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); } ALWAYS_INLINE @@ -160,14 +131,20 @@ static int msync_validate (void *addr, size_t len) static int mincore_validate (void *addr, size_t len) { unsigned char mvec[2]; /* Unaligned access may cross page boundary */ + size_t i; /* mincore could fail with EAGAIN but we conservatively return -1 instead of looping. */ - if (mincore (addr, len, (char *)mvec) != 0) + if (mincore (addr, len, mvec) != 0) { return -1; } + for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) + { + if (!(mvec[i] & 1)) return -1; + } + return write_validate (addr); } #endif @@ -186,9 +163,9 @@ tdep_init_mem_validate (void) unw_word_t addr = PAGE_START((unw_word_t)&present); unsigned char mvec[1]; int ret; - while ((ret = mincore ((void*)addr, PAGE_SIZE, (char *)mvec)) == -1 && + while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && errno == EAGAIN) {} - if (ret == 0) + if (ret == 0 && (mvec[0] & 1)) { Debug(1, "using mincore to validate memory\n"); mem_validate_func = mincore_validate; @@ -203,93 +180,13 @@ tdep_init_mem_validate (void) /* Cache of already validated addresses */ #define NLGA 4 -#if defined(HAVE___THREAD) && HAVE___THREAD -// thread-local variant -static __thread unw_word_t last_good_addr[NLGA]; -static __thread int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == last_good_addr[i]) - return 1; - } - return 0; -} - -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] == 0) { - last_good_addr[victim] = addr; - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; -} - -#elif HAVE_ATOMIC_OPS_H -// global, thread safe variant -static AO_T last_good_addr[NLGA]; -static AO_T lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == AO_load(&last_good_addr[i])) - return 1; - } - return 0; -} - -static void -cache_valid_mem(unw_word_t addr) -{ - int i, victim; - victim = AO_load(&lga_victim); - for (i = 0; i < NLGA; i++) { - if (AO_compare_and_swap(&last_good_addr[victim], 0, addr)) { - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - AO_store(&last_good_addr[victim], addr); - victim = (victim + 1) % NLGA; - AO_store(&lga_victim, victim); -} -#else -// disabled, no cache -static int -is_cached_valid_mem(unw_word_t addr UNUSED) -{ - return 0; -} - -static void -cache_valid_mem(unw_word_t addr UNUSED) -{ -} -#endif +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; static int validate_mem (unw_word_t addr) { + int i, victim; size_t len; if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) @@ -302,13 +199,28 @@ validate_mem (unw_word_t addr) if (addr == 0) return -1; - if (is_cached_valid_mem(addr)) - return 0; + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } if (mem_validate_func ((void *) addr, len) == -1) return -1; - cache_valid_mem(addr); + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; return 0; } @@ -422,6 +334,9 @@ x86_64_local_addr_space_init (void) local_addr_space.acc.resume = x86_64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; unw_flush_cache (&local_addr_space, 0, 0); + + memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); + lga_victim = 0; } #endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c index 12a9e3e4c96aa8..5eaead0f840bb2 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c @@ -43,7 +43,7 @@ unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_i { struct cursor *c = (struct cursor *) cursor; - if (unlikely (!atomic_read(&tdep_init_done))) + if (unlikely (!tdep_init_done)) tdep_init (); Debug (1, "(cursor=%p)\n", c); diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c index f411b233317823..efd61d64d4b8f2 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c @@ -36,7 +36,7 @@ unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) #else /* !UNW_LOCAL_ONLY */ struct cursor *c = (struct cursor *) cursor; - if (!atomic_read(&tdep_init_done)) + if (!tdep_init_done) tdep_init (); Debug (1, "(cursor=%p)\n", c); diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c deleted file mode 100644 index 75258d61d8755b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c +++ /dev/null @@ -1,133 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 "unwind_i.h" -#include "ucontext_i.h" - -#include - -struct sigframe { - uint64_t signo; - uint64_t sip; -}; - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - c->sigcontext_format = (c->dwarf.ip == (unw_word_t)-1) ? - X86_64_SCF_SOLARIS_SIGFRAME : X86_64_SCF_NONE; - - return (c->sigcontext_format); -} - -HIDDEN int -x86_64_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t ucontext = c->dwarf.cfa + sizeof (struct sigframe); - - if (c->sigcontext_format != X86_64_SCF_SOLARIS_SIGFRAME) - return -UNW_EBADFRAME; - - c->sigcontext_addr = c->dwarf.cfa; - - Debug(1, "signal frame cfa = %lx ucontext = %lx\n", - (uint64_t)c->dwarf.cfa, (uint64_t)ucontext); - - struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); - int ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); - - if (ret < 0) - { - Debug (2, "return %d\n", ret); - return ret; - } - - c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); - c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); - c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); - c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); - c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); - c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); - c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); - c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); - c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); - c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); - c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); - c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); - c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); - c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); - c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); - c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); - c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); - - c->dwarf.use_prev_instr = 1; - return 0; -} - -#ifndef UNW_REMOTE_ONLY -HIDDEN void * -x86_64_r_uc_addr (ucontext_t *uc, int reg) -{ - /* NOTE: common_init() in init.h inlines these for fast path access. */ - void *addr; - - switch (reg) - { - case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; - case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; - case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; - case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; - case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; - case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; - case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; - case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; - case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; - case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; - case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; - case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; - case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; - case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; - case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; - case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; - case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; - - default: - addr = NULL; - } - return addr; -} - -HIDDEN NORETURN void -x86_64_sigreturn (unw_cursor_t *cursor) -{ - abort(); -} - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c index 2a44f873e9edf4..2c7bc312e28c06 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c @@ -110,10 +110,10 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) } else if (f->frame_type == UNW_X86_64_FRAME_ALIGNED) { - Debug (4, " aligned frame, offset %i\n", f->cfa_reg_offset); + Debug (4, " aligned frame, offset %li\n", f->cfa_reg_offset); } + /* PLT and guessed RBP-walked frames are handled in unw_step(). */ - else { + else Debug (4, " unusual frame\n"); - } } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c index d4831197cb39ed..10498170ac76dc 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c @@ -104,7 +104,6 @@ unw_step (unw_cursor_t *cursor) via CALLQ. Try this for all non-signal trampoline code. */ - unw_word_t invalid_prev_rip = 0; unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa; struct dwarf_loc rbp_loc, rsp_loc, rip_loc; @@ -150,10 +149,7 @@ unw_step (unw_cursor_t *cursor) return ret; } - unw_word_t not_used; - invalid_prev_rip = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, prev_ip), ¬_used); - - if (!rbp && invalid_prev_rip == 0) + if (!rbp) { /* Looks like we may have reached the end of the call-chain. */ rbp_loc = DWARF_NULL_LOC; @@ -162,90 +158,38 @@ unw_step (unw_cursor_t *cursor) } else { - /* - * Check if previous RIP was invalid - * This could happen if a bad function pointer was - * followed and so the stack wasn't updated by the - * preamble - */ - int rip_fixup_success = 0; - if (invalid_prev_rip != 0) - { - Debug (2, "Previous RIP 0x%lx was invalid, attempting fixup\n", prev_ip); - unw_word_t rsp; - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RSP], &rsp); - - /*Test to see if what we think is the previous RIP is valid*/ - unw_word_t new_ip = 0; - if (dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) == 0) - { - Debug (2, "RSP 0x%lx looks valid\n", rsp); - if ((ret = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used)) == 0) - { - Debug (2, "new_ip 0x%lx looks valid\n", new_ip); - rip_fixup_success = 1; - c->frame_info.cfa_reg_offset = 8; - c->frame_info.cfa_reg_rsp = 1; - c->frame_info.rbp_cfa_offset = -1; - c->frame_info.rsp_cfa_offset = -1; - c->frame_info.frame_type = UNW_X86_64_FRAME_OTHER; - /* - * The call should have pushed RIP to the stack - * and since there was no preamble RSP hasn't been - * touched so RIP should be at RSP. - */ - c->dwarf.cfa += 8; - /* Optimised x64 binaries don't use RBP it seems? */ - rbp_loc = DWARF_LOC (rbp, 0); - rsp_loc = DWARF_LOC (rsp, 0); - rip_loc = DWARF_LOC (rsp, 0); - } - else - Debug (2, "new_ip 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used) != 0\n", new_ip); - } - else - Debug (2, "rsp 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) != 0\n", rsp); - } - /* - * If the previous rip we found on the stack didn't look valid fall back - * to the previous method for finding a valid stack frame - */ - if (!rip_fixup_success) + unw_word_t rbp1 = 0; + rbp_loc = DWARF_LOC(rbp, 0); + rsp_loc = DWARF_NULL_LOC; + rip_loc = DWARF_LOC (rbp + 8, 0); + ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); + Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", + (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), + rbp, c->dwarf.cfa, rbp1); + + /* Heuristic to determine incorrect guess. For RBP to be a + valid frame it needs to be above current CFA, but don't + let it go more than a little. Note that we can't deduce + anything about new RBP (rbp1) since it may not be a frame + pointer in the frame above. Just check we get the value. */ + if (ret < 0 + || rbp < c->dwarf.cfa + || (rbp - c->dwarf.cfa) > 0x4000) { - Debug (2, "RIP fixup didn't work, falling back\n"); - unw_word_t rbp1 = 0; - rbp_loc = DWARF_LOC(rbp, 0); - rsp_loc = DWARF_NULL_LOC; - rip_loc = DWARF_LOC (rbp + 8, 0); - ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); - Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", - (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), - rbp, c->dwarf.cfa, rbp1); - - /* Heuristic to determine incorrect guess. For RBP to be a - valid frame it needs to be above current CFA, but don't - let it go more than a little. Note that we can't deduce - anything about new RBP (rbp1) since it may not be a frame - pointer in the frame above. Just check we get the value. */ - if (ret < 0 - || rbp < c->dwarf.cfa - || (rbp - c->dwarf.cfa) > 0x4000) - { - rip_loc = DWARF_NULL_LOC; - rbp_loc = DWARF_NULL_LOC; - } - - c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; - c->frame_info.cfa_reg_rsp = 0; - c->frame_info.cfa_reg_offset = 16; - c->frame_info.rbp_cfa_offset = -16; - c->dwarf.cfa += 16; - + rip_loc = DWARF_NULL_LOC; + rbp_loc = DWARF_NULL_LOC; } + + c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; + c->frame_info.cfa_reg_rsp = 0; + c->frame_info.cfa_reg_offset = 16; + c->frame_info.rbp_cfa_offset = -16; + c->dwarf.cfa += 16; } + /* Mark all registers unsaved */ for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; + c->dwarf.loc[i] = DWARF_NULL_LOC; c->dwarf.loc[RBP] = rbp_loc; c->dwarf.loc[RSP] = rsp_loc; @@ -253,7 +197,7 @@ unw_step (unw_cursor_t *cursor) c->dwarf.use_prev_instr = 1; } - if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]) && invalid_prev_rip == 0) + if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) { ret = 0; Debug (2, "NULL %%rbp loc, returning %d\n", ret); @@ -270,13 +214,6 @@ unw_step (unw_cursor_t *cursor) Debug (2, "returning %d\n", ret); return ret; } -#if __sun - if (c->dwarf.ip == 0) - { - Debug (2, "returning 0\n"); - return ret; - } -#endif ret = 1; } else diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c index 824527f9beaac0..741227105e1843 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c @@ -540,7 +540,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) break; /* Record this address in stack trace. We skipped the first address. */ - buffer[depth++] = (void *) rip; + buffer[depth++] = (void *) (rip - d->use_prev_instr); } #if UNW_DEBUG diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c deleted file mode 100644 index be64b2c695b896..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-solaris.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S index e1450719b7da1a..7a8b5664bdaebd 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S @@ -57,13 +57,11 @@ _Ux86_64_getcontext: movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi) movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi) -#if defined __linux__ || defined __sun +#if defined __linux__ /* Save fp state (not needed, except for setcontext not restoring garbage). */ leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 -#ifdef UC_MCONTEXT_FPREGS_PTR movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi) -#endif // UC_MCONTEXT_FPREGS_PTR fnstenv (%r8) stmxcsr FPREGS_OFFSET_MXCSR(%r8) #elif defined __FreeBSD__ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S index 17e5ae12032aad..358217defbaf3b 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S @@ -37,13 +37,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ _Ux86_64_setcontext: -#if defined __linux__ || defined __sun +#if defined __linux__ /* restore fp state */ -#ifdef UC_MCONTEXT_FPREGS_PTR mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8 -#else // UC_MCONTEXT_FPREGS_PTR - leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 -#endif // UC_MCONTEXT_FPREGS_PTR fldenv (%r8) ldmxcsr FPREGS_OFFSET_MXCSR(%r8) #elif defined __FreeBSD__ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h index e886c948453ceb..aded941d053f76 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h @@ -78,25 +78,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UC_MCONTEXT_FPOWNED_FPU 0x20001 #define UC_MCONTEXT_FPFMT_XMM 0x10002 #define UC_MCONTEXT_MC_LEN_VAL 0x320 -#elif defined __sun -#define UC_MCONTEXT_GREGS_R8 0x78 -#define UC_MCONTEXT_GREGS_R9 0x70 -#define UC_MCONTEXT_GREGS_R10 0x68 -#define UC_MCONTEXT_GREGS_R11 0x60 -#define UC_MCONTEXT_GREGS_R12 0x58 -#define UC_MCONTEXT_GREGS_R13 0x50 -#define UC_MCONTEXT_GREGS_R14 0x48 -#define UC_MCONTEXT_GREGS_R15 0x40 -#define UC_MCONTEXT_GREGS_RDI 0x80 -#define UC_MCONTEXT_GREGS_RSI 0x88 -#define UC_MCONTEXT_GREGS_RBP 0x90 -#define UC_MCONTEXT_GREGS_RBX 0x98 -#define UC_MCONTEXT_GREGS_RDX 0xa0 -#define UC_MCONTEXT_GREGS_RAX 0xb0 -#define UC_MCONTEXT_GREGS_RCX 0xa8 -#define UC_MCONTEXT_GREGS_RSP 0xe0 -#define UC_MCONTEXT_GREGS_RIP 0xc8 -#define UC_MCONTEXT_FPREGS_MEM 0x120 -#define FPREGS_OFFSET_MXCSR 0x18 #endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c index d5b484478705c7..beae2a3ccd9b94 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c @@ -176,7 +176,7 @@ sighandler (int signal, void *siginfo UNUSED, void *context) { printf ("sighandler: got signal %d, sp=%p", signal, &sp); #if UNW_TARGET_IA64 -# if defined(__linux__) || defined __sun +# if defined(__linux__) printf (" @ %lx", uc->uc_mcontext.sc_ip); # else { @@ -189,13 +189,13 @@ sighandler (int signal, void *siginfo UNUSED, void *context) } # endif #elif UNW_TARGET_X86 -#if defined __linux__ || defined __sun +#if defined __linux__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); #endif #elif UNW_TARGET_X86_64 -#if defined __linux__ || defined __sun +#if defined __linux__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c index 48667bb9f4df30..fc1f646eac6d06 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c @@ -207,7 +207,7 @@ sighandler (int signal, void *siginfo UNUSED, void *context) printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); #endif #elif UNW_TARGET_X86_64 -#if defined __linux__ || defined __sun +#if defined __linux__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c deleted file mode 100644 index 209f87131248da..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include - -#include - -static int verbose; -static int nerrors; - -#define panic(args...) \ - do { printf (args); ++nerrors; } while (0) - -// Assembly routine which sets up the stack for the test then calls another one -// which clobbers the stack, and which in turn calls recover_register below -extern int64_t DW_CFA_expression_testcase(int64_t regnum, int64_t height); - -// recover_register is called by the assembly routines. It returns the value of -// a register at a specified height from the inner-most frame. The return value -// is propagated back through the assembly routines to the testcase. -extern int64_t recover_register(int64_t regnum, int64_t height) -{ - // Initialize cursor to current frame - int rc, i; - unw_cursor_t cursor; - unw_context_t context; - unw_getcontext(&context); - unw_init_local(&cursor, &context); - // Unwind frames until required height from inner-most frame (i.e. this one) - for (i = 0; i < height; ++i) - { - rc = unw_step(&cursor); - if (rc < 0) - panic("%s: unw_step failed on step %d with return code %d", __FUNCTION__, i, rc); - else if (rc == 0) - panic("%s: unw_step failed to reach the end of the stack", __FUNCTION__); - unw_word_t pc; - rc = unw_get_reg(&cursor, UNW_REG_IP, &pc); - if (rc < 0 || pc == 0) - panic("%s: unw_get_reg failed to locate the program counter", __FUNCTION__); - } - // We're now at the required height, extract register - uint64_t value; - if ((rc = unw_get_reg(&cursor, (unw_regnum_t) regnum, &value)) != 0) - panic("%s: unw_get_reg failed to retrieve register %lu", __FUNCTION__, regnum); - return value; -} - -int -main (int argc, char **argv) -{ - if (argc > 1) - verbose = 1; - - if (DW_CFA_expression_testcase(12, 1) != 0) - panic("r12 should be clobbered at height 1 (DW_CFA_expression_inner)"); - if (DW_CFA_expression_testcase(12, 2) != 111222333) - panic("r12 should be restored at height 2 (DW_CFA_expression_testcase)"); - - if (nerrors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - - if (verbose) - printf ("SUCCESS.\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c index e5127b90628fc3..1cacb9f028f151 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c @@ -35,8 +35,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#include -#include #define panic(args...) \ { fprintf (stderr, args); exit (-1); } diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c deleted file mode 100644 index 07e916e60a6acb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gx64-test-dwarf-expressions.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am index 61d1bf875a8c89..4b0b9db7d16996 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am @@ -37,11 +37,7 @@ if ARCH_PPC64 if USE_ALTIVEC noinst_PROGRAMS_arch += ppc64-test-altivec endif #USE_ALTIVEC -else #!ARCH_PPC64 -if ARCH_X86_64 - check_PROGRAMS_arch += Gx64-test-dwarf-expressions Lx64-test-dwarf-expressions x64-unwind-badjmp-signal-frame -endif #ARCH X86_64 -endif #!ARCH_PPC64 +endif #ARCH_PPC64 endif #!ARCH_IA64 check_PROGRAMS_cdep += Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ Gtest-init Ltest-init \ @@ -143,21 +139,12 @@ Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S \ flush-cache.h ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c - - -Gx64_test_dwarf_expressions_SOURCES = Gx64-test-dwarf-expressions.c \ - x64-test-dwarf-expressions.S -Lx64_test_dwarf_expressions_SOURCES = Lx64-test-dwarf-expressions.c \ - x64-test-dwarf-expressions.S - - Gtest_init_SOURCES = Gtest-init.cxx Ltest_init_SOURCES = Ltest-init.cxx Ltest_cxx_exceptions_SOURCES = Ltest-cxx-exceptions.cxx Ltest_init_local_signal_SOURCES = Ltest-init-local-signal.c Ltest-init-local-signal-lib.c -x64_unwind_badjmp_signal_frame_SOURCES = x64-unwind-badjmp-signal-frame.c Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S flush-cache.h Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S flush-cache.h test_static_link_SOURCES = test-static-link-loc.c test-static-link-gen.c @@ -204,7 +191,6 @@ Ltest_init_local_signal_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_bt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_concurrent_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -lpthread -x64_unwind_badjmp_signal_frame_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_dyn1_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_exc_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_init_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @BACKTRACELIB@ @@ -246,6 +232,3 @@ Lia64_test_readonly_LDADD = $(LIBUNWIND_local) ia64_test_dyn1_LDADD = $(LIBUNWIND) ia64_test_sig_LDADD = $(LIBUNWIND) ppc64_test_altivec_LDADD = $(LIBUNWIND) - -Gx64_test_dwarf_expressions_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Lx64_test_dwarf_expressions_LDADD = $(LIBUNWIND_local) diff --git a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in index f43bca263bc35e..6d0081732da007 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in +++ b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in @@ -85,11 +85,6 @@ filter_misc () { ignore _ftext ignore _gp fi - - if [ ${os} == "solaris2.11" ]; then - ignore _PROCEDURE_LINKAGE_TABLE_ - ignore _etext - fi } check_local_unw_abi () { @@ -126,7 +121,7 @@ check_local_unw_abi () { match _U_dyn_register match unw_backtrace - @CONFIG_WEAK_BACKTRACE_TRUE@match backtrace + match backtrace case ${plat} in arm) @@ -181,14 +176,6 @@ check_local_unw_abi () { 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}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - match _U${plat}_setcontext - ;; *) match _U${plat}_is_fpreg @@ -289,13 +276,6 @@ check_generic_unw_abi () { match _U${plat}_local_addr_space_init match ${plat}_lock ;; - s390x) - match _U${plat}_is_fpreg - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - ;; *) match _U${plat}_is_fpreg match _U${plat}_dwarf_search_unwind_table diff --git a/src/coreclr/src/pal/src/libunwind/tests/crasher.c b/src/coreclr/src/pal/src/libunwind/tests/crasher.c index bb99e339c26397..24c78054c9478a 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/crasher.c +++ b/src/coreclr/src/pal/src/libunwind/tests/crasher.c @@ -87,13 +87,8 @@ write_maps(char *fname) #endif #ifdef __GNUC__ -#ifndef __clang__ -// Gcc >= 8 became too good at inlining aliase c into b when using -O2 or -O3, -// so force -O1 in all cases, otherwise a frame will be missing in the tests. -#pragma GCC optimize "-O1" -#endif int c(int x) NOINLINE ALIAS(b); -#define compiler_barrier() __asm__ __volatile__ (""); +#define compiler_barrier() asm volatile(""); #else int c(int x); #define compiler_barrier() diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c index fb06a38effa10f..53498237c2fd0f 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c +++ b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c @@ -57,11 +57,7 @@ #include /* For SIGSEGV handler code */ -#if HAVE_EXECINFO_H -# include -#else - extern int backtrace (void **, int); -#endif +#include #include #include @@ -246,7 +242,7 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) void *array[50]; int size; size = backtrace(array, 50); -#if defined __linux__ && HAVE_EXECINFO_H +#ifdef __linux__ backtrace_symbols_fd(array, size, 2); #endif } diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S b/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S deleted file mode 100644 index f275625df10063..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S +++ /dev/null @@ -1,78 +0,0 @@ -.global DW_CFA_expression_testcase - -.extern recover_register - -.text - -# CFI expressions were added in DWARF v3 to allow compilers to specify memory -# locations or register values using DWARF programs. These programs are simple -# stack-based operations which allow the compiler to encode integer mathematics -# and other complex logic. CFI expressions are therefore more powerful than the -# conventional register + offset schemes. -# -# These tests capture a bug we have fixed in libunwind. CFI expression programs -# always start with the current CFA pushed onto the stack. This file contains a -# pair of routines which test CFI expression parsing. Specifically they test -# DW_CFA_expression logic, which uses DWARF expressions to compute the address -# where a non-volatile register was stored. -# -# Main calls DW_CFA_expression_testcase, which sets up known state in a -# non-volatile (caller-saved) register. We use r12 for this purpose. After this -# DW_CFA_expression_testcase then calls DW_CFA_expression_inner, which clobbers -# r12 after stashing its value on the stack. This routine contains a DWARF3 CFI -# expression to restore the value of r12 on unwind which should allow libunwind -# to recover clobbered state. DW_CFA_expression_inner calls recover_register to -# retrieve the cached register value. This function recovers the register value -# by using libunwind to unwind the stack through DW_CFA_expression_inner and up -# to the call site in DW_CFA_expression_testcase. If our expression is correct, -# libunwind will be able to restore r12 from the stack. -# -# BE CAREFUL WITH rdi, rsi, rax HERE! The arguments to recover_register are -# passed in via rdi, rsi and I just let them flow through unchanged. Similarly -# RAX flows back unchanged. Adding any function calls to the below may clobber -# these registers and cause this test to fail mysteriously. - - -######################################################## -# Test: Restoring a register using a DW_CFA_expression # -# which uses implicit CFA pushed onto stack. # -######################################################## - -.type DW_CFA_expression_testcase STT_FUNC -DW_CFA_expression_testcase: - .cfi_startproc - push %r12 - .cfi_adjust_cfa_offset 8 - # Move our sentinel (known) value into non-volatile (Callee-saved) r12 - mov $111222333, %r12 - .cfi_rel_offset %r12, 0 - call DW_CFA_expression_inner - pop %r12 - .cfi_restore %r12 - .cfi_adjust_cfa_offset -8 - ret - .cfi_endproc -.size DW_CFA_expression_testcase,.-DW_CFA_expression_testcase - -.type DW_CFA_expression_inner STT_FUNC -DW_CFA_expression_inner: - .cfi_startproc - push %r12 - .cfi_adjust_cfa_offset 8 - # !! IMPORTANT BIT !! The test is all about how we parse the following bytes. - # Now we use an expression to describe where our sentinel value is stored: - # DW_CFA_expression(0x10), r12(0x0c), Length(0x02), (preamble) - # DW_OP_lit16(0x40), DW_OP_minus(0x1c) (instructions) - # Parsing starts with the CFA on the stack, then pushes 16, then does a minus - # which is eqivalent to a=pop(), b=pop(), push(b-a), leaving us with a value - # of cfa-16 (cfa points at old rsp, cfa-8 is our rip, so we stored r12 at - # cfa-16). - xor %r12, %r12 # Trash r12 - .cfi_escape 0x10, 0x0c, 0x2, 0x40, 0x1c # DW_CFA_expression for recovery - call recover_register - pop %r12 - .cfi_restore %r12 - .cfi_adjust_cfa_offset -8 - ret - .cfi_endproc -.size DW_CFA_expression_inner,.-DW_CFA_expression_inner diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c b/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c deleted file mode 100644 index c7b7cf7335a8bd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c +++ /dev/null @@ -1,124 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2019 Brock York - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -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 -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_PTRACE_H -#include -#endif - -#define UNW_LOCAL_ONLY -#include - -/* - * unwind in the signal handler checking the backtrace is correct - * after a bad jump. - */ -void handle_sigsegv(int signal, siginfo_t *info, void *ucontext) -{ - /* - * 0 = success - * !0 = general failure - * 77 = test skipped - * 99 = complete failure - */ - int test_status = 0; - unw_cursor_t cursor; unw_context_t uc; - unw_word_t ip, sp, offset; - char name[1000]; - int found_signal_frame = 0; - int i = 0; - char *names[] = { - "", - "main", - }; - int names_count = sizeof(names) / sizeof(*names); - - unw_getcontext(&uc); - unw_init_local(&cursor, &uc); - - while (unw_step(&cursor) > 0 && !test_status) - { - if (unw_is_signal_frame(&cursor)) - { - found_signal_frame = 1; - } - if (found_signal_frame) - { - unw_get_reg(&cursor, UNW_REG_IP, &ip); - unw_get_reg(&cursor, UNW_REG_SP, &sp); - memset(name, 0, sizeof(char) * 1000); - unw_get_proc_name(&cursor, name, sizeof(char) * 1000, &offset); - printf("ip = %lx, sp = %lx offset = %lx name = %s\n", (long) ip, (long) sp, (long) offset, name); - if (i < names_count) - { - if (strcmp(names[i], name) != 0) - { - test_status = 1; - printf("frame %s doesn't match expected frame %s\n", name, names[i]); - } - else - { - i += 1; - } - } - } - } - - if (i != names_count) //Make sure we found all the frames! - { - printf("Failed to find all frames i:%d != names_count:%d\n", i, names_count); - test_status = 1; - } - - /*return test_status to test harness*/ - exit(test_status); -} - -void (*invalid_function)() = (void*)1; - -int main(int argc, char *argv[]) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handle_sigsegv; - sa.sa_flags = SA_SIGINFO; - sigaction(SIGSEGV, &sa, NULL); - - invalid_function(); - - /* - * 99 is the hard error exit status for automake tests: - * https://www.gnu.org/software/automake/manual/html_node/Scripts_002dbased-Testsuites.html#Scripts_002dbased-Testsuites - * If we dont end up in the signal handler something went horribly wrong. - */ - return 99; -}