diff --git a/src/native/external/libunwind-version.txt b/src/native/external/libunwind-version.txt index de52659948a1cb..f7064e3c6e1fe7 100644 --- a/src/native/external/libunwind-version.txt +++ b/src/native/external/libunwind-version.txt @@ -1,6 +1,8 @@ -v1.7.0 -https://github.com/libunwind/libunwind/commit/688caaf6ef9853cc26ad8bd1706804d48a0df0bc +v1.8.0 +https://github.com/libunwind/libunwind/commit/2c2566c79c4f9cb505e6a23e4ab884d856ef88fe -Apply https://github.com/libunwind/libunwind/pull/457 -Apply https://github.com/libunwind/libunwind/pull/455 -Apply https://github.com/libunwind/libunwind/pull/460 +Apply https://github.com/libunwind/libunwind/pull/700 +Apply https://github.com/libunwind/libunwind/pull/701 +Apply https://github.com/libunwind/libunwind/pull/703 +Apply https://github.com/libunwind/libunwind/pull/704 +Revert https://github.com/libunwind/libunwind/pull/503 # issue: https://github.com/libunwind/libunwind/issues/702 diff --git a/src/native/external/libunwind.cmake b/src/native/external/libunwind.cmake index c4456cf93b71ba..5dcca157e23ae6 100644 --- a/src/native/external/libunwind.cmake +++ b/src/native/external/libunwind.cmake @@ -45,6 +45,7 @@ set(libunwind_la_SOURCES_generic mi/Gget_fpreg.c mi/Gset_fpreg.c mi/Gset_caching_policy.c mi/Gset_cache_size.c + mi/Gaddress_validator.c ) set(libunwind_la_SOURCES_os_linux @@ -81,6 +82,8 @@ if(CLR_CMAKE_TARGET_LINUX) set(libunwind_la_SOURCES_x86_64_os_local x86_64/Los-linux.c) set(libunwind_la_SOURCES_arm_os arm/Gos-linux.c) set(libunwind_la_SOURCES_arm_os_local arm/Los-linux.c) + set(libunwind_la_SOURCES_aarch64_os aarch64/Gos-linux.c) + set(libunwind_la_SOURCES_aarch64_os_local aarch64/Los-linux.c) list(APPEND libunwind_coredump_la_SOURCES coredump/_UCD_access_reg_linux.c) elseif(CLR_CMAKE_TARGET_FREEBSD) set(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_freebsd}) @@ -92,6 +95,8 @@ elseif(CLR_CMAKE_TARGET_FREEBSD) set(libunwind_la_SOURCES_x86_64_os_local x86_64/Los-freebsd.c) set(libunwind_la_SOURCES_arm_os arm/Gos-freebsd.c) set(libunwind_la_SOURCES_arm_os_local arm/Los-freebsd.c) + set(libunwind_la_SOURCES_aarch64_os aarch64/Gos-freebsd.c) + set(libunwind_la_SOURCES_aarch64_os_local aarch64/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}) @@ -224,6 +229,7 @@ set(libunwind_la_SOURCES_aarch64_common # The list of files that go into libunwind: set(libunwind_la_SOURCES_aarch64 ${libunwind_la_SOURCES_aarch64_common} + ${libunwind_la_SOURCES_aarch64_os_local} ${libunwind_la_SOURCES_local} aarch64/Lapply_reg_state.c aarch64/Lreg_states_iterate.c aarch64/Lcreate_addr_space.c aarch64/Lget_proc_info.c @@ -234,8 +240,10 @@ set(libunwind_la_SOURCES_aarch64 aarch64/getcontext.S ) +# The list of files that go into libunwind-aarch64: set(libunwind_aarch64_la_SOURCES_aarch64 ${libunwind_la_SOURCES_aarch64_common} + ${libunwind_la_SOURCES_aarch64_os} ${libunwind_la_SOURCES_generic} aarch64/Gapply_reg_state.c aarch64/Greg_states_iterate.c aarch64/Gcreate_addr_space.c aarch64/Gget_proc_info.c diff --git a/src/native/external/libunwind/.github/workflows/CI-unix.yml b/src/native/external/libunwind/.github/workflows/CI-unix.yml index 7d48b48daec03c..cb237f5e4e80ee 100644 --- a/src/native/external/libunwind/.github/workflows/CI-unix.yml +++ b/src/native/external/libunwind/.github/workflows/CI-unix.yml @@ -1,5 +1,8 @@ name: CI - Unix +permissions: + contents: read + on: pull_request: paths: @@ -16,106 +19,118 @@ on: - master jobs: - build: - runs-on: ubuntu-latest - name: build-${{ join(matrix.*, ' ') }} + build-native: + runs-on: ubuntu-22.04 + name: build-${{ matrix.toolchain.compiler }}-${{ matrix.target.arch }}${{ matrix.optimization.CFLAGS }} + strategy: fail-fast: false matrix: - HOST: - - x86_64-linux-gnu - - x86-linux-gnu - - arm-linux-gnueabihf - - aarch64-linux-gnu - - mipsel-linux-gnu - - powerpc64-linux-gnu - OPT: - - O0 - - O3 + target: + - { arch: i686, triple: i686-pc-linux-gnu, CFLAGS: -m32 } + - { arch: x86_64, triple: x86_64-pc-linux-gnu, CFLAGS: } + toolchain: + - { compiler: gcc, CC: gcc-12, CXX: g++-12 } + - { compiler: clang, CC: clang-13, CXX: clang++-13 } + optimization: + - { CFLAGS: -O0 } + - { CFLAGS: -O3 } steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Setup + if: ${{ matrix.target.arch }} = 'i686' run: | - HOST=${{ matrix.HOST }} - if [ $HOST = 'x86-linux-gnu' ]; then - sudo apt-get update - sudo apt-get install -yqq -o=Dpkg::Use-Pty=0 g++-multilib - elif [ $HOST != 'x86_64-linux-gnu' ]; then - sudo apt-get update - sudo apt-get install -yqq -o=Dpkg::Use-Pty=0 g++-$HOST - fi + sudo apt update + sudo apt install -y g++-12-multilib + - name: Configure run: | set -x - HOST=${{ matrix.HOST }} - BUILD=x86_64-linux-gnu - if [ $HOST = 'x86-linux-gnu' ]; then - CFLAGS="-m32" - CXXFLAGS="-m32" - BUILD=x86-linux-gnu - fi - export CFLAGS="$CFLAGS -${{ matrix.OPT }}" - export CXXFLAGS="$CXXFLAGS -${{ matrix.OPT}}" autoreconf -i - ./configure --build=$BUILD --host=$HOST + ./configure --build=x86_64-pc-linux-gnu --host=${{ matrix.target.triple }} + env: + CC: ${{ matrix.toolchain.CC }} + CXX: ${{ matrix.toolchain.CXX }} + CFLAGS: "${{ matrix.target.CFLAGS }} ${{ matrix.optimization.CFLAGS }} -Wall -Wextra" + CXXFLAGS: "${{ matrix.target.CFLAGS }} ${{ matrix.optimization.CFLAGS }} -Wall -Wextra" + LDFLAGS: ${{ matrix.target.CFLAGS }} + + - name: Build + run: | make -j8 + - name: Test (native) - if: ${{ success() && (matrix.HOST == 'x86_64-linux-gnu' || matrix.HOST == 'x86-linux-gnu') }} + if: ${{ success() }} run: | set -x sudo bash -c 'echo core.%p.%p > /proc/sys/kernel/core_pattern' ulimit -c unlimited - make check -j32 + make check -j8 + - name: Show Logs if: ${{ failure() }} run: | cat tests/test-suite.log 2>/dev/null - build-cross-qemu: - runs-on: ubuntu-latest - name: build-cross-qemu-${{ matrix.config.target }} + build-cross: + runs-on: ubuntu-22.04 + name: build-cross-${{ matrix.config.target }} strategy: fail-fast: false matrix: config: - - {target: arm, toolchain: g++-arm-linux-gnueabi, host: arm-linux-gnueabi, qemu: arm } - - {target: armhf, toolchain: g++-arm-linux-gnueabihf, host: arm-linux-gnueabihf, qemu: arm } - - {target: aarch64, toolchain: g++-aarch64-linux-gnu, host: aarch64-linux-gnu, qemu: aarch64 } - - {target: riscv64, toolchain: g++-riscv64-linux-gnu, host: riscv64-linux-gnu, qemu: riscv64 } - - {target: ppc, toolchain: g++-powerpc-linux-gnu, host: powerpc-linux-gnu, qemu: ppc } - - {target: ppc64, toolchain: g++-powerpc64-linux-gnu, host: powerpc64-linux-gnu, qemu: ppc64 } - - {target: ppc64le, toolchain: g++-powerpc64le-linux-gnu, host: powerpc64le-linux-gnu, qemu: ppc64le } - - {target: s390x, toolchain: g++-s390x-linux-gnu, host: s390x-linux-gnu, qemu: s390x } - - {target: mips, toolchain: g++-mips-linux-gnu, host: mips-linux-gnu, qemu: mips } - - {target: mips64, toolchain: g++-mips64-linux-gnuabi64, host: mips64-linux-gnuabi64, qemu: mips64 } - - {target: mipsel, toolchain: g++-mipsel-linux-gnu, host: mipsel-linux-gnu, qemu: mipsel } - - {target: mips64el,toolchain: g++-mips64el-linux-gnuabi64, host: mips64el-linux-gnuabi64,qemu: mips64el } + - {target: arm, host: arm-linux-gnueabi, qemu: arm, gccver: 12 } + - {target: armhf, host: arm-linux-gnueabihf, qemu: arm, gccver: 12 } + - {target: aarch64, host: aarch64-linux-gnu, qemu: aarch64, gccver: 12 } + - {target: riscv64, host: riscv64-linux-gnu, qemu: riscv64, gccver: 12 } + - {target: ppc, host: powerpc-linux-gnu, qemu: ppc, gccver: 12 } + - {target: ppc64, host: powerpc64-linux-gnu, qemu: ppc64, gccver: 12 } + - {target: ppc64le, host: powerpc64le-linux-gnu, qemu: ppc64le, gccver: 12 } + - {target: s390x, host: s390x-linux-gnu, qemu: s390x, gccver: 12 } + - {target: mips, host: mips-linux-gnu, qemu: mips, gccver: 10 } + - {target: mips64, host: mips64-linux-gnuabi64, qemu: mips64, gccver: 10 } + - {target: mipsel, host: mipsel-linux-gnu, qemu: mipsel, gccver: 10 } + - {target: mips64el, host: mips64el-linux-gnuabi64, qemu: mips64el, gccver: 10 } steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install QEMU # this ensure install latest qemu on ubuntu, apt get version is old env: QEMU_SRC: "http://archive.ubuntu.com/ubuntu/pool/universe/q/qemu" - QEMU_VER: "qemu-user-static_4\\.2-.*_amd64.deb$" + QEMU_VER: "qemu-user-static_7\\.2.*_amd64.deb$" run: | DEB=`curl -s $QEMU_SRC/ | grep -o -E 'href="([^"#]+)"' | cut -d'"' -f2 | grep $QEMU_VER | tail -1` wget $QEMU_SRC/$DEB sudo dpkg -i $DEB - - name: Install ${{ matrix.config.toolchain }} + + - name: Install ${{ matrix.config.host }} Toolchain run: | sudo apt update - sudo apt install ${{ matrix.config.toolchain }} -y + sudo apt install g++-${{ matrix.config.gccver }}-${{ matrix.config.host }} -y + - name: Configure with ${{ matrix.config.cc }} run: | set -x autoreconf -i BUILD=x86_64-linux-gnu - ./configure --build=$BUILD --host=${{ matrix.config.host }} --with-testdriver=$(pwd)/scripts/qemu-test-driver + ./configure --build=$BUILD --host=${{ matrix.config.host }} --with-testdriver=$(pwd)/scripts/qemu-test-driver --enable-debug + env: + CC: ${{ matrix.config.host }}-gcc-${{ matrix.config.gccver }} + CXX: ${{ matrix.config.host }}-g++-${{ matrix.config.gccver }} + - name: Build run: | make -j8 + env: + CFLAGS: "-Wall -Wextra" + + - name: ABI Check + run: | + cd tests && ./run-check-namespace + - name: Test run: | set -x @@ -123,6 +138,9 @@ jobs: ulimit -c unlimited CROSS_LIB="/usr/${{ matrix.config.host }}" make -j8 check LOG_DRIVER_FLAGS="--qemu-arch ${{ matrix.config.qemu }}" LDFLAGS="-L$CROSS_LIB/lib -static" QEMU_LD_PREFIX="$CROSS_LIB" + env: + UNW_DEBUG_LEVEL: 4 + - name: Show Logs if: ${{ failure() }} run: | diff --git a/src/native/external/libunwind/.github/workflows/CI-win.yml b/src/native/external/libunwind/.github/workflows/CI-win.yml index 7effb9b23af871..6490816fe6a138 100644 --- a/src/native/external/libunwind/.github/workflows/CI-win.yml +++ b/src/native/external/libunwind/.github/workflows/CI-win.yml @@ -1,5 +1,8 @@ name: CI - Windows +permissions: + contents: read + on: pull_request: paths: @@ -27,7 +30,7 @@ jobs: - {toolchain: Visual Studio 17 2022, arch: x64, server: 2022, TARGET: aarch64-linux-gnu} - {toolchain: Visual Studio 17 2022, arch: x64, server: 2022, TARGET: x86_64-linux-gnu} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build shell: cmd env: diff --git a/src/native/external/libunwind/.github/workflows/codeql-analysis.yml b/src/native/external/libunwind/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000000..f6a6e0dfbcc457 --- /dev/null +++ b/src/native/external/libunwind/.github/workflows/codeql-analysis.yml @@ -0,0 +1,41 @@ +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + # Runs automatically on the twelfth of every month at 16:26 + - cron: '26 16 12 * *' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: security-extended,security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/src/native/external/libunwind/.github/workflows/groom-issues.yml b/src/native/external/libunwind/.github/workflows/groom-issues.yml new file mode 100644 index 00000000000000..ab7b5bfa58c7c5 --- /dev/null +++ b/src/native/external/libunwind/.github/workflows/groom-issues.yml @@ -0,0 +1,25 @@ +# Automate stale iossue tagging and closing +name: Close inactive issues +on: + schedule: + - cron: "30 1 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v5 + with: + stale-issue-label: "needs info" + days-before-issue-stale: -1 + days-before-issue-close: 60 + close-issue-message: > + Without additional information we're not able to resolve this issue. + Feel free to add more info or respond to any questions above and we + can reopen the case. Thanks for your contribution! + days-before-pr-stale: -1 + days-before-pr-close: -1 + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/src/native/external/libunwind/.gitignore b/src/native/external/libunwind/.gitignore index cd3e197c7a6f00..d59a6e3f73563a 100644 --- a/src/native/external/libunwind/.gitignore +++ b/src/native/external/libunwind/.gitignore @@ -15,6 +15,7 @@ Makefile.in INSTALL aclocal.m4 +m4/ autom4te.cache/ aux config.log @@ -77,7 +78,12 @@ tests/[GL]ia64-test-readonly tests/[GL]ia64-test-stack tests/ia64-test-dyn1 tests/ia64-test-sig +tests/ppc64-test-altivec +tests/ppc64-test-plt tests/[GL]x64-test-dwarf-expressions tests/x64-unwind-badjmp-signal-frame +tests/[GL]arm64-test-sve-signal +tests/aarch64-test-plt +tests/aarch64-test-frame-record tests/*.log tests/*.trs diff --git a/src/native/external/libunwind/CMakeLists.txt b/src/native/external/libunwind/CMakeLists.txt index 245a41bfbb35d5..8de31d12e32f59 100644 --- a/src/native/external/libunwind/CMakeLists.txt +++ b/src/native/external/libunwind/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 11) set(PKG_MAJOR "1") set(PKG_MINOR "6") -set(PKG_EXTRA "-rc1") +set(PKG_EXTRA "-rc2") set(PACKAGE_STRING "libunwind") set(PACKAGE_BUGREPORT "") diff --git a/src/native/external/libunwind/Makefile.am b/src/native/external/libunwind/Makefile.am index 0d5eee057fb381..0ce5128af4d1a7 100644 --- a/src/native/external/libunwind/Makefile.am +++ b/src/native/external/libunwind/Makefile.am @@ -8,7 +8,9 @@ endif BUILD_PTRACE if BUILD_COREDUMP include_HEADERS += include/libunwind-coredump.h endif BUILD_COREDUMP - +if BUILD_NTO +include_HEADERS += include/libunwind-nto.h +endif BUILD_NTO if ARCH_AARCH64 include_HEADERS += include/libunwind-aarch64.h endif @@ -24,9 +26,6 @@ endif if ARCH_MIPS include_HEADERS += include/libunwind-mips.h endif -if ARCH_TILEGX -include_HEADERS += include/libunwind-tilegx.h -endif if ARCH_X86 include_HEADERS += include/libunwind-x86.h endif @@ -85,8 +84,6 @@ noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \ include/tdep-hppa/jmpbuf.h include/tdep-hppa/dwarf-config.h \ include/tdep-mips/libunwind_i.h \ include/tdep-mips/jmpbuf.h include/tdep-mips/dwarf-config.h \ - include/tdep-tilegx/libunwind_i.h \ - include/tdep-tilegx/jmpbuf.h include/tdep-tilegx/dwarf-config.h \ include/tdep-x86/libunwind_i.h \ include/tdep-x86/jmpbuf.h include/tdep-x86/dwarf-config.h \ include/tdep-x86_64/libunwind_i.h \ diff --git a/src/native/external/libunwind/README b/src/native/external/libunwind/README index 26e1a9607c637c..62b0cdc84c7da1 100644 --- a/src/native/external/libunwind/README +++ b/src/native/external/libunwind/README @@ -16,7 +16,6 @@ This library supports several architecture/operating-system combinations: | Linux | SuperH | ✓ | | Linux | IA-64 | ✓ | | Linux | PARISC | Works well, but C library missing unwind-info | -| Linux | Tilegx | 64-bit mode only | | Linux | MIPS | ✓ | | Linux | RISC-V | 64-bit only | | Linux | LoongArch | 64-bit only | @@ -26,6 +25,8 @@ This library supports several architecture/operating-system combinations: | FreeBSD | AArch64 | ✓ | | FreeBSD | PPC32 | ✓ | | FreeBSD | PPC64 | ✓ | +| QNX | Aarch64 | ✓ | +| QNX | x86-64 | ✓ | | Solaris | x86-64 | ✓ | ## Libc Requirements @@ -52,7 +53,6 @@ such dependencies | riscv | p | p | | s390x | p | p | | sh | r | | -| tilegx | r | r | | x86 | p | r | | x86_64 | p | p | @@ -200,10 +200,5 @@ commands: ## Contacting the Developers -Please direct all questions regarding this library to . - -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 . - -You can also interact on our GitHub page: . +Please raise issues and pull requests through the GitHub repository: +. diff --git a/src/native/external/libunwind/SECURITY.md b/src/native/external/libunwind/SECURITY.md new file mode 100644 index 00000000000000..27b3483608d50f --- /dev/null +++ b/src/native/external/libunwind/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. + +Please disclose it at [security advisory](https://github.com/libunwind/libunwind/security/advisories/new). + +This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure. diff --git a/src/native/external/libunwind/configure.ac b/src/native/external/libunwind/configure.ac index d97e50652d349f..98d71e16887497 100644 --- a/src/native/external/libunwind/configure.ac +++ b/src/native/external/libunwind/configure.ac @@ -1,10 +1,10 @@ dnl Process this file with autoconf to produce a configure script. define(pkg_major, 1) -define(pkg_minor, 7) +define(pkg_minor, 8) define(pkg_extra, 0) -define(pkg_maintainer, libunwind-devel@nongnu.org) -define(mkvers, $1.$2$3) +define(pkg_maintainer, https://github.com/libunwind/libunwind) +define(mkvers, $1.$2.$3) AC_INIT([libunwind],[mkvers(pkg_major, pkg_minor, pkg_extra)],[pkg_maintainer]) AC_CONFIG_SRCDIR(src/mi/backtrace.c) @@ -26,31 +26,22 @@ LT_INIT AM_PROG_AS AM_PROG_CC_C_O -dnl Checks for libraries. -AC_CHECK_LIB(uca, __uc_get_grs) -OLD_LIBS=${LIBS} -AC_SEARCH_LIBS(dlopen, dl) -LIBS=${OLD_LIBS} -case "$ac_cv_search_dlopen" in - -l*) DLLIB=$ac_cv_search_dlopen;; - *) DLLIB="";; -esac +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_CHECK_SIZEOF(off_t) dnl Checks for header files. -AC_HEADER_STDC +AC_MSG_NOTICE([--- Checking for header files ---]) AC_CHECK_HEADERS(asm/ptrace_offsets.h asm/ptrace.h asm/vsyscall.h endian.h sys/endian.h \ sys/param.h execinfo.h ia64intrin.h sys/uc_access.h unistd.h signal.h \ sys/types.h sys/procfs.h sys/ptrace.h sys/syscall.h byteswap.h elf.h \ sys/elf.h link.h sys/link.h) -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_C_INLINE -AC_TYPE_SIZE_T -AC_CHECK_SIZEOF(off_t) - CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE" +AC_MSG_NOTICE([--- Checking for available types ---]) AC_CHECK_MEMBERS([struct dl_phdr_info.dlpi_subs],,,[#include ]) AC_CHECK_TYPES([struct elf_prstatus, struct prstatus, procfs_status, elf_fpregset_t], [], [], [$ac_includes_default @@ -59,21 +50,24 @@ AC_CHECK_TYPES([struct elf_prstatus, struct prstatus, procfs_status, elf_fpregse #endif ]) -AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA, PTRACE_SETREGSET, -PTRACE_TRACEME, PTRACE_CONT, PTRACE_SINGLESTEP, -PTRACE_SYSCALL, PT_IO, PT_GETREGS, -PT_GETFPREGS, PT_CONTINUE, PT_TRACE_ME, -PT_STEP, PT_SYSCALL], [], [], -[$ac_includes_default -#if HAVE_SYS_TYPES_H -#include -#endif -#include -]) +dnl Checks for libraries. +AC_MSG_NOTICE([--- Checking for libraries ---]) +save_LDFLAGS="$LDFLAGS" +save_LIBS="$LIBS" +LDFLAGS="${LDFLAGS} -nostdlib" +AC_SEARCH_LIBS([_Unwind_Resume], [gcc_s gcc], + [AS_IF([test "$ac_cv_search__Unwind_Resume" != "none required"], + [AC_SUBST([LIBCRTS], ["$ac_cv_search__Unwind_Resume"])])], + [], + [-lc] +) +LIBS="$save_LIBS" +LDFLAGS="$save_LDFLAGS" +AC_SEARCH_LIBS([__uc_get_grs], [uca]) dnl Checks for library functions. AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \ - ttrace mincore pipe2 sigaltstack) + ttrace mincore pipe2 sigaltstack execvpe) AC_MSG_CHECKING([if building with AltiVec]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ @@ -100,7 +94,6 @@ AC_DEFUN([SET_ARCH],[ [powerpc*],[$2=ppc$ppc_bits], [sh*],[$2=sh], [amd64],[$2=x86_64], - [tile*],[$2=tilegx], [riscv*],[$2=riscv], [loongarch64*],[$2=loongarch64], [$2=$1]) @@ -110,61 +103,212 @@ SET_ARCH([$build_cpu],[build_arch]) SET_ARCH([$host_cpu],[host_arch]) SET_ARCH([$target_cpu],[target_arch]) -# Check for Android -AC_MSG_CHECKING([for Android]) -android="no" -case "$host_os" in - *android*) - android="yes" - AC_MSG_RESULT([yes]) - ;; - *) - AC_MSG_RESULT([no]) - ;; -esac - -AC_ARG_ENABLE(coredump, - AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),, - [AS_CASE([$host_arch], [aarch64*|arm*|mips*|sh*|x86*|tile*|riscv*|loongarch64], [enable_coredump=yes], [enable_coredump=no])] +AC_MSG_CHECKING([if libunwind-coredump should be built]) +AC_ARG_ENABLE([coredump], + [AS_HELP_STRING([--enable-coredump], + [build libunwind-coredump library + @<:@default=autodetect@:>@])], + [], + [enable_coredump="check"] +) +AS_IF([test "$enable_coredump" = "check"], + [AS_CASE([$host_arch], + [aarch64*|arm*|mips*|sh*|x86*|riscv*|loongarch64], [enable_coredump=yes], + [enable_coredump=no])] ) - -AC_MSG_CHECKING([if we should build libunwind-coredump]) AC_MSG_RESULT([$enable_coredump]) +AM_CONDITIONAL(BUILD_COREDUMP, test x$enable_coredump = xyes) -AC_ARG_ENABLE(ptrace, - AS_HELP_STRING([--enable-ptrace],[building libunwind-ptrace library]),, - [AC_CHECK_HEADER([sys/ptrace.h], [enable_ptrace=yes], [enable_ptrace=no])] +AC_MSG_CHECKING([if libunwind-ptrace should be built]) +AC_ARG_ENABLE([ptrace], + [AS_HELP_STRING([--enable-ptrace], + [build libunwind-ptrace library + @<:@default=autodetect@:>@])], + [], + [enable_ptrace="check"] +) +AS_IF([test "$enable_ptrace" != "no"], + [AS_IF([test "$ac_cv_header_sys_ptrace_h" = "yes"], [enable_ptrace=yes], + [test "$enable_ptrace" != "check"], [AC_MSG_FAILURE([--enable-ptrace given but + ptrace not supported on target])], + [enable_ptrace="no"] + )] ) - -AC_MSG_CHECKING([if we should build libunwind-ptrace]) AC_MSG_RESULT([$enable_ptrace]) +AM_CONDITIONAL([BUILD_PTRACE], [test x$enable_ptrace = xyes]) +AM_COND_IF([BUILD_PTRACE], [ + AC_MSG_NOTICE([--- Checking for ptrace symbols ---]) + AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA, PTRACE_SETREGSET, + PTRACE_TRACEME, PTRACE_CONT, PTRACE_SINGLESTEP, + PTRACE_SYSCALL, PT_IO, PT_GETREGS, + PT_GETFPREGS, PT_CONTINUE, PT_TRACE_ME, + PT_STEP, PT_SYSCALL], + [], + [], + [$ac_includes_default + #if HAVE_SYS_TYPES_H + #include + #endif + #include + ]) +]) -AC_ARG_ENABLE(setjmp, - AS_HELP_STRING([--enable-setjmp],[building libunwind-setjmp library]),, - [AS_IF([test x$target_arch = x$host_arch], [enable_setjmp=yes], [enable_setjmp=no])] +AC_MSG_CHECKING([if libunwind-nto should be built]) +AC_ARG_ENABLE(nto, + [AS_HELP_STRING([--enable-nto], + [build libunwind-nto library + @<:@default=autodetect@:>@])], + [], + [enable_nto="check"] +) +AS_IF([test "$enable_nto" != "no"], + [AC_CHECK_HEADER([sys/neutrino.h], [enable_nto=yes], [enable_nto=no])] +) +AC_MSG_RESULT([$enable_nto]) +AM_CONDITIONAL([BUILD_NTO], [test x$enable_nto = xyes]) + +AC_MSG_CHECKING([if libunwind-setjmp should be built]) +AC_ARG_ENABLE([setjmp], + [AS_HELP_STRING([--enable-setjmp], + [build libunwind-setjmp library + @<:@default=autodetect@:>@])], + [], + [enable_setjmp=check] ) +AS_IF([test "$enable_setjmp" = check], + [AS_IF([test x$target_arch = x$host_arch], + [enable_setjmp=yes], + [enable_setjmp=no])] + [AS_IF([expr x$target_os : xnto-qnx >/dev/null], + [enable_setjmp=no])] +) +AC_MSG_RESULT([$enable_setjmp]) +AM_CONDITIONAL(BUILD_SETJMP, test x$enable_setjmp = xyes) -AC_ARG_ENABLE(documentation, - AS_HELP_STRING([--disable-documentation],[Disable generating the man pages]),, - [enable_documentation=yes]) +AC_MSG_CHECKING([if weak-backtrace is enabled]) +AC_ARG_ENABLE([weak-backtrace], + [AS_HELP_STRING([--disable-weak-backtrace], + [do not provide the weak 'backtrace' symbol + @<:@default=no@:>@])], + [], + [enable_weak_backtrace=yes] +) +AC_MSG_RESULT([$enable_weak_backtrace]) +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_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 unwind.h should be exported]) +AC_ARG_ENABLE([unwind-header], + [AS_HELP_STRING([--disable-unwind-header], + [do not export the 'unwind.h' header + @<:@default=no@:>@])], + [], + [enable_unwind_header=yes] +) +AC_MSG_RESULT([$enable_unwind_header]) +AM_CONDITIONAL(BUILD_UNWIND_HEADER, test "x$enable_unwind_header" = xyes) -AC_ARG_ENABLE(unwind-header, - AS_HELP_STRING([--disable-unwind-header],[Do not export the 'unwind.h' header]),, - [enable_unwind_header=yes]) +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 high TLS memory usage) + @<:@default=no@:>@])], + [], + [enable_per_thread_cache=no] +) +AC_MSG_RESULT([$enable_per_thread_cache]) +AS_IF([test x$enable_per_thread_cache = xyes], + [AC_DEFINE([HAVE___CACHE_PER_THREAD], 1, [Define to 1 if --enable-per-thread-cache])] +) -AC_MSG_CHECKING([if we should export unwind.h]) -AC_MSG_RESULT([$enable_unwind_header]) +AC_MSG_CHECKING([if testsuite should be built]) +AC_ARG_ENABLE([tests], + [AS_HELP_STRING([--disable-tests], + [disable building tests @<:@default=no@:>@])], + [], + [enable_tests=yes] +) +AC_MSG_RESULT([$enable_tests]) +AM_CONDITIONAL([CONFIG_TESTS], [test x$enable_tests = xyes]) +AM_COND_IF([CONFIG_TESTS], [ + old_LIBS="$LIBS" + AC_MSG_NOTICE([--- Checking for extra libraries linked to tests ---]) + AC_SEARCH_LIBS([dlopen], [dl], + [AS_IF([test "$ac_cv_search_dlopen" != "none required"], + [AC_SUBST([DLLIB], ["$ac_cv_search_dlopen"])])]) + AC_SEARCH_LIBS([pthread_create], [pthread], + [AS_IF([test "$ac_cv_search_pthread_create" != "none required"], + [AC_SUBST([PTHREADS_LIB],["$ac_cv_search_pthread_create"])])]) + AC_SEARCH_LIBS([backtrace], [execinfo], + [AS_IF([test "$ac_cv_search_backtrace" != "none required"], + [AC_SUBST([BACKTRACELIB],["$ac_cv_search_backtrace"])])]) + LIBS="$old_LIBS" + AC_CONFIG_FILES(tests/Makefile tests/check-namespace.sh) +]) +AC_ARG_WITH([testdriver], + [AS_HELP_STRING([--with-testdriver], + [use designated test driver instead of default LOG_DRIVER])], + [], + [with_testdriver=\$\(top_srcdir\)/config/test-driver]) +AC_SUBST([UNW_TESTDRIVER], $with_testdriver) -AC_MSG_CHECKING([if we should build libunwind-setjmp]) -AC_MSG_RESULT([$enable_setjmp]) + +AC_MSG_CHECKING([if debug support should be built]) +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [enable debug support (slows down execution) + @<:@default=no@:>@])], + [], + [enable_debug=no] +) +AC_MSG_RESULT([$enable_debug]) +AS_IF([test x$enable_debug = xyes], + [CPPFLAGS="${CPPFLAGS} -DDEBUG"], + [CPPFLAGS="${CPPFLAGS} -DNDEBUG"] +) + +AC_MSG_CHECKING([if C++ exception support should be built]) +AC_ARG_ENABLE([cxx_exceptions], + [AS_HELP_STRING([--enable-cxx-exceptions], + [use libunwind to handle C++ exceptions + @<:@default=autodetect@:>@])], + [], + [enable_cxx_exceptions=check] +) +AS_IF([test $enable_cxx_exceptions = check], + [AS_CASE([$target_arch], + [aarch64*|arm*|mips*|x86*|s390x*|loongarch64], [enable_cxx_exceptions=no], + [enable_cxx_exceptions=yes])] +) +AC_MSG_RESULT([$enable_cxx_exceptions]) +AM_CONDITIONAL([SUPPORT_CXX_EXCEPTIONS], [test x$enable_cxx_exceptions = xyes]) + +AC_MSG_CHECKING([if documentation should be built]) +AC_ARG_ENABLE([documentation], + [AS_HELP_STRING([--enable-documentation], + [enable generating the man pages @<:@default=yes@:>@])], + [], + [enable_documentation=yes]) +AC_MSG_RESULT([$enable_documentation]) +AC_PATH_PROG([LATEX2MAN],[latex2man]) +AS_IF([test "x$LATEX2MAN" = "x" && test "x$enable_documentation" != "xno"], [ + AC_MSG_WARN([latex2man not found. Install latex2man. Disabling docs.]) + enable_documentation="no"; +]) +AM_CONDITIONAL([CONFIG_DOCS], [test x$enable_documentation != xno]) +AM_COND_IF([CONFIG_DOCS], [AC_CONFIG_FILES([doc/Makefile doc/common.tex])]) + +# Enable tests built around unw_resume, which is not supported on all targets +AC_MSG_CHECKING([if we should enable unw_resume tests]) +AS_CASE([$target_os], + [nto-qnx*], [enable_unw_resume_tests=no], + [enable_unw_resume_tests=yes]) +AC_MSG_RESULT([$enable_unw_resume_tests]) +AM_CONDITIONAL([ENABLE_UNW_RESUME_TESTS], [test x$enable_unw_resume_tests = xyes]) AC_MSG_CHECKING([for build architecture]) AC_MSG_RESULT([$build_arch]) @@ -175,11 +319,8 @@ AC_MSG_RESULT([$target_arch]) AC_MSG_CHECKING([for target operating system]) AC_MSG_RESULT([$target_os]) -AM_CONDITIONAL(BUILD_COREDUMP, test x$enable_coredump = xyes) -AM_CONDITIONAL(BUILD_PTRACE, test x$enable_ptrace = xyes) -AM_CONDITIONAL(BUILD_SETJMP, test x$enable_setjmp = xyes) -AM_CONDITIONAL(BUILD_UNWIND_HEADER, test "x$enable_unwind_header" = xyes) -AM_CONDITIONAL(NO_PTRACE_TEST, test x$build_arch != x$host_arch) +AM_CONDITIONAL([XFAIL_PTRACE_TEST], [echo $CFLAGS | grep -q '\-m32\>']) +AM_CONDITIONAL([CROSS_BUILD], [test x$build_arch != x$host_arch]) AM_CONDITIONAL(REMOTE_ONLY, test x$target_arch != x$host_arch) AM_CONDITIONAL(ARCH_AARCH64, test x$target_arch = xaarch64) AM_CONDITIONAL(ARCH_ARM, test x$target_arch = xarm) @@ -191,7 +332,6 @@ AM_CONDITIONAL(ARCH_X86_64, test x$target_arch = xx86_64) 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(ARCH_RISCV, test x$target_arch = xriscv) AM_CONDITIONAL(ARCH_LOONGARCH64, test x$target_arch = xloongarch64) @@ -202,12 +342,12 @@ 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]);; -(mips|riscv|loongarch64) use_elfxx=yes; AC_MSG_RESULT([xx]);; -*) AC_MSG_ERROR([Unknown ELF target: ${target_arch}]) -esac +AS_CASE([${target_arch}], + [arm|hppa|ppc32|x86|sh], [use_elf32=yes; AC_MSG_RESULT([32])], + [aarch64|ia64|ppc64|x86_64|s390x], [use_elf64=yes; AC_MSG_RESULT([64])], + [mips|riscv|loongarch64], [use_elfxx=yes; AC_MSG_RESULT([xx])], + [AC_MSG_ERROR([Unknown ELF target: ${target_arch}])] +) AM_CONDITIONAL(USE_ELF32, [test x$use_elf32 = xyes]) AM_CONDITIONAL(USE_ELF64, [test x$use_elf64 = xyes]) AM_CONDITIONAL(USE_ELFXX, [test x$use_elfxx = xyes]) @@ -230,36 +370,6 @@ else fi AC_MSG_RESULT([$remote_only]) -AC_MSG_CHECKING([whether to enable debug support]) -AC_ARG_ENABLE(debug, -AS_HELP_STRING([--enable-debug],[turn on debug support (slows down execution)])) -if test x$enable_debug = xyes; then - CPPFLAGS="${CPPFLAGS} -DDEBUG" -else - CPPFLAGS="${CPPFLAGS} -DNDEBUG" -fi -AC_MSG_RESULT([$enable_debug]) - -AC_MSG_CHECKING([whether to enable C++ exception support]) -AC_ARG_ENABLE(cxx_exceptions, -AS_HELP_STRING([--enable-cxx-exceptions],[use libunwind to handle C++ exceptions]),, -[ -# C++ exception handling doesn't work too well on x86 -case $target_arch in - x86*) enable_cxx_exceptions=no;; - aarch64*) enable_cxx_exceptions=no;; - arm*) enable_cxx_exceptions=no;; - mips*) enable_cxx_exceptions=no;; - tile*) enable_cxx_exceptions=no;; - s390x*) enable_cxx_exceptions=no;; - loongarch*) enable_cxx_exceptions=no;; - *) enable_cxx_exceptions=yes;; -esac -]) - -AM_CONDITIONAL([SUPPORT_CXX_EXCEPTIONS], [test x$enable_cxx_exceptions = xyes]) -AC_MSG_RESULT([$enable_cxx_exceptions]) - AC_MSG_CHECKING([whether to load .debug_frame sections]) AC_ARG_ENABLE(debug_frame, AS_HELP_STRING([--enable-debug-frame],[Load the ".debug_frame" section if available]),, [ @@ -337,15 +447,6 @@ 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 high TLS memory usage) (default: disabled)])) -AC_MSG_RESULT([$enable_per_thread_cache]) -AS_IF([test x$enable_per_thread_cache = xyes], [ - AC_DEFINE(HAVE___CACHE_PER_THREAD, 1, - [Define to 1 if --enable-per-thread-cache]) -]) - AC_MSG_CHECKING([for Intel compiler]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __INTEL_COMPILER #error choke me @@ -386,9 +487,13 @@ else LDFLAGS_NOSTARTFILES="-XCClinker -nostartfiles" fi -if test x$GCC = xyes -a x$intel_compiler != xyes -a x$qcc_compiler != xyes -a x$android != xyes; then - LIBCRTS="-lgcc_s" -fi +OLD_CFLAGS="${CFLAGS}" +CFLAGS="${CFLAGS} -march=armv8-a+sve" +AC_MSG_CHECKING([if compiler supports -march=armv8-a+sve]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], [supports_march_armv8_a_sve=yes],[supports_march_armv8_a_sve=no]) +AM_CONDITIONAL(COMPILER_SUPPORTS_MARCH_ARMV8_A_SVE, [test x$supports_march_armv8_a_sve = xyes]) +AC_MSG_RESULT([$supports_march_armv8_a_sve]) +CFLAGS="${OLD_CFLAGS}" AC_MSG_CHECKING([for __builtin___clear_cache]) AC_LINK_IFELSE( @@ -423,21 +528,6 @@ PKG_MINOR=pkg_minor PKG_EXTRA=pkg_extra PKG_MAINTAINER=pkg_maintainer -old_LIBS="$LIBS" -LIBS="" -AC_SEARCH_LIBS(backtrace, execinfo) -LIBS="$old_LIBS" -case "$ac_cv_search_backtrace" in - -l*) BACKTRACELIB=$ac_cv_search_backtrace;; - *) BACKTRACELIB="";; -esac - -AC_ARG_WITH([testdriver], - [AS_HELP_STRING([--with-testdriver], - [use designated test driver instead of default LOG_DRIVER])], - [], - [with_testdriver=\$\(top_srcdir\)/config/test-driver]) -AC_SUBST([UNW_TESTDRIVER], $with_testdriver) AC_SUBST(build_arch) AC_SUBST(target_os) @@ -445,36 +535,13 @@ AC_SUBST(arch) AC_SUBST(ARCH) AC_SUBST(LDFLAGS_STATIC_LIBCXA) AC_SUBST(LDFLAGS_NOSTARTFILES) -AC_SUBST(LIBCRTS) AC_SUBST(PKG_MAJOR) AC_SUBST(PKG_MINOR) AC_SUBST(PKG_EXTRA) AC_SUBST(PKG_MAINTAINER) AC_SUBST(enable_cxx_exceptions) AC_SUBST(enable_debug_frame) -AC_SUBST(DLLIB) -AC_SUBST(BACKTRACELIB) -AC_PATH_PROG([LATEX2MAN],[latex2man]) -if test "x$LATEX2MAN" = "x" && test "x$enable_documentation" = "xyes"; then - AC_MSG_WARN([latex2man not found. Install latex2man. Disabling docs.]) - enable_documentation="no"; -fi - -AM_CONDITIONAL([CONFIG_DOCS], [test x$enable_documentation = xyes]) -if test "x$enable_documentation" = "xyes"; then - AC_CONFIG_FILES(doc/Makefile doc/common.tex) -fi - -AM_CONDITIONAL([CONFIG_TESTS], [test x$enable_tests = xyes]) -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 diff --git a/src/native/external/libunwind/doc/Makefile.am b/src/native/external/libunwind/doc/Makefile.am index 2252978dcd79fc..74bf6ca6a70684 100644 --- a/src/native/external/libunwind/doc/Makefile.am +++ b/src/native/external/libunwind/doc/Makefile.am @@ -1,6 +1,9 @@ # man pages that go into section 3: man3_MANS = libunwind.man libunwind-dynamic.man libunwind-ia64.man \ - libunwind-ptrace.man libunwind-setjmp.man \ + libunwind-coredump.man \ + libunwind-ptrace.man \ + libunwind-setjmp.man \ + libunwind-nto.man \ unw_apply_reg_state.man \ unw_backtrace.man \ unw_flush_cache.man \ @@ -22,17 +25,23 @@ man3_MANS = libunwind.man libunwind-dynamic.man libunwind-ia64.man \ unw_regname.man unw_resume.man \ unw_reg_states_iterate.man \ unw_set_caching_policy.man \ + unw_set_iterate_phdr_function.man \ unw_set_cache_size.man \ unw_set_fpreg.man \ unw_set_reg.man \ unw_step.man \ unw_strerror.man \ _U_dyn_register.man \ - _U_dyn_cancel.man + _U_dyn_cancel.man \ + unw_get_elf_filename.man \ + unw_get_elf_filename_by_ip.man EXTRA_DIST = NOTES libunwind.trans \ libunwind.tex libunwind-dynamic.tex libunwind-ia64.tex \ - libunwind-ptrace.tex libunwind-setjmp.tex \ + libunwind-coredump.tex \ + libunwind-ptrace.tex \ + libunwind-setjmp.tex \ + libunwind-nto.tex \ unw_apply_reg_state.tex \ unw_backtrace.tex \ unw_flush_cache.tex \ @@ -50,6 +59,7 @@ EXTRA_DIST = NOTES libunwind.trans \ unw_is_signal_frame.tex \ unw_create_addr_space.tex unw_destroy_addr_space.tex \ unw_regname.tex unw_resume.tex unw_set_caching_policy.tex \ + unw_set_iterate_phdr_function.tex \ unw_reg_states_iterate.tex \ unw_set_cache_size.tex \ unw_set_fpreg.tex \ @@ -58,6 +68,8 @@ EXTRA_DIST = NOTES libunwind.trans \ unw_strerror.tex \ _U_dyn_register.tex \ _U_dyn_cancel.tex \ + unw_get_elf_filename.tex \ + unw_get_elf_filename_by_ip.tex \ $(man3_MANS) L2M = latex2man diff --git a/src/native/external/libunwind/doc/_U_dyn_cancel.man b/src/native/external/libunwind/doc/_U_dyn_cancel.man index a420a6deaf3e09..653b09795ae7be 100644 --- a/src/native/external/libunwind/doc/_U_dyn_cancel.man +++ b/src/native/external/libunwind/doc/_U_dyn_cancel.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 12:09:49 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "\\_U\\_DYN\\_CANCEL" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "\\_U\\_DYN\\_CANCEL" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME _U_dyn_cancel \-\- cancel unwind\-info for dynamically generated code @@ -30,7 +32,7 @@ _U_dyn_cancel(unw_dyn_info_t *di); .PP The _U_dyn_cancel() routine cancels the registration of the -unwind\-info for a dynamically generated procedure. Argument di +unwind info for a dynamically generated procedure. Argument di is the pointer to the unw_dyn_info_t structure that describes the procedure\&'s unwind\-info. @@ -45,15 +47,15 @@ or _U_dyn_cancel()). .PP _U_dyn_cancel() -is thread\-safe but \fInot\fP +is thread safe but \fInot\fP safe to use from a signal handler. .PP .SH SEE ALSO .PP -libunwind\-dynamic(3), -_U_dyn_register(3) +libunwind\-dynamic(3libunwind), +_U_dyn_register(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/_U_dyn_cancel.tex b/src/native/external/libunwind/doc/_U_dyn_cancel.tex index ca5a12a76eede5..c9cefc3e18a2d1 100644 --- a/src/native/external/libunwind/doc/_U_dyn_cancel.tex +++ b/src/native/external/libunwind/doc/_U_dyn_cancel.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{\_U\_dyn\_cancel}{David Mosberger-Tang}{Programming Library}{\_U\_dyn\_cancel}\_U\_dyn\_cancel -- cancel unwind-info for dynamically generated code +\begin{Name}{3libunwind}{\_U\_dyn\_cancel}{David Mosberger-Tang}{Programming Library}{\_U\_dyn\_cancel}\_U\_dyn\_cancel -- cancel unwind-info for dynamically generated code \end{Name} \section{Synopsis} @@ -17,7 +17,7 @@ \section{Synopsis} \section{Description} The \Func{\_U\_dyn\_cancel}() routine cancels the registration of the -unwind-info for a dynamically generated procedure. Argument \Var{di} +unwind info for a dynamically generated procedure. Argument \Var{di} is the pointer to the \Type{unw\_dyn\_info\_t} structure that describes the procedure's unwind-info. @@ -28,12 +28,13 @@ \section{Description} \section{Thread and Signal Safety} -\Func{\_U\_dyn\_cancel}() is thread-safe but \emph{not} safe to use +\Func{\_U\_dyn\_cancel}() is thread safe but \emph{not} safe to use from a signal handler. \section{See Also} -\SeeAlso{libunwind-dynamic(3)}, \SeeAlso{\_U\_dyn\_register(3)} +\SeeAlso{libunwind-dynamic}(3libunwind), +\SeeAlso{\_U\_dyn\_register}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/_U_dyn_register.man b/src/native/external/libunwind/doc/_U_dyn_register.man index 107e5fd0e18d8c..dc5814160d8156 100644 --- a/src/native/external/libunwind/doc/_U_dyn_register.man +++ b/src/native/external/libunwind/doc/_U_dyn_register.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 12:09:49 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,10 +12,10 @@ .fi .. -.TH "\\_U\\_DYN\\_REGISTER" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "\\_U\\_DYN\\_REGISTER" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME _U_dyn_register -\-\- register unwind\-info for dynamically generated code +\-\- register unwind info for dynamically generated code .PP .SH SYNOPSIS @@ -29,11 +31,11 @@ _U_dyn_register(unw_dyn_info_t *di); .PP The _U_dyn_register() -routine registers unwind\-info for a -dynamically generated procedure. The procedure\&'s unwind\-info is +routine registers unwind info for a +dynamically generated procedure. The procedure\&'s unwind info is described by a structure of type unw_dyn_info_t (see -libunwind\-dynamic(3)). +libunwind\-dynamic(3libunwind)). A pointer to this structure is passed in argument di\&. .PP @@ -47,15 +49,15 @@ or _U_dyn_cancel()). .PP _U_dyn_register() -is thread\-safe but \fInot\fP +is thread safe but \fInot\fP safe to use from a signal handler. .PP .SH SEE ALSO .PP -libunwind\-dynamic(3), -_U_dyn_cancel(3) +libunwind\-dynamic(3libunwind), +_U_dyn_cancel(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/_U_dyn_register.tex b/src/native/external/libunwind/doc/_U_dyn_register.tex index ab23b5c6213634..d56a7ceec81c65 100644 --- a/src/native/external/libunwind/doc/_U_dyn_register.tex +++ b/src/native/external/libunwind/doc/_U_dyn_register.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{\_U\_dyn\_register}{David Mosberger-Tang}{Programming Library}{\_U\_dyn\_register}\_U\_dyn\_register -- register unwind-info for dynamically generated code +\begin{Name}{3libunwind}{\_U\_dyn\_register}{David Mosberger-Tang}{Programming Library}{\_U\_dyn\_register}\_U\_dyn\_register -- register unwind info for dynamically generated code \end{Name} \section{Synopsis} @@ -16,10 +16,10 @@ \section{Synopsis} \section{Description} -The \Func{\_U\_dyn\_register}() routine registers unwind-info for a -dynamically generated procedure. The procedure's unwind-info is +The \Func{\_U\_dyn\_register}() routine registers unwind info for a +dynamically generated procedure. The procedure's unwind info is described by a structure of type \Type{unw\_dyn\_info\_t} (see -\SeeAlso{libunwind-dynamic(3)}). A pointer to this structure is +\SeeAlso{libunwind-dynamic}(3libunwind)). A pointer to this structure is passed in argument \Var{di}. The \Func{\_U\_dyn\_register}() routine is guaranteed to execute in @@ -29,12 +29,13 @@ \section{Description} \section{Thread and Signal Safety} -\Func{\_U\_dyn\_register}() is thread-safe but \emph{not} safe to use +\Func{\_U\_dyn\_register}() is thread safe but \emph{not} safe to use from a signal handler. \section{See Also} -\SeeAlso{libunwind-dynamic(3)}, \SeeAlso{\_U\_dyn\_cancel(3)} +\SeeAlso{libunwind-dynamic}(3libunwind), +\SeeAlso{\_U\_dyn\_cancel}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/libunwind-coredump.man b/src/native/external/libunwind/doc/libunwind-coredump.man new file mode 100644 index 00000000000000..9562ea5fbac9a2 --- /dev/null +++ b/src/native/external/libunwind/doc/libunwind-coredump.man @@ -0,0 +1,211 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} +'\" t +.\" Manual page created with latex2man on Tue Aug 29 10:53:41 2023 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "LIBUNWIND\-COREDUMP" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " +.SH NAME +libunwind\-coredump +\-\- coredump() support in libunwind +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +unw_accessors_t +_UCD_accessors; +.br +.PP +struct UCD_info *_UCD_create(char const *); +.br +void _UCD_destroy(struct UCD_info *); +.br +.PP +int +_UCD_get_num_threads(struct UCD_info *); +.br +void +_UCD_select_thread(struct UCD_info *, +int); +.br +void +_UCD_get_pid(struct UCD_info *); +.br +void +_UCD_get_cursig(struct UCD_info *); +.br +.PP +int +_UCD_find_proc_info(unw_addr_space_t, +unw_word_t, +unw_proc_info_t *, +int, +void *); +.br +void +_UCD_put_unwind_info(unw_addr_space_t, +unw_proc_info_t *, +void *); +.br +int +_UCD_get_dyn_info_list_addr(unw_addr_space_t, +unw_word_t *, +void *); +.br +int +_UCD_access_mem(unw_addr_space_t, +unw_word_t, +unw_word_t *, +int, +void *); +.br +int +_UCD_access_reg(unw_addr_space_t, +unw_regnum_t, +unw_word_t *, +int, +void *); +.br +int +_UCD_access_fpreg(unw_addr_space_t, +unw_regnum_t, +unw_fpreg_t *, +int, +void *); +.br +int +_UCD_get_proc_name(unw_addr_space_t, +unw_word_t, +char *, +size_t, +unw_word_t *, +void *); +.br +int +_UCD_resume(unw_addr_space_t, +unw_cursor_t *, +void *); +.br +.PP +.SH DESCRIPTION + +.PP +It is possible to generate a snapshot of a process state at a specific moment in +time and save it in a specially\-formatted file called a coredump. +This often happens automatically when a process encounters an unrecoverable +error and the OS itself captures the state of the process when the error +occurred. +libunwind +provides a library that can be used as part of a lightweight +tool to generate some useful information as to why the process abnormally +terminated (such as a stack trace of al threads of execution). +The routines and variables +implementing this facility use a prefix of _UCD, +which +stands for ``unwind\-via\-coredump\&''\&. +.PP +An application that wants to use the coredump remote first needs +to create a new libunwind +address space that represents the +target process. This is done by calling +unw_create_addr_space(). +In many cases, the application +will simply want to pass the address of _UCD_accessors +as the +first argument to this routine. Doing so will ensure that +libunwind +will be able to properly unwind the target process. +However, in special circumstances, an application may prefer to use +only portions of the _UCD\-facility. +For this reason, the +individual callback routines (_UCD_find_proc_info(), +_UCD_put_unwind_info(), +etc.) are also available for direct +use. Of course, the addresses of these routines could also be picked +up from _UCD_accessors, +but doing so would prevent static +initialization. Also, when using _UCD_accessors, +\fIall\fP +the callback routines will be linked into the application, even if +they are never actually called. +.PP +Next, the application needs to load the corefile for analysis and create an +(opaque) UCD_info structure by calling _UCD_create(), +passing the name of the corefile. +The returned opaque pointer then needs to be +passed as the ``argument\&'' pointer (third argument) to +unw_init_remote(). +.PP +When the application is done using libunwind +on the corefile, +_UCD_destroy() +needs to be called, +passing it the pointer that was returned by the corresponding call to +_UCD_create(). +This ensures that all memory and other resources are freed up. +.PP +.TP +_UCD_get_num_threads() + Gets the number of threads in the corefile. +.PP +.TP +_UCD_get_pid() + Gets the process ID of the process associated with the corefile. +.PP +.TP +_UCD_get_cursig() + Gets the current signal begin received by the process associated with the +corefile (if any). +.PP +.TP +_UCD_select_thread() + Selects the current thread for unwinding. +.PP +.SH THREAD SAFETY + +.PP +The coredump remote assumes that a single _UCD_info +structure is never shared between threads. +Because of this, +no explicit locking is used. +As long as only one thread uses a _UCD_info +structure at any given time, +this facility is thread\-safe. +.PP +.SH RETURN VALUE + +.PP +_UCD_create() +may return a null pointer if it fails +to create the UCD_info +for any reason. +.PP +.SH FILES + +.PP +.TP +libunwind\-coredump.h + Header file to include when using the +interface defined by this library. +.TP +\fB\-l\fPunwind\-coredump \fB\-l\fPunwind\-generic + Linker\-switches to add when building a program that uses the +functions defined by this library. +.PP +.SH SEE ALSO + +.PP +libunwind(3libunwind) +.PP +.\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/native/external/libunwind/doc/libunwind-coredump.tex b/src/native/external/libunwind/doc/libunwind-coredump.tex new file mode 100644 index 00000000000000..08b5e0055b749f --- /dev/null +++ b/src/native/external/libunwind/doc/libunwind-coredump.tex @@ -0,0 +1,138 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3libunwind}{libunwind-coredump}{}{Programming Library}{coredump analysis support in libunwind}libunwind-coredump -- coredump() support in libunwind +\end{Name} + +\section{Synopsis} + +\File{\#include $<$libunwind-coredump.h$>$}\\ + +\noindent +\Type{unw\_accessors\_t} \Var{\_UCD\_accessors};\\ + +\Type{struct~UCD\_info~*}\Func{\_UCD\_create}(\Type{char const~*});\\ +\noindent +\Type{void}~\Func{\_UCD\_destroy}(\Type{struct UCD\_info~*});\\ + +\noindent +\Type{int} \Func{\_UCD\_get\_num\_threads}(\Type{struct UCD\_info~*});\\ +\noindent +\Type{void} \Func{\_UCD\_select\_thread}(\Type{struct UCD\_info~*}, \Type{int});\\ +\noindent +\Type{void} \Func{\_UCD\_get\_pid}(\Type{struct UCD\_info~*});\\ +\noindent +\Type{void} \Func{\_UCD\_get\_cursig}(\Type{struct UCD\_info~*});\\ + +\noindent +\Type{int} \Func{\_UCD\_find\_proc\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_proc\_info\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{void} \Func{\_UCD\_put\_unwind\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_proc\_info\_t~*}, \Type{void~*});\\ +\noindent +\Type{int} \Func{\_UCD\_get\_dyn\_info\_list\_addr}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ +\noindent +\Type{int} \Func{\_UCD\_access\_mem}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{int} \Func{\_UCD\_access\_reg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{int} \Func{\_UCD\_access\_fpreg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{int} \Func{\_UCD\_get\_proc\_name}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ +\noindent +\Type{int} \Func{\_UCD\_resume}(\Type{unw\_addr\_space\_t}, \Type{unw\_cursor\_t~*}, \Type{void~*});\\ + +\section{Description} + +It is possible to generate a snapshot of a process state at a specific moment in +time and save it in a specially-formatted file called a coredump. +This often happens automatically when a process encounters an unrecoverable +error and the OS itself captures the state of the process when the error +occurred. +\Prog{libunwind} provides a library that can be used as part of a lightweight +tool to generate some useful information as to why the process abnormally +terminated (such as a stack trace of al threads of execution). +The routines and variables +implementing this facility use a prefix of \Func{\_UCD}, which +stands for ``unwind-via-coredump''. + +An application that wants to use the coredump remote first needs +to create a new \Prog{libunwind} address space that represents the +target process. This is done by calling +\Func{unw\_create\_addr\_space}(). In many cases, the application +will simply want to pass the address of \Var{\_UCD\_accessors} as the +first argument to this routine. Doing so will ensure that +\Prog{libunwind} will be able to properly unwind the target process. +However, in special circumstances, an application may prefer to use +only portions of the \Prog{\_UCD}-facility. For this reason, the +individual callback routines (\Func{\_UCD\_find\_proc\_info}(), +\Func{\_UCD\_put\_unwind\_info}(), etc.) are also available for direct +use. Of course, the addresses of these routines could also be picked +up from \Var{\_UCD\_accessors}, but doing so would prevent static +initialization. Also, when using \Var{\_UCD\_accessors}, \emph{all} +the callback routines will be linked into the application, even if +they are never actually called. + +Next, the application needs to load the corefile for analysis and create an +(opaque) UCD\_info structure by calling \Func{\_UCD_create}(), +passing the name of the corefile. +The returned opaque pointer then needs to be +passed as the ``argument'' pointer (third argument) to +\Func{unw\_init\_remote}(). + +When the application is done using \Prog{libunwind} on the corefile, +\Func{\_UCD\_destroy}() needs to be called, +passing it the pointer that was returned by the corresponding call to +\Func{\_UCD\_create}(). +This ensures that all memory and other resources are freed up. + +\begin{description}[style=nextline] + + \item[\Func{\_UCD\_get\_num\_threads}()] + Gets the number of threads in the corefile. + +\item[\Func{\_UCD\_get\_pid}()] + Gets the process ID of the process associated with the corefile. + +\item[\Func{\_UCD\_get\_cursig}()] + Gets the current signal begin received by the process associated with the + corefile (if any). + +\item[\Func{\_UCD\_select\_thread}()] + Selects the current thread for unwinding. + +\end{description} + +\section{Thread Safety} + +The coredump remote assumes that a single \Prog{\_UCD\_info} +structure is never shared between threads. +Because of this, +no explicit locking is used. +As long as only one thread uses a \Prog{\_UCD\_info} structure at any given time, +this facility is thread-safe. + +\section{Return Value} + +\Func{\_UCD\_create}() may return a null pointer if it fails +to create the \Prog{UCD\_info} for any reason. + +\section{Files} + +\begin{Description} +\item[\File{libunwind-coredump.h}] Header file to include when using the + interface defined by this library. +\item[\Opt{-l}\File{unwind-coredump} \Opt{-l}\File{unwind-generic}] + Linker-switches to add when building a program that uses the + functions defined by this library. +\end{Description} + +\section{See Also} + +\SeeAlso{libunwind}(3libunwind) + +\LatexManEnd +\end{document} diff --git a/src/native/external/libunwind/doc/libunwind-dynamic.man b/src/native/external/libunwind/doc/libunwind-dynamic.man index 68c66f3a329843..df28abaac8b664 100644 --- a/src/native/external/libunwind/doc/libunwind-dynamic.man +++ b/src/native/external/libunwind/doc/libunwind-dynamic.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Sun Aug 29 23:45:06 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,479 +12,478 @@ .fi .. -.TH "LIBUNWIND\-DYNAMIC" "3" "29 August 2021" "Programming Library " "Programming Library " +.TH "LIBUNWIND\-DYNAMIC" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME libunwind\-dynamic -\-\- libunwind\-support for runtime\-generated code +\-\- libunwind\-support for runtime\-generated code .PP .SH INTRODUCTION .PP For libunwind -to do its job, it needs to be able to reconstruct +to do its job, it needs to be able to reconstruct the \fIframe state\fP -of each frame in a call\-chain. The frame state -describes the subset of the machine\-state that consists of the +of each frame in a call\-chain. The frame state +describes the subset of the machine\-state that consists of the \fIframe registers\fP -(typically the instruction\-pointer and the -stack\-pointer) and all callee\-saved registers (preserved registers). -The frame state describes each register either by providing its -current value (for frame registers) or by providing the location at -which the current value is stored (callee\-saved registers). +(typically the instruction\-pointer and the +stack\-pointer) and all callee\-saved registers (preserved registers). +The frame state describes each register either by providing its +current value (for frame registers) or by providing the location at +which the current value is stored (callee\-saved registers). .PP -For statically generated code, the compiler normally takes care of +For statically generated code, the compiler normally takes care of emitting \fIunwind\-info\fP -which provides the minimum amount of -information needed to reconstruct the frame\-state for each instruction -in a procedure. For dynamically generated code, the runtime code -generator must use the dynamic unwind\-info interface provided by +which provides the minimum amount of +information needed to reconstruct the frame\-state for each instruction +in a procedure. For dynamically generated code, the runtime code +generator must use the dynamic unwind\-info interface provided by libunwind -to supply the equivalent information. This manual -page describes the format of this information in detail. +to supply the equivalent information. This manual +page describes the format of this information in detail. .PP For the purpose of this discussion, a \fIprocedure\fP -is defined to +is defined to be an arbitrary piece of \fIcontiguous\fP -code. Normally, each -procedure directly corresponds to a function in the source\-language -but this is not strictly required. For example, a runtime -code\-generator could translate a given function into two separate -(discontiguous) procedures: one for frequently\-executed (hot) code and -one for rarely\-executed (cold) code. Similarly, simple -source\-language functions (usually leaf functions) may get translated -into code for which the default unwind\-conventions apply and for such -code, it is not strictly necessary to register dynamic unwind\-info. +code. Normally, each +procedure directly corresponds to a function in the source\-language +but this is not strictly required. For example, a runtime +code\-generator could translate a given function into two separate +(discontiguous) procedures: one for frequently\-executed (hot) code and +one for rarely\-executed (cold) code. Similarly, simple +source\-language functions (usually leaf functions) may get translated +into code for which the default unwind\-conventions apply and for such +code, it is not strictly necessary to register dynamic unwind\-info. .PP A procedure logically consists of a sequence of \fIregions\fP\&. -Regions are nested in the sense that the frame state at the end of one -region is, by default, assumed to be the frame state for the next -region. Each region is thought of as being divided into a +Regions are nested in the sense that the frame state at the end of one +region is, by default, assumed to be the frame state for the next +region. Each region is thought of as being divided into a \fIprologue\fP, a \fIbody\fP, and an \fIepilogue\fP\&. -Each of them -can be empty. If non\-empty, the prologue sets up the frame state for -the body. For example, the prologue may need to allocate some space -on the stack and save certain callee\-saved registers. The body -performs the actual work of the procedure but does not change the -frame state in any way. If non\-empty, the epilogue restores the -previous frame state and as such it undoes or cancels the effect of -the prologue. In fact, a single epilogue may undo the effect of the -prologues of several (nested) regions. -.PP -We should point out that even though the prologue, body, and epilogue -are logically separate entities, optimizing code\-generators will -generally interleave instructions from all three entities. For this +Each of them +can be empty. If non\-empty, the prologue sets up the frame state for +the body. For example, the prologue may need to allocate some space +on the stack and save certain callee\-saved registers. The body +performs the actual work of the procedure but does not change the +frame state in any way. If non\-empty, the epilogue restores the +previous frame state and as such it undoes or cancels the effect of +the prologue. In fact, a single epilogue may undo the effect of the +prologues of several (nested) regions. +.PP +We should point out that even though the prologue, body, and epilogue +are logically separate entities, optimizing code\-generators will +generally interleave instructions from all three entities. For this reason, the dynamic unwind\-info interface of libunwind -makes no -distinction whatsoever between prologue and body. Similarly, the -exact set of instructions that make up an epilogue is also irrelevant. -The only point in the epilogue that needs to be described explicitly -by the dynamic unwind\-info is the point at which the stack\-pointer -gets restored. The reason this point needs to be described is that -once the stack\-pointer is restored, all values saved in the -deallocated portion of the stack frame become invalid and hence +makes no +distinction whatsoever between prologue and body. Similarly, the +exact set of instructions that make up an epilogue is also irrelevant. +The only point in the epilogue that needs to be described explicitly +by the dynamic unwind\-info is the point at which the stack\-pointer +gets restored. The reason this point needs to be described is that +once the stack\-pointer is restored, all values saved in the +deallocated portion of the stack frame become invalid and hence libunwind -needs to know about it. The portion of the frame -state not saved on the stack is assumed to remain valid through the end -of the region. For this reason, there is usually no need to describe -instructions which restore the contents of callee\-saved registers. -.PP -Within a region, each instruction that affects the frame state in some -fashion needs to be described with an operation descriptor. For this -purpose, each instruction in the region is assigned a unique index. -Exactly how this index is derived depends on the architecture. For -example, on RISC and EPIC\-style architecture, instructions have a -fixed size so it\&'s possible to simply number the instructions. In -contrast, most CISC use variable\-length instruction encodings, so it -is usually necessary to use a byte\-offset as the index. Given the -instruction index, the operation descriptor specifies the effect of -the instruction in an abstract manner. For example, it might express +needs to know about it. The portion of the frame +state not saved on the stack is assumed to remain valid through the end +of the region. For this reason, there is usually no need to describe +instructions which restore the contents of callee\-saved registers. +.PP +Within a region, each instruction that affects the frame state in some +fashion needs to be described with an operation descriptor. For this +purpose, each instruction in the region is assigned a unique index. +Exactly how this index is derived depends on the architecture. For +example, on RISC and EPIC\-style architecture, instructions have a +fixed size so it\&'s possible to simply number the instructions. In +contrast, most CISC use variable\-length instruction encodings, so it +is usually necessary to use a byte\-offset as the index. Given the +instruction index, the operation descriptor specifies the effect of +the instruction in an abstract manner. For example, it might express that the instruction stores callee\-saved register r1 -at offset 16 -in the stack frame. +at offset 16 +in the stack frame. .PP .SH PROCEDURES .PP -A runtime code\-generator registers the dynamic unwind\-info of a +A runtime code\-generator registers the dynamic unwind\-info of a procedure by setting up a structure of type unw_dyn_info_t and calling _U_dyn_register(), -passing the address of the -structure as the sole argument. The members of the +passing the address of the +structure as the sole argument. The members of the unw_dyn_info_t -structure are described below: +structure are described below: .TP void *next Private to libunwind\&. -Must not be used -by the application. +Must not be used +by the application. .TP void *prev Private to libunwind\&. -Must not be used -by the application. +Must not be used +by the application. .TP unw_word_t start_ip - The start\-address of the -instructions of the procedure (remember: procedure are defined to be -contiguous pieces of code, so a single code\-range is sufficient). + The start\-address of the +instructions of the procedure (remember: procedure are defined to be +contiguous pieces of code, so a single code\-range is sufficient). .TP unw_word_t end_ip - The end\-address of the -instructions of the procedure (non\-inclusive, that is, + The end\-address of the +instructions of the procedure (non\-inclusive, that is, end_ip\-start_ip -is the size of the procedure in -bytes). +is the size of the procedure in +bytes). .TP unw_word_t gp - The global\-pointer value in use -for this procedure. The exact meaning of the global\-pointer is -architecture\-specific and on some architecture, it is not used at -all. + The global\-pointer value in use +for this procedure. The exact meaning of the global\-pointer is +architecture\-specific and on some architecture, it is not used at +all. .TP int32_t format - The format of the unwind\-info. + The format of the unwind\-info. This member can be one of UNW_INFO_FORMAT_DYNAMIC, UNW_INFO_FORMAT_TABLE, -or +or UNW_INFO_FORMAT_REMOTE_TABLE\&. .TP union u - This union contains one sub\-member -structure for every possible unwind\-info format: + This union contains one sub\-member +structure for every possible unwind\-info format: .RS .TP unw_dyn_proc_info_t pi - This member is used + This member is used for format UNW_INFO_FORMAT_DYNAMIC\&. .TP unw_dyn_table_info_t ti - This member is used + This member is used for format UNW_INFO_FORMAT_TABLE\&. .TP unw_dyn_remote_table_info_t rti - This member + This member is used for format UNW_INFO_FORMAT_REMOTE_TABLE\&. .RE .RS .PP -The format of these sub\-members is described in detail below. +The format of these sub\-members is described in detail below. .RE .PP .SS PROC\-INFO FORMAT .PP -This is the preferred dynamic unwind\-info format and it is generally -the one used by full\-blown runtime code\-generators. In this format, -the details of a procedure are described by a structure of type +This is the preferred dynamic unwind\-info format and it is generally +the one used by full\-blown runtime code generators. In this format, +the details of a procedure are described by a structure of type unw_dyn_proc_info_t\&. -This structure contains the following -members: +This structure contains the following +members: .PP -.RE .TP unw_word_t name_ptr - The address of a -(human\-readable) name of the procedure or 0 if no such name is -available. If non\-zero, the string stored at this address must be -ASCII NUL terminated. For source languages that use name\-mangling -(such as C++ or Java) the string stored at this address should be + The address of a +(human\-readable) name of the procedure or 0 if no such name is +available. If non\-zero, the string stored at this address must be +ASCII NUL terminated. For source languages that use name mangling +(such as C++ or Java) the string stored at this address should be the \fIdemangled\fP -version of the name. +version of the name. .PP .TP unw_word_t handler - The address of the -personality\-routine for this procedure. Personality\-routines are -used in conjunction with exception handling. See the C++ ABI draft -(http://www.codesourcery.com/cxx\-abi/) for an overview and a -description of the personality routine. If the procedure has no + The address of the +personality routine for this procedure. Personality routines are +used in conjunction with exception handling. See the C++ ABI draft +(http://www.codesourcery.com/cxx\-abi/) for an overview and a +description of the personality routine. If the procedure has no personality routine, handler -must be set to 0. +must be set to 0. .PP .TP uint32_t flags - A bitmask of flags. At the -moment, no flags have been defined and this member must be -set to 0. + A bitmask of flags. At the +moment, no flags have been defined and this member must be +set to 0. .PP .TP unw_dyn_region_info_t *regions - A NULL\-terminated -linked list of region\-descriptors. See section ``Region -descriptors\&'' below for more details. + A NULL\-terminated +linked list of region descriptors. See section ``Region +descriptors\&'' below for more details. .PP .SS TABLE\-INFO FORMAT .PP -This format is generally used when the dynamically generated code was -derived from static code and the unwind\-info for the dynamic and the -static versions are identical. For example, this format can be useful -when loading statically\-generated code into an address\-space in a -non\-standard fashion (i.e., through some means other than +This format is generally used when the dynamically generated code was +derived from static code and the unwind\-info for the dynamic and the +static versions are identical. For example, this format can be useful +when loading statically\-generated code into an address\-space in a +non\-standard fashion (i.e., through some means other than dlopen()). -In this format, the details of a group of procedures +In this format, the details of a group of procedures is described by a structure of type unw_dyn_table_info\&. -This structure contains the following members: +This structure contains the following members: .PP .TP unw_word_t name_ptr - The address of a -(human\-readable) name of the procedure or 0 if no such name is -available. If non\-zero, the string stored at this address must be -ASCII NUL terminated. For source languages that use name\-mangling -(such as C++ or Java) the string stored at this address should be + The address of a +(human\-readable) name of the procedure or 0 if no such name is +available. If non\-zero, the string stored at this address must be +ASCII NUL terminated. For source languages that use name\-mangling +(such as C++ or Java) the string stored at this address should be the \fIdemangled\fP -version of the name. +version of the name. .PP .TP unw_word_t segbase - The segment\-base value -that needs to be added to the segment\-relative values stored in the -unwind\-info. The exact meaning of this value is -architecture\-specific. + The segment\-base value +that needs to be added to the segment\-relative values stored in the +unwind\-info. The exact meaning of this value is +architecture\-specific. .PP .TP unw_word_t table_len - The length of the + The length of the unwind\-info (table_data) -counted in units of words +counted in units of words (unw_word_t). .PP .TP unw_word_t table_data - A pointer to the actual -data encoding the unwind\-info. The exact format is -architecture\-specific (see architecture\-specific sections below). + A pointer to the actual +data encoding the unwind info. The exact format is +architecture\-specific (see architecture\-specific sections below). .PP .SS REMOTE TABLE\-INFO FORMAT .PP -The remote table\-info format has the same basic purpose as the regular +The remote table\-info format has the same basic purpose as the regular table\-info format. The only difference is that when libunwind -uses the unwind\-info, it will keep the table data in the target -address\-space (which may be remote). Consequently, the type of the +uses the unwind\-info, it will keep the table data in the target +address\-space (which may be remote). Consequently, the type of the table_data member is unw_word_t -rather than a pointer. +rather than a pointer. This implies that libunwind -will have to access the table\-data +will have to access the table\-data via the address\-space\&'s access_mem() -call\-back, rather than -through a direct memory reference. -.PP -From the point of view of a runtime\-code generator, the remote -table\-info format offers no advantage and it is expected that such -generators will describe their procedures either with the proc\-info -format or the normal table\-info format. The main reason that the -remote table\-info format exists is to enable the +call\-back, rather than +through a direct memory reference. +.PP +From the point of view of a runtime code generator, the remote +table\-info format offers no advantage and it is expected that such +generators will describe their procedures either with the proc\-info +format or the normal table\-info format. The main reason that the +remote table\-info format exists is to enable the address\-space\-specific find_proc_info() -callback (see -unw_create_addr_space(3)) -to return unwind tables whose -data remains in remote memory. This can speed up unwinding (e.g., for -a debugger) because it reduces the amount of data that needs to be -loaded from remote memory. +callback (see +unw_create_addr_space(3libunwind)) +to return unwind tables whose +data remains in remote memory. This can speed up unwinding (e.g., for +a debugger) because it reduces the amount of data that needs to be +loaded from remote memory. .PP .SH REGIONS DESCRIPTORS .PP -A region descriptor is a variable length structure that describes how -each instruction in the region affects the frame state. Of course, -most instructions in a region usually do not change the frame state and -for those, nothing needs to be recorded in the region descriptor. A -region descriptor is a structure of type +A region descriptor is a variable length structure that describes how +each instruction in the region affects the frame state. Of course, +most instructions in a region usually do not change the frame state and +for those, nothing needs to be recorded in the region descriptor. A +region descriptor is a structure of type unw_dyn_region_info_t -and has the following members: +and has the following members: .TP unw_dyn_region_info_t *next - A pointer to the + A pointer to the next region. If this is the last region, next is NULL\&. .TP int32_t insn_count - The length of the region in -instructions. Each instruction is assumed to have a fixed size (see -architecture\-specific sections for details). The value of + The length of the region in +instructions. Each instruction is assumed to have a fixed size (see +architecture\-specific sections for details). The value of insn_count -may be negative in the last region of a procedure +may be negative in the last region of a procedure (i.e., it may be negative only if next is NULL). -A +A negative value indicates that the region covers the last \fIN\fP instructions of the procedure, where \fIN\fP -is the absolute value +is the absolute value of insn_count\&. .TP uint32_t op_count - The (allocated) length of + The (allocated) length of the op_count -array. +array. .TP unw_dyn_op_t op - An array of dynamic unwind -directives. See Section ``Dynamic unwind directives\&'' for a -description of the directives. + An array of dynamic unwind +directives. See Section ``Dynamic unwind directives\&'' for a +description of the directives. .PP A region descriptor with an insn_count -of zero is an +of zero is an \fIempty region\fP -and such regions are perfectly legal. In fact, -empty regions can be useful to establish a particular frame state -before the start of another region. -.PP -A single region list can be shared across multiple procedures provided -those procedures share a common prologue and epilogue (their bodies -may differ, of course). Normally, such procedures consist of a canned -prologue, the body, and a canned epilogue. This could be described by -two regions: one covering the prologue and one covering the epilogue. -Since the body length is variable, the latter region would need to +and such regions are perfectly legal. In fact, +empty regions can be useful to establish a particular frame state +before the start of another region. +.PP +A single region list can be shared across multiple procedures provided +those procedures share a common prologue and epilogue (their bodies +may differ, of course). Normally, such procedures consist of a canned +prologue, the body, and a canned epilogue. This could be described by +two regions: one covering the prologue and one covering the epilogue. +Since the body length is variable, the latter region would need to specify a negative value in insn_count -such that +such that libunwind -knows that the region covers the end of the procedure +knows that the region covers the end of the procedure (up to the address specified by end_ip). .PP -The region descriptor is a variable length structure to make it -possible to allocate all the necessary memory with a single -memory\-allocation request. To facilitate the allocation of a region +The region descriptor is a variable length structure to make it +possible to allocate all the necessary memory with a single +memory\-allocation request. To facilitate the allocation of a region descriptors libunwind -provides a helper routine with the -following synopsis: +provides a helper routine with the +following synopsis: .PP size_t _U_dyn_region_size(int op_count); .PP -This routine returns the number of bytes needed to hold a region +This routine returns the number of bytes needed to hold a region descriptor with space for op_count -unwind directives. Note +unwind directives. Note that the length of the op -array does not have to match exactly -with the number of directives in a region. Instead, it is sufficient +array does not have to match exactly +with the number of directives in a region. Instead, it is sufficient if the op -array contains at least as many entries as there are -directives, since the end of the directives can always be indicated +array contains at least as many entries as there are +directives, since the end of the directives can always be indicated with the UNW_DYN_STOP -directive. +directive. .PP .SH DYNAMIC UNWIND DIRECTIVES .PP -A dynamic unwind directive describes how the frame state changes -at a particular point within a region. The description is in +A dynamic unwind directive describes how the frame state changes +at a particular point within a region. The description is in the form of a structure of type unw_dyn_op_t\&. -This -structure has the following members: +This +structure has the following members: .TP int8_t tag - The operation tag. Must be one + The operation tag. Must be one of the unw_dyn_operation_t -values described below. +values described below. .TP int8_t qp - The qualifying predicate that controls -whether or not this directive is active. This is useful for -predicated architectures such as IA\-64 or ARM, where the contents of -another (callee\-saved) register determines whether or not an -instruction is executed (takes effect). If the directive is always -active, this member should be set to the manifest constant + The qualifying predicate that controls +whether or not this directive is active. This is useful for +predicated architectures such as IA\-64 or ARM, where the contents of +another (callee\-saved) register determines whether or not an +instruction is executed (takes effect). If the directive is always +active, this member should be set to the manifest constant _U_QP_TRUE -(this constant is defined for all -architectures, predicated or not). +(this constant is defined for all +architectures, predicated or not). .TP int16_t reg - The number of the register affected -by the instruction. + The number of the register affected +by the instruction. .TP int32_t when - The region\-relative number of -the instruction to which this directive applies. For example, -a value of 0 means that the effect described by this directive -has taken place once the first instruction in the region has -executed. + The region\-relative number of +the instruction to which this directive applies. For example, +a value of 0 means that the effect described by this directive +has taken place once the first instruction in the region has +executed. .TP unw_word_t val - The value to be applied by the -operation tag. The exact meaning of this value varies by tag. See -Section ``Operation tags\&'' below. + The value to be applied by the +operation tag. The exact meaning of this value varies by tag. See +Section ``Operation tags\&'' below. .PP -It is perfectly legitimate to specify multiple dynamic unwind +It is perfectly legitimate to specify multiple dynamic unwind directives with the same when -value, if a particular instruction -has a complex effect on the frame state. +value, if a particular instruction +has a complex effect on the frame state. .PP -Empty regions by definition contain no actual instructions and as such -the directives are not tied to a particular instruction. By +Empty regions by definition contain no actual instructions and as such +the directives are not tied to a particular instruction. By convention, the when -member should be set to 0, however. +member should be set to 0, however. .PP -There is no need for the dynamic unwind directives to appear +There is no need for the dynamic unwind directives to appear in order of increasing when -values. If the directives happen to -be sorted in that order, it may result in slightly faster execution, -but a runtime code\-generator should not go to extra lengths just to -ensure that the directives are sorted. +values. If the directives happen to +be sorted in that order, it may result in slightly faster execution, +but a runtime code\-generator should not go to extra lengths just to +ensure that the directives are sorted. .PP IMPLEMENTATION NOTE: should libunwind -implementations for -certain architectures prefer the list of unwind directives to be -sorted, it is recommended that such implementations first check -whether the list happens to be sorted already and, if not, sort the -directives explicitly before the first use. With this approach, the -overhead of explicit sorting is only paid when there is a real benefit -and if the runtime code\-generator happens to generate sorted lists -naturally, the performance penalty is limited to a simple O(N) check. +implementations for +certain architectures prefer the list of unwind directives to be +sorted, it is recommended that such implementations first check +whether the list happens to be sorted already and, if not, sort the +directives explicitly before the first use. With this approach, the +overhead of explicit sorting is only paid when there is a real benefit +and if the runtime code\-generator happens to generate sorted lists +naturally, the performance penalty is limited to a simple O(N) check. .PP .SS OPERATIONS TAGS .PP -The possible operation tags are defined by enumeration type +The possible operation tags are defined by enumeration type unw_dyn_operation_t -which defines the following -values: +which defines the following +values: .PP .TP UNW_DYN_STOP - Marks the end of the dynamic unwind + Marks the end of the dynamic unwind directive list. All remaining entries in the op -array of the -region\-descriptor are ignored. This tag is guaranteed to have a -value of 0. +array of the +region\-descriptor are ignored. This tag is guaranteed to have a +value of 0. .PP .TP UNW_DYN_SAVE_REG - Marks an instruction which saves + Marks an instruction which saves register reg to register val\&. .PP .TP UNW_DYN_SPILL_FP_REL - Marks an instruction which + Marks an instruction which spills register reg -to a frame\-pointer\-relative location. The -frame\-pointer\-relative offset is given by the value stored in member +to a frame\-pointer\-relative location. The +frame\-pointer\-relative offset is given by the value stored in member val\&. -See the architecture\-specific sections for a description -of the stack frame layout. +See the architecture\-specific sections for a description +of the stack frame layout. .PP .TP UNW_DYN_SPILL_SP_REL - Marks an instruction which + Marks an instruction which spills register reg -to a stack\-pointer\-relative location. The -stack\-pointer\-relative offset is given by the value stored in member +to a stack\-pointer\-relative location. The +stack\-pointer\-relative offset is given by the value stored in member val\&. -See the architecture\-specific sections for a description -of the stack frame layout. +See the architecture\-specific sections for a description +of the stack frame layout. .PP .TP UNW_DYN_ADD - Marks an instruction which adds + Marks an instruction which adds the constant value val to register reg\&. -To add subtract -a constant value, store the two\&'s\-complement of the value in +To add subtract +a constant value, store the two\&'s\-complement of the value in val\&. -The set of registers that can be specified for this tag -is described in the architecture\-specific sections below. +The set of registers that can be specified for this tag +is described in the architecture\-specific sections below. .PP .TP UNW_DYN_POP_FRAMES @@ -496,36 +497,36 @@ UNW_DYN_COPY_STATE .TP UNW_DYN_ALIAS .PP -unw_dyn_op_t -.PP -_U_dyn_op_save_reg(); -_U_dyn_op_spill_fp_rel(); -_U_dyn_op_spill_sp_rel(); -_U_dyn_op_add(); -_U_dyn_op_pop_frames(); -_U_dyn_op_label_state(); -_U_dyn_op_copy_state(); -_U_dyn_op_alias(); -_U_dyn_op_stop(); +unw_dyn_op_t +.PP +_U_dyn_op_save_reg(); +_U_dyn_op_spill_fp_rel(); +_U_dyn_op_spill_sp_rel(); +_U_dyn_op_add(); +_U_dyn_op_pop_frames(); +_U_dyn_op_label_state(); +_U_dyn_op_copy_state(); +_U_dyn_op_alias(); +_U_dyn_op_stop(); .PP .SH IA\-64 SPECIFICS .PP -\- meaning of segbase member in table\-info/table\-remote\-info format -\- format of table_data in table\-info/table\-remote\-info format -\- instruction size: each bundle is counted as 3 instructions, regardless -of template (MLX) -\- describe stack\-frame layout, especially with regards to sp\-relative -and fp\-relative addressing -\- UNW_DYN_ADD can only add to ``sp\&'' (always a negative value); use -POP_FRAMES otherwise +\- meaning of segbase member in table\-info/table\-remote\-info format +\- format of table_data in table\-info/table\-remote\-info format +\- instruction size: each bundle is counted as 3 instructions, regardless +of template (MLX) +\- describe stack\-frame layout, especially with regards to sp\-relative +and fp\-relative addressing +\- UNW_DYN_ADD can only add to ``sp\&'' (always a negative value); use +POP_FRAMES otherwise .PP .SH SEE ALSO .PP -libunwind(3), -_U_dyn_register(3), -_U_dyn_cancel(3) +libunwind(3libunwind), +_U_dyn_register(3libunwind), +_U_dyn_cancel(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/libunwind-dynamic.tex b/src/native/external/libunwind/doc/libunwind-dynamic.tex index a3b7762b247157..85af41f5007f95 100644 --- a/src/native/external/libunwind/doc/libunwind-dynamic.tex +++ b/src/native/external/libunwind/doc/libunwind-dynamic.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{libunwind-dynamic}{David Mosberger-Tang}{Programming Library}{Introduction to dynamic unwind-info}libunwind-dynamic -- libunwind-support for runtime-generated code +\begin{Name}{3libunwind}{libunwind-dynamic}{David Mosberger-Tang}{Programming Library}{Introduction to dynamic unwind-info}libunwind-dynamic -- libunwind-support for runtime-generated code \end{Name} \section{Introduction} @@ -124,7 +124,7 @@ \section{Procedures} \subsection{Proc-info format} This is the preferred dynamic unwind-info format and it is generally -the one used by full-blown runtime code-generators. In this format, +the one used by full-blown runtime code generators. In this format, the details of a procedure are described by a structure of type \Type{unw\_dyn\_proc\_info\_t}. This structure contains the following members: @@ -133,12 +133,12 @@ \subsection{Proc-info format} \item[\Type{unw\_word\_t} \Var{name\_ptr}] The address of a (human-readable) name of the procedure or 0 if no such name is available. If non-zero, the string stored at this address must be - ASCII NUL terminated. For source languages that use name-mangling + ASCII NUL terminated. For source languages that use name mangling (such as C++ or Java) the string stored at this address should be the \emph{demangled} version of the name. \item[\Type{unw\_word\_t} \Var{handler}] The address of the - personality-routine for this procedure. Personality-routines are + personality routine for this procedure. Personality routines are used in conjunction with exception handling. See the C++ ABI draft (http://www.codesourcery.com/cxx-abi/) for an overview and a description of the personality routine. If the procedure has no @@ -149,7 +149,7 @@ \subsection{Proc-info format} set to 0. \item[\Type{unw\_dyn\_region\_info\_t~*}\Var{regions}] A NULL-terminated - linked list of region-descriptors. See section ``Region + linked list of region descriptors. See section ``Region descriptors'' below for more details. \end{description} @@ -183,7 +183,7 @@ \subsection{Table-info format} (\Type{unw\_word\_t}). \item[\Type{unw\_word\_t} \Var{table\_data}] A pointer to the actual - data encoding the unwind-info. The exact format is + data encoding the unwind info. The exact format is architecture-specific (see architecture-specific sections below). \end{description} @@ -199,13 +199,13 @@ \subsection{Remote table-info format} via the address-space's \Func{access\_mem}() call-back, rather than through a direct memory reference. -From the point of view of a runtime-code generator, the remote +From the point of view of a runtime code generator, the remote table-info format offers no advantage and it is expected that such generators will describe their procedures either with the proc-info format or the normal table-info format. The main reason that the remote table-info format exists is to enable the address-space-specific \Func{find\_proc\_info}() callback (see -\SeeAlso{unw\_create\_addr\_space}(3)) to return unwind tables whose +\SeeAlso{unw\_create\_addr\_space}(3libunwind)) to return unwind tables whose data remains in remote memory. This can speed up unwinding (e.g., for a debugger) because it reduces the amount of data that needs to be loaded from remote memory. @@ -386,9 +386,9 @@ \section{IA-64 specifics} \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{\_U\_dyn\_register(3)}, -\SeeAlso{\_U\_dyn\_cancel(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{\_U\_dyn\_register}(3libunwind), +\SeeAlso{\_U\_dyn\_cancel}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/libunwind-ia64.man b/src/native/external/libunwind/doc/libunwind-ia64.man index 06b141eb3e2b70..6441e4dd5e420f 100644 --- a/src/native/external/libunwind/doc/libunwind-ia64.man +++ b/src/native/external/libunwind/doc/libunwind-ia64.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "LIBUNWIND\-IA64" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "LIBUNWIND\-IA64" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME libunwind\-ia64 \-\- IA\-64\-specific support in libunwind @@ -301,7 +303,7 @@ portable code should not rely on this equivalence. .SH SEE ALSO .PP -libunwind(3) +libunwind(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/libunwind-ia64.tex b/src/native/external/libunwind/doc/libunwind-ia64.tex index c08946dc4b327d..76a688a980ad9b 100644 --- a/src/native/external/libunwind/doc/libunwind-ia64.tex +++ b/src/native/external/libunwind/doc/libunwind-ia64.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{libunwind-ia64}{David Mosberger-Tang}{Programming Library}{IA-64-specific support in libunwind}libunwind-ia64 -- IA-64-specific support in libunwind +\begin{Name}{3libunwind}{libunwind-ia64}{David Mosberger-Tang}{Programming Library}{IA-64-specific support in libunwind}libunwind-ia64 -- IA-64-specific support in libunwind \end{Name} @@ -203,7 +203,7 @@ \section{The Unwind-Context Type} \section{See Also} -\SeeAlso{libunwind(3)} +\SeeAlso{libunwind}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/libunwind-nto.man b/src/native/external/libunwind/doc/libunwind-nto.man new file mode 100644 index 00000000000000..8b105cfaf90735 --- /dev/null +++ b/src/native/external/libunwind/doc/libunwind-nto.man @@ -0,0 +1,256 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} +'\" t +.\" Manual page created with latex2man on Tue Aug 29 10:53:41 2023 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "LIBUNWIND\-NTO" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " +.SH NAME +libunwind\-nto +\-\- QNX Neutrino support in libunwind +.SH SYNOPSIS + +.PP +#include +.br +.PP +unw_accessors_t +unw_nto_accessors; +.br +.PP +void *unw_nto_create(pid_t, +pthread_t); +.br +void unw_nto_destroy(void *); +.br +.PP +int +unw_nto_find_proc_info(unw_addr_space_t, +unw_word_t, +unw_proc_info_t *, +int, +void *); +.br +void +unw_nto_put_unwind_info(unw_addr_space_t, +unw_proc_info_t *, +void *); +.br +int +unw_nto_get_dyn_info_list_addr(unw_addr_space_t, +unw_word_t *, +void *); +.br +int +unw_nto_access_mem(unw_addr_space_t, +unw_word_t, +unw_word_t *, +int, +void *); +.br +int +unw_nto_access_reg(unw_addr_space_t, +unw_regnum_t, +unw_word_t *, +int, +void *); +.br +int +unw_nto_access_fpreg(unw_addr_space_t, +unw_regnum_t, +unw_fpreg_t *, +int, +void *); +.br +int +unw_nto_get_proc_name(unw_addr_space_t, +unw_word_t, +char *, +size_t, +unw_word_t *, +void *); +.br +int +unw_nto_resume(unw_addr_space_t, +unw_cursor_t *, +void *); +.br +.PP +.SH DESCRIPTION + +.PP +The QNX operating system makes it possible for a process to +gain access to the machine state and virtual memory of \fIanother\fP +process, or a different thread within the same process. +gain access to the machine state and virtual memory of \fIanother\fP +it is possible to hook up libunwind +to another process. +While it\&'s not very difficult to do so directly, +libunwind +further facilitates this task by providing +ready\-to\-use callbacks for this purpose. +The routines and variables +implementing this facility use a name prefix of unw_nto, +which is stands for ``unwind\-via\-nto\&''\&. +.PP +An application that wants to use the libunwind +NTO remote needs +to take the following steps. +.PP +.TP +1. +Create a new libunwind address\-space that represents the target +process and thread. This is done by calling +unw_create_addr_space(). +In many cases, the application will +simply want to pass the address of unw_nto_accessors +as the +first argument to this routine. Doing so will ensure that +libunwind +will be able to properly unwind the target process. +.PP +.TP +2. +Create an NTO info structure by calling unw_nto_create(), +passing the pid and tid of the target process thread as the arguments. +This will stop the target thread. The process ID (pid) of the target +process must be known, and only a single thread can be unwound at a time +so the thread ID (tid) must also be specified. +.PP +.TP +3. +The opaque pointer returned then needs to be passed as the +``argument\&'' pointer (third argument) to unw_init_remote(). +.PP +When the application is done using libunwind +on the target process, +unw_nto_destroy() +needs to be called, passing it the opaque pointer +that was returned by the call to unw_nto_create(). +This ensures that +all memory and other resources are freed up. +.PP +The unw_nto_resume() +is not supported on the NTO remote. +.PP +In special circumstances, an application may prefer to use +only portions of the libunwind +NTO remote. For this reason, the +individual callback routines (unw_nto_find_proc_info(), +unw_nto_put_unwind_info(), +etc.) are also available for direct +use. Of course, the addresses of these routines could also be picked +up from unw_nto_accessors, +but doing so would prevent static +initialization. Also, when using unw_nto_accessors, +\fIall\fP +the callback routines will be linked into the application, even if +they are never actually called. +.PP +.SH THREAD SAFETY + +.PP +The libunwind +NTO remote assumes that a single unw_nto\-info +structure is never shared between threads of the unwinding program. +Because of this, +no explicit locking is used. +As long as only one thread uses an NTO info structure at any given time, +this facility is thread\-safe. +.PP +.SH RETURN VALUE + +.PP +unw_nto_create() +may return a NULL if it fails +to create the NTO info structure for any reason. +.PP +.SH FILES + +.PP +.TP +libunwind\-nto.h + Headerfile to include when using the +interface defined by this library. +.TP +\fB\-l\fPunwind\-nto \fB\-l\fPunwind\-generic + Linker\-switches to add when building a program that uses the +functions defined by this library. +.PP +.SH EXAMPLE + +.Vb + #include + #include + #include + + int + main (int argc, char **argv) + { + if (argc != 2) { + fprintf (stderr, "usage: %s PID\\n", argv[0]); + exit (EXIT_FAILURE); + } + + char *endptr; + pid_t target_pid = strtoul (argv[1], &endptr, 10); + if (target_pid == 0 && argv[1] == endptr) { + fprintf (stderr, "usage: %s PID\\n", argv[0]); + exit (EXIT_FAILURE); + } + + unw_addr_space_t as = unw_create_addr_space (&unw_nto_accessors, 0); + if (!as) { + fprintf (stderr, "unw_create_addr_space() failed"); + exit (EXIT_FAILURE); + } + + void *ui = unw_nto_create (target_pid, (thread_t)1); + if (!ui) { + fprintf (stderr, "unw_nto_create() failed"); + exit (EXIT_FAILURE); + } + + unw_cursor_t cursor; + int ret = unw_init_remote (&cursor, as, ui); + if (ret < 0) { + fprintf (stderr, "unw_init_remote() failed: ret=%d\\n", ret); + exit (EXIT_FAILURE); + } + + do { + unw_proc_info_t pi; + ret = unw_get_proc_info (&cursor, &pi); + if (ret == \-UNW_ENOINFO) { + fprintf (stdout, "no info\\n"); + } else if (ret >= 0) { + printf ("\\tproc=%#016lx\-%#016lx\\thandler=%#016lx lsda=%#016lx", + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda); + } + ret = unw_step (&cursor); + } while (ret > 0); + if (ret < 0) { + fprintf (stderr, "unwind failed with ret=%d\\n", ret); + exit (EXIT_FAILURE); + } + + unw_nto_destroy (ui); + unw_destroy_addr_space (as); + exit (EXIT_SUCCESS); + } +.Ve +.PP +.SH SEE ALSO + +libunwind(3libunwind) +.PP +.\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/native/external/libunwind/doc/libunwind-nto.tex b/src/native/external/libunwind/doc/libunwind-nto.tex new file mode 100644 index 00000000000000..74c59912cb7d9a --- /dev/null +++ b/src/native/external/libunwind/doc/libunwind-nto.tex @@ -0,0 +1,183 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3libunwind}{libunwind-nto}{Blackberry}{Programming Library}{QNX Neutrino remote for libunwind}libunwind-nto -- QNX Neutrino support in libunwind +\end{Name} +\section{Synopsis} + +\File{\#include $<$libunwind-nto.h$>$}\\ + +\noindent +\Type{unw\_accessors\_t} \Var{unw\_nto\_accessors};\\ + +\Type{void~*}\Func{unw\_nto\_create}(\Type{pid\_t}, \Type{pthread\_t});\\ +\noindent +\Type{void}~\Func{unw\_nto\_destroy}(\Type{void~*});\\ + +\noindent +\Type{int} \Func{unw\_nto\_find\_proc\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_proc\_info\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{void} \Func{unw\_nto\_put\_unwind\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_proc\_info\_t~*}, \Type{void~*});\\ +\noindent +\Type{int} \Func{unw\_nto\_get\_dyn\_info\_list\_addr}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ +\noindent +\Type{int} \Func{unw\_nto\_access\_mem}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{int} \Func{unw\_nto\_access\_reg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{int} \Func{unw\_nto\_access\_fpreg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*}, \Type{int}, \Type{void~*});\\ +\noindent +\Type{int} \Func{unw\_nto\_get\_proc\_name}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ +\noindent +\Type{int} \Func{unw\_nto\_resume}(\Type{unw\_addr\_space\_t}, \Type{unw\_cursor\_t~*}, \Type{void~*});\\ + +\section{Description} + +The QNX operating system makes it possible for a process to +gain access to the machine state and virtual memory of \emph{another} +process, or a different thread within the same process. +gain access to the machine state and virtual memory of \emph{another} +it is possible to hook up \Prog{libunwind} to another process. +While it's not very difficult to do so directly, +\Prog{libunwind} further facilitates this task by providing +ready-to-use callbacks for this purpose. +The routines and variables +implementing this facility use a name prefix of \Func{unw\_nto}, +which is stands for ``unwind-via-nto''. + +An application that wants to use the \Prog{libunwind} NTO remote needs +to take the following steps. +\begin{enumerate} + + \item Create a new \Prog{libunwind} address-space that represents the target + process and thread. This is done by calling + \Func{unw\_create\_addr\_space}(). In many cases, the application will + simply want to pass the address of \Var{unw\_nto\_accessors} as the + first argument to this routine. Doing so will ensure that + \Prog{libunwind} will be able to properly unwind the target process. + + \item Create an NTO info structure by calling \Func{unw\_nto\_create}(), + passing the pid and tid of the target process thread as the arguments. + This will stop the target thread. The process ID (pid) of the target + process must be known, and only a single thread can be unwound at a time + so the thread ID (tid) must also be specified. + + \item The opaque pointer returned then needs to be passed as the + ``argument'' pointer (third argument) to \Func{unw\_init\_remote}(). + +\end{enumerate} + +When the application is done using \Prog{libunwind} on the target process, +\Func{unw\_nto\_destroy}() needs to be called, passing it the opaque pointer +that was returned by the call to \Func{unw\_nto\_create}(). This ensures that +all memory and other resources are freed up. + +The \Func{unw\_nto\_resume}() is not supported on the NTO remote. + +In special circumstances, an application may prefer to use +only portions of the \Prog{libunwind} NTO remote. For this reason, the +individual callback routines (\Func{unw\_nto\_find\_proc\_info}(), +\Func{unw\_nto\_put\_unwind\_info}(), etc.) are also available for direct +use. Of course, the addresses of these routines could also be picked +up from \Var{unw\_nto\_accessors}, but doing so would prevent static +initialization. Also, when using \Var{unw\_nto\_accessors}, \emph{all} +the callback routines will be linked into the application, even if +they are never actually called. + +\section{Thread Safety} + +The \Prog{libunwind} NTO remote assumes that a single \Prog{unw\_nto}-info +structure is never shared between threads of the unwinding program. +Because of this, +no explicit locking is used. +As long as only one thread uses an NTO info structure at any given time, +this facility is thread-safe. + +\section{Return Value} + +\Func{unw\_nto\_create}() may return a NULL if it fails +to create the NTO info structure for any reason. + +\section{Files} + +\begin{Description} +\item[\File{libunwind-nto.h}] Headerfile to include when using the + interface defined by this library. +\item[\Opt{-l}\File{unwind-nto} \Opt{-l}\File{unwind-generic}] + Linker-switches to add when building a program that uses the + functions defined by this library. +\end{Description} + +\section{Example} +\begin{verbatim} + #include + #include + #include + + int + main (int argc, char **argv) + { + if (argc != 2) { + fprintf (stderr, "usage: %s PID\n", argv[0]); + exit (EXIT_FAILURE); + } + + char *endptr; + pid_t target_pid = strtoul (argv[1], &endptr, 10); + if (target_pid == 0 && argv[1] == endptr) { + fprintf (stderr, "usage: %s PID\n", argv[0]); + exit (EXIT_FAILURE); + } + + unw_addr_space_t as = unw_create_addr_space (&unw_nto_accessors, 0); + if (!as) { + fprintf (stderr, "unw_create_addr_space() failed"); + exit (EXIT_FAILURE); + } + + void *ui = unw_nto_create (target_pid, (thread_t)1); + if (!ui) { + fprintf (stderr, "unw_nto_create() failed"); + exit (EXIT_FAILURE); + } + + unw_cursor_t cursor; + int ret = unw_init_remote (&cursor, as, ui); + if (ret < 0) { + fprintf (stderr, "unw_init_remote() failed: ret=%d\n", ret); + exit (EXIT_FAILURE); + } + + do { + unw_proc_info_t pi; + ret = unw_get_proc_info (&cursor, &pi); + if (ret == -UNW_ENOINFO) { + fprintf (stdout, "no info\n"); + } else if (ret >= 0) { + printf ("\tproc=%#016lx-%#016lx\thandler=%#016lx lsda=%#016lx", + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda); + } + ret = unw_step (&cursor); + } while (ret > 0); + if (ret < 0) { + fprintf (stderr, "unwind failed with ret=%d\n", ret); + exit (EXIT_FAILURE); + } + + unw_nto_destroy (ui); + unw_destroy_addr_space (as); + exit (EXIT_SUCCESS); + } +\end{verbatim} + +\section{See Also} +\SeeAlso{libunwind}(3libunwind) + +\LatexManEnd + +\end{document} diff --git a/src/native/external/libunwind/doc/libunwind-ptrace.man b/src/native/external/libunwind/doc/libunwind-ptrace.man index 985fcae275333c..415d972206a439 100644 --- a/src/native/external/libunwind/doc/libunwind-ptrace.man +++ b/src/native/external/libunwind/doc/libunwind-ptrace.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 10:53:41 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,10 +12,10 @@ .fi .. -.TH "LIBUNWIND\-PTRACE" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "LIBUNWIND\-PTRACE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME libunwind\-ptrace -\-\- ptrace() support in libunwind +\-\- ptrace() support in libunwind .PP .SH SYNOPSIS @@ -27,58 +29,49 @@ _UPT_accessors; .PP void *_UPT_create(pid_t); .br -void -_UPT_destroy(void *); +void _UPT_destroy(void *); .br .PP -int -_UPT_find_proc_info(unw_addr_space_t, +int _UPT_find_proc_info(unw_addr_space_t, unw_word_t, unw_proc_info_t *, int, void *); .br -void -_UPT_put_unwind_info(unw_addr_space_t, +void _UPT_put_unwind_info(unw_addr_space_t, unw_proc_info_t *, void *); .br -int -_UPT_get_dyn_info_list_addr(unw_addr_space_t, +int _UPT_get_dyn_info_list_addr(unw_addr_space_t, unw_word_t *, void *); .br -int -_UPT_access_mem(unw_addr_space_t, +int _UPT_access_mem(unw_addr_space_t, unw_word_t, unw_word_t *, int, void *); .br -int -_UPT_access_reg(unw_addr_space_t, +int _UPT_access_reg(unw_addr_space_t, unw_regnum_t, unw_word_t *, int, void *); .br -int -_UPT_access_fpreg(unw_addr_space_t, +int _UPT_access_fpreg(unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, int, void *); .br -int -_UPT_get_proc_name(unw_addr_space_t, +int _UPT_get_proc_name(unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *); .br -int -_UPT_resume(unw_addr_space_t, +int _UPT_resume(unw_addr_space_t, unw_cursor_t *, void *); .br @@ -87,9 +80,9 @@ void *); .PP The ptrace(2) -system\-call makes it possible for a process to -gain access to the machine\-state and virtual memory of \fIanother\fP -process. With the right set of call\-back routines, it is therefore +system call makes it possible for a process to +gain access to the machine state and virtual memory of \fIanother\fP +process. With the right set of callback routines, it is therefore possible to hook up libunwind to another process via ptrace(2). @@ -97,117 +90,185 @@ While it\&'s not very difficult to do so directly, libunwind further facilitates this task by providing ready\-to\-use callbacks for this purpose. The routines and variables -implementing this facility use a name\-prefix of _UPT, +implementing this facility use a name prefix of _UPT, which is -stands for ``unwind\-via\-ptrace\&''\&. -.PP -An application that wants to use the _UPT\-facility -first needs -to create a new libunwind -address\-space that represents the -target process. This is done by calling -unw_create_addr_space(). -In many cases, the application -will simply want to pass the address of _UPT_accessors -as the -first argument to this routine. Doing so will ensure that -libunwind -will be able to properly unwind the target process. -However, in special circumstances, an application may prefer to use -only portions of the _UPT\-facility. -For this reason, the -individual callback routines (_UPT_find_proc_info(), +stands for ``unwind via ptrace\&''\&. +.PP +An application that wants to use the libunwind +ptrace remote needs to +take the folowing steps. +.PP +.TP +1. +Create a new libunwind address space that represents the target +process. This is done by calling unw_create_addr_space(). +In +many cases, the application will simply want to pass the address of +_UPT_accessors +as the first argument to this routine. Doing so +will ensure that libunwind +will be able to properly unwind the +target process. +.PP +.TP +2. +Turn on ptrace mode on the target process, either by forking a new +process, invoking PTRACE_TRACEME, +and then starting the target +program (via execve(2)), +or by directly attaching to an already +running process (via PTRACE_ATTACH). +.PP +.TP +3. +Once the process\-ID (pid) of the target process is known, a +UPT info structure can be created by calling +_UPT_create(), +passing the pid of the target process as the +only argument. +.PP +.TP +4. +The opaque pointer returned then needs to be passed as the +``argument\&'' pointer (third argument) to unw_init_remote(). +.PP +In special circumstances, an application may prefer to use only +portions of the libunwind +ptrace remote. For this reason, the individual +callback routines (_UPT_find_proc_info(), _UPT_put_unwind_info(), -etc.) are also available for direct -use. Of course, the addresses of these routines could also be picked -up from _UPT_accessors, -but doing so would prevent static -initialization. Also, when using _UPT_accessors, +etc.) are also available for direct use. Of +course, the addresses of these routines could also be picked up from +_UPT_accessors, +but doing so would prevent static initialization. Also, +when using _UPT_accessors, \fIall\fP -the callback routines will be linked into the application, even if -they are never actually called. -.PP -Next, the application can turn on ptrace\-mode on the target process, -either by forking a new process, invoking PTRACE_TRACEME, -and -then starting the target program (via execve(2)), -or by -directly attaching to an already running process (via -PTRACE_ATTACH). -Either way, once the process\-ID (pid) of the -target process is known, a _UPT\-info\-structure -can be created -by calling _UPT_create(), -passing the pid of the target process -as the only argument. The returned void\-pointer then needs to be -passed as the ``argument\&'' pointer (third argument) to -unw_init_remote(). +the callback routines will be +linked into the application, even if they are never actually called. .PP The _UPT_resume() -routine can be used to resume execution of -the target process. It simply invokes ptrace(2) -with a command -value of PTRACE_CONT\&. +routine can be used to resume execution of the target +process. It simply invokes ptrace(2) +with a command value of +PTRACE_CONT\&. .PP When the application is done using libunwind -on the target -process, _UPT_destroy() -needs to be called, passing it the -void\-pointer that was returned by the corresponding call to -_UPT_create(). -This ensures that all memory and other -resources are freed up. +on the target process, +_UPT_destroy() +needs to be called, passing it the opaque pointer that +was returned by the call to _UPT_create(). +This ensures that all +memory and other resources are freed up. .PP .SH AVAILABILITY .PP Since ptrace(2) -works within a single machine only, the -_UPT\-facility -by definition is not available in -libunwind\-versions -configured for cross\-unwinding. +works within a single machine only, the libunwind ptrace +remote by definition is not available in libunwind +versions configured +for cross\-unwinding. .PP .SH THREAD SAFETY .PP -The _UPT\-facility -assumes that a single _UPT\-info -structure is never shared between threads. Because of this, no -explicit locking is used. As long as only one thread uses -a _UPT\-info -structure at any given time, this facility -is thread\-safe. +The libunwind +ptrace remote assumes that a single UPT info structure is +never shared between threads. Because of this, no explicit locking is used. As +long as only one thread uses a UPT info structure at any given time, this +facility is thread\-safe. .PP .SH RETURN VALUE .PP _UPT_create() may return a NULL -pointer if it fails -to create the _UPT\-info\-structure -for any reason. For the -current implementation, the only reason this call may fail is when the -system is out of memory. +pointer if it fails to create +the UPT info structure for any reason. For the current implementation, the only +reason this call may fail is when the system is out of memory. .PP .SH FILES .PP .TP libunwind\-ptrace.h - Headerfile to include when using the + Header file to include when using the interface defined by this library. .TP \fB\-l\fPunwind\-ptrace \fB\-l\fPunwind\-generic - Linker\-switches to add when building a program that uses the + Linker switches to add when building a program that uses the functions defined by this library. .PP +.SH EXAMPLE + +.Vb + #include + #include + #include + + int + main (int argc, char **argv) + { + if (argc != 2) { + fprintf (stderr, "usage: %s PID\\n", argv[0]); + exit (EXIT_FAILURE); + } + + char *endptr; + pid_t target_pid = strtoul (argv[1], &endptr, 10); + if (target_pid == 0 && argv[1] == endptr) { + fprintf (stderr, "usage: %s PID\\n", argv[0]); + exit (EXIT_FAILURE); + } + + unw_addr_space_t as = unw_create_addr_space (&_UPT_accessors, 0); + if (!as) { + fprintf (stderr, "unw_create_addr_space() failed"); + exit (EXIT_FAILURE); + } + + void *ui = _UPT_create (target_pid); + if (!ui) { + fprintf (stderr, "_UPT_create() failed"); + exit (EXIT_FAILURE); + } + + unw_cursor_t cursor; + int ret = unw_init_remote (&cursor, as, ui); + if (ret < 0) { + fprintf (stderr, "unw_init_remote() failed: ret=%d\\n", ret); + exit (EXIT_FAILURE); + } + + do { + unw_proc_info_t pi; + ret = unw_get_proc_info (&cursor, &pi); + if (ret == \-UNW_ENOINFO) { + fprintf (stdout, "no info\\n"); + } else if (ret >= 0) { + printf ("\\tproc=%#016lx\-%#016lx\\thandler=%#016lx lsda=%#016lx", + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda); + } + ret = unw_step (&cursor); + } while (ret > 0); + if (ret < 0) { + fprintf (stderr, "unwind failed with ret=%d\\n", ret); + exit (EXIT_FAILURE); + } + + _UPT_destroy (ui); + unw_destroy_addr_space (as); + exit (EXIT_SUCCESS); + } +.Ve +.PP .SH SEE ALSO .PP -execve(2), -libunwind(3), -ptrace(2) +execve(2), +libunwind(3libunwind), +ptrace(2) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/libunwind-ptrace.tex b/src/native/external/libunwind/doc/libunwind-ptrace.tex index fe074d8619174a..513314aa6acb46 100644 --- a/src/native/external/libunwind/doc/libunwind-ptrace.tex +++ b/src/native/external/libunwind/doc/libunwind-ptrace.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{libunwind-ptrace}{David Mosberger-Tang}{Programming Library}{ptrace() support in libunwind}libunwind-ptrace -- ptrace() support in libunwind +\begin{Name}{3libunwind}{libunwind-ptrace}{David Mosberger-Tang}{Programming Library}{ptrace() support in \Prog{libunwind}libunwind-ptrace -- ptrace() support in \Prog{libunwind} \end{Name} \section{Synopsis} @@ -17,111 +17,178 @@ \section{Synopsis} \Type{void~*}\Func{\_UPT\_create}(\Type{pid\_t});\\ \noindent -\Type{void} \Func{\_UPT\_destroy}(\Type{void~*});\\ +\Type{void}~\Func{\_UPT\_destroy}(\Type{void~*});\\ \noindent -\Type{int} \Func{\_UPT\_find\_proc\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_proc\_info\_t~*}, \Type{int}, \Type{void~*});\\ +\Type{int}~\Func{\_UPT\_find\_proc\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_proc\_info\_t~*}, \Type{int}, \Type{void~*});\\ \noindent -\Type{void} \Func{\_UPT\_put\_unwind\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_proc\_info\_t~*}, \Type{void~*});\\ +\Type{void}~\Func{\_UPT\_put\_unwind\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_proc\_info\_t~*}, \Type{void~*});\\ \noindent -\Type{int} \Func{\_UPT\_get\_dyn\_info\_list\_addr}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ +\Type{int}~\Func{\_UPT\_get\_dyn\_info\_list\_addr}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ \noindent -\Type{int} \Func{\_UPT\_access\_mem}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ +\Type{int}~\Func{\_UPT\_access\_mem}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ \noindent -\Type{int} \Func{\_UPT\_access\_reg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ +\Type{int}~\Func{\_UPT\_access\_reg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\ \noindent -\Type{int} \Func{\_UPT\_access\_fpreg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*}, \Type{int}, \Type{void~*});\\ +\Type{int}~\Func{\_UPT\_access\_fpreg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*}, \Type{int}, \Type{void~*});\\ \noindent -\Type{int} \Func{\_UPT\_get\_proc\_name}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ +\Type{int}~\Func{\_UPT\_get\_proc\_name}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\ \noindent -\Type{int} \Func{\_UPT\_resume}(\Type{unw\_addr\_space\_t}, \Type{unw\_cursor\_t~*}, \Type{void~*});\\ +\Type{int}~\Func{\_UPT\_resume}(\Type{unw\_addr\_space\_t}, \Type{unw\_cursor\_t~*}, \Type{void~*});\\ \section{Description} -The \Func{ptrace}(2) system-call makes it possible for a process to -gain access to the machine-state and virtual memory of \emph{another} -process. With the right set of call-back routines, it is therefore +The \Func{ptrace}(2) system call makes it possible for a process to +gain access to the machine state and virtual memory of \emph{another} +process. With the right set of callback routines, it is therefore possible to hook up \Prog{libunwind} to another process via \Func{ptrace}(2). While it's not very difficult to do so directly, \Prog{libunwind} further facilitates this task by providing ready-to-use callbacks for this purpose. The routines and variables -implementing this facility use a name-prefix of \Func{\_UPT}, which is -stands for ``unwind-via-ptrace''. - -An application that wants to use the \Func{\_UPT}-facility first needs -to create a new \Prog{libunwind} address-space that represents the -target process. This is done by calling -\Func{unw\_create\_addr\_space}(). In many cases, the application -will simply want to pass the address of \Var{\_UPT\_accessors} as the -first argument to this routine. Doing so will ensure that -\Prog{libunwind} will be able to properly unwind the target process. -However, in special circumstances, an application may prefer to use -only portions of the \Prog{\_UPT}-facility. For this reason, the -individual callback routines (\Func{\_UPT\_find\_proc\_info}(), -\Func{\_UPT\_put\_unwind\_info}(), etc.) are also available for direct -use. Of course, the addresses of these routines could also be picked -up from \Var{\_UPT\_accessors}, but doing so would prevent static -initialization. Also, when using \Var{\_UPT\_accessors}, \emph{all} -the callback routines will be linked into the application, even if -they are never actually called. - -Next, the application can turn on ptrace-mode on the target process, -either by forking a new process, invoking \Const{PTRACE\_TRACEME}, and -then starting the target program (via \Func{execve}(2)), or by -directly attaching to an already running process (via -\Const{PTRACE\_ATTACH}). Either way, once the process-ID (pid) of the -target process is known, a \Prog{\_UPT}-info-structure can be created -by calling \Func{\_UPT\_create}(), passing the pid of the target process -as the only argument. The returned void-pointer then needs to be -passed as the ``argument'' pointer (third argument) to -\Func{unw\_init\_remote}(). - -The \Func{\_UPT\_resume}() routine can be used to resume execution of -the target process. It simply invokes \Func{ptrace}(2) with a command -value of \Const{PTRACE\_CONT}. - -When the application is done using \Prog{libunwind} on the target -process, \Func{\_UPT\_destroy}() needs to be called, passing it the -void-pointer that was returned by the corresponding call to -\Func{\_UPT\_create}(). This ensures that all memory and other -resources are freed up. +implementing this facility use a name prefix of \Func{\_UPT}, which is +stands for ``unwind via ptrace''. + +An application that wants to use the \Prog{libunwind} ptrace remote needs to +take the folowing steps. +\begin{enumerate} + + \item Create a new \Prog{libunwind} address space that represents the target + process. This is done by calling \Func{unw\_create\_addr\_space}(). In + many cases, the application will simply want to pass the address of + \Var{\_UPT\_accessors} as the first argument to this routine. Doing so + will ensure that \Prog{libunwind} will be able to properly unwind the + target process. + + \item Turn on ptrace mode on the target process, either by forking a new + process, invoking \Const{PTRACE\_TRACEME}, and then starting the target + program (via \Func{execve}(2)), or by directly attaching to an already + running process (via \Const{PTRACE\_ATTACH}). + + \item Once the process-ID (pid) of the target process is known, a + UPT info structure can be created by calling + \Func{\_UPT\_create}(), passing the pid of the target process as the + only argument. + + \item The opaque pointer returned then needs to be passed as the + ``argument'' pointer (third argument) to \Func{unw\_init\_remote}(). + +\end{enumerate} + +In special circumstances, an application may prefer to use only +portions of the \Prog{libunwind} ptrace remote. For this reason, the individual +callback routines (\Func{\_UPT\_find\_proc\_info}(), +\Func{\_UPT\_put\_unwind\_info}(), etc.) are also available for direct use. Of +course, the addresses of these routines could also be picked up from +\Var{\_UPT\_accessors}, but doing so would prevent static initialization. Also, +when using \Var{\_UPT\_accessors}, \emph{all} the callback routines will be +linked into the application, even if they are never actually called. + +The \Func{\_UPT\_resume}() routine can be used to resume execution of the target +process. It simply invokes \Func{ptrace}(2) with a command value of +\Const{PTRACE\_CONT}. + +When the application is done using \Prog{libunwind} on the target process, +\Func{\_UPT\_destroy}() needs to be called, passing it the opaque pointer that +was returned by the call to \Func{\_UPT\_create}(). This ensures that all +memory and other resources are freed up. \section{Availability} -Since \Func{ptrace}(2) works within a single machine only, the -\Prog{\_UPT}-facility by definition is not available in -\Prog{libunwind}-versions configured for cross-unwinding. +Since \Func{ptrace}(2) works within a single machine only, the libunwind ptrace +remote by definition is not available in \Prog{libunwind} versions configured +for cross-unwinding. \section{Thread Safety} -The \Prog{\_UPT}-facility assumes that a single \Prog{\_UPT}-info -structure is never shared between threads. Because of this, no -explicit locking is used. As long as only one thread uses -a \Prog{\_UPT}-info structure at any given time, this facility -is thread-safe. +The \Prog{libunwind} ptrace remote assumes that a single UPT info structure is +never shared between threads. Because of this, no explicit locking is used. As +long as only one thread uses a UPT info structure at any given time, this +facility is thread-safe. \section{Return Value} -\Func{\_UPT\_create}() may return a \Const{NULL} pointer if it fails -to create the \Prog{\_UPT}-info-structure for any reason. For the -current implementation, the only reason this call may fail is when the -system is out of memory. +\Func{\_UPT\_create}() may return a \Const{NULL} pointer if it fails to create +the UPT info structure for any reason. For the current implementation, the only +reason this call may fail is when the system is out of memory. \section{Files} \begin{Description} -\item[\File{libunwind-ptrace.h}] Headerfile to include when using the - interface defined by this library. +\item[\File{libunwind-ptrace.h}] Header file to include when using the + interface defined by this library. \item[\Opt{-l}\File{unwind-ptrace} \Opt{-l}\File{unwind-generic}] - Linker-switches to add when building a program that uses the + Linker switches to add when building a program that uses the functions defined by this library. \end{Description} +\section{Example} +\begin{verbatim} + #include + #include + #include + + int + main (int argc, char **argv) + { + if (argc != 2) { + fprintf (stderr, "usage: %s PID\n", argv[0]); + exit (EXIT_FAILURE); + } + + char *endptr; + pid_t target_pid = strtoul (argv[1], &endptr, 10); + if (target_pid == 0 && argv[1] == endptr) { + fprintf (stderr, "usage: %s PID\n", argv[0]); + exit (EXIT_FAILURE); + } + + unw_addr_space_t as = unw_create_addr_space (&_UPT_accessors, 0); + if (!as) { + fprintf (stderr, "unw_create_addr_space() failed"); + exit (EXIT_FAILURE); + } + + void *ui = _UPT_create (target_pid); + if (!ui) { + fprintf (stderr, "_UPT_create() failed"); + exit (EXIT_FAILURE); + } + + unw_cursor_t cursor; + int ret = unw_init_remote (&cursor, as, ui); + if (ret < 0) { + fprintf (stderr, "unw_init_remote() failed: ret=%d\n", ret); + exit (EXIT_FAILURE); + } + + do { + unw_proc_info_t pi; + ret = unw_get_proc_info (&cursor, &pi); + if (ret == -UNW_ENOINFO) { + fprintf (stdout, "no info\n"); + } else if (ret >= 0) { + printf ("\tproc=%#016lx-%#016lx\thandler=%#016lx lsda=%#016lx", + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda); + } + ret = unw_step (&cursor); + } while (ret > 0); + if (ret < 0) { + fprintf (stderr, "unwind failed with ret=%d\n", ret); + exit (EXIT_FAILURE); + } + + _UPT_destroy (ui); + unw_destroy_addr_space (as); + exit (EXIT_SUCCESS); + } +\end{verbatim} + \section{See Also} -execve(2), -\SeeAlso{libunwind(3)}, -ptrace(2) +\SeeAlso{execve}(2), +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{ptrace}(2) \section{Author} diff --git a/src/native/external/libunwind/doc/libunwind-setjmp.man b/src/native/external/libunwind/doc/libunwind-setjmp.man index 1faa38e475ddba..2fd4480867f5a0 100644 --- a/src/native/external/libunwind/doc/libunwind-setjmp.man +++ b/src/native/external/libunwind/doc/libunwind-setjmp.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 10:53:41 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "LIBUNWIND\-SETJMP" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "LIBUNWIND\-SETJMP" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME libunwind\-setjmp \-\- libunwind\-based non\-local gotos @@ -115,11 +117,13 @@ goto routines. .PP .SH SEE ALSO -.PP -libunwind(3), -setjmp(3), longjmp(3), -_setjmp(3), _longjmp(3), -sigsetjmp(3), siglongjmp(3) +libunwind(3libunwind), +setjmp(3), +longjmp(3), +_setjmp(3), +_longjmp(3), +sigsetjmp(3), +siglongjmp(3) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/libunwind-setjmp.tex b/src/native/external/libunwind/doc/libunwind-setjmp.tex index 17ce073186a6c3..2dc9575f80378a 100644 --- a/src/native/external/libunwind/doc/libunwind-setjmp.tex +++ b/src/native/external/libunwind/doc/libunwind-setjmp.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{libunwind-setjmp}{David Mosberger-Tang}{Programming Library}{libunwind-based non-local gotos}libunwind-setjmp -- libunwind-based non-local gotos +\begin{Name}{3libunwind}{libunwind-setjmp}{David Mosberger-Tang}{Programming Library}{libunwind-based non-local gotos}libunwind-setjmp -- libunwind-based non-local gotos \end{Name} \section{Synopsis} @@ -70,11 +70,10 @@ \section{Files} \section{See Also} - -\SeeAlso{libunwind(3)}, -setjmp(3), longjmp(3), -\_setjmp(3), \_longjmp(3), -sigsetjmp(3), siglongjmp(3) +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{setjmp}(3), \SeeAlso{longjmp}(3), +\SeeAlso{\_setjmp}(3), \SeeAlso{\_longjmp}(3), +\SeeAlso{sigsetjmp}(3), \SeeAlso{siglongjmp}(3) \section{Author} diff --git a/src/native/external/libunwind/doc/libunwind.man b/src/native/external/libunwind/doc/libunwind.man index 837e6e31e9a2d3..96efb04fb85c14 100644 --- a/src/native/external/libunwind/doc/libunwind.man +++ b/src/native/external/libunwind/doc/libunwind.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Sun Aug 29 23:45:06 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 11:06:25 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "LIBUNWIND" "3" "29 August 2021" "Programming Library " "Programming Library " +.TH "LIBUNWIND" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME libunwind \-\- a (mostly) platform\-independent unwind API @@ -129,7 +131,7 @@ unwinding. Say you want to unwind the stack while executing in some function F(). In this function, you would call unw_getcontext() -to get a snapshot of the CPU registers (machine\-state). Then you +to get a snapshot of the CPU registers (machine state). Then you initialize an \fIunwind cursor\fP based on this snapshot. This is done with a call to unw_init_local(). @@ -140,7 +142,7 @@ The unwind cursor can then be moved ``up\&'' (towards earlier stack frames) by calling unw_step(). By repeatedly calling this routine, you can -uncover the entire call\-chain that led to the activation of function +uncover the entire call chain that led to the activation of function F(). A positive return value from unw_step() indicates @@ -166,7 +168,7 @@ back prev to curr whenever that is necessary. In the most extreme case, a program could maintain a separate cursor for each call -frame and that way it could move up and down the callframe\-chain at +frame and that way it could move up and down the callframe chain at will. .PP Given an unwind cursor, it is possible to read and write the CPU @@ -226,14 +228,14 @@ before including the headerfile It is perfectly OK for a single program to employ both local\-only and generic unwinding. That is, whether or not UNW_LOCAL_ONLY -is defined is a choice that each source\-file -(compilation\-unit) can make on its own. Independent of the setting(s) +is defined is a choice that each source file +(compilation unit) can make on its own. Independent of the setting(s) of UNW_LOCAL_ONLY, you\&'ll always link the same library into the program (normally \fB\-l\fPunwind). Furthermore, the portion of libunwind -that manages unwind\-info for dynamically +that manages unwind info for dynamically generated code is not affected by the setting of UNW_LOCAL_ONLY\&. .PP @@ -272,12 +274,12 @@ Remote unwinding is typically used by debuggers and instruction\-set simulators, for example. .PP Before you can unwind a remote process, you need to create a new -address\-space object for that process. This is achieved with the +address space object for that process. This is achieved with the unw_create_addr_space() routine. The routine takes two arguments: a pointer to a set of \fIaccessor\fP routines and an -integer that specifies the byte\-order of the target process. The +integer that specifies the byte order of the target process. The accessor routines provide libunwind with the means to communicate with the remote process. In particular, there are @@ -288,7 +290,7 @@ With the address space created, unwinding can be initiated by a call to unw_init_remote(). This routine is very similar to unw_init_local(), -except that it takes an address\-space +except that it takes an address space object and an opaque pointer as arguments. The routine uses these arguments to fetch the initial machine state. Libunwind never @@ -299,7 +301,7 @@ select, e.g., the thread within a process that is to be unwound. Once a cursor has been initialized with unw_init_remote(), unwinding works exactly like in the local case. That is, you can use unw_step() -to move ``up\&'' in the call\-chain, read and write +to move ``up\&'' in the call chain, read and write registers, or resume execution at a particular stack frame by calling unw_resume\&. .PP @@ -362,7 +364,7 @@ simultaneously. However, any given cursor may be accessed by only one thread at any given time. .PP -To ensure thread\-safety, some libunwind +To ensure thread safety, some libunwind routines may have to use locking. Such routines \fImust not\fP be called from signal @@ -374,7 +376,7 @@ any routine that may be needed for \fIlocal\fP unwinding is signal\-safe (e.g., unw_step() for local unwinding is -signal\-safe). For remote\-unwinding, \fInone\fP +signal\-safe). For remote unwinding, \fInone\fP of the libunwind routines are guaranteed to be signal\-safe. @@ -396,15 +398,15 @@ high\-level language exception handling may not work as expected. .PP The interface for registering and canceling dynamic unwind info has been designed for maximum efficiency, so as to minimize the -performance impact on JIT\-compilers. In particular, both routines are +performance impact on JIT compilers. In particular, both routines are guaranteed to execute in ``constant time\&'' (O(1)) and the -data\-structure encapsulating the dynamic unwind info has been designed +data structure encapsulating the dynamic unwind info has been designed to facilitate sharing, such that similar procedures can share much of the underlying information. .PP For more information on the libunwind support for dynamically -generated code, see libunwind\-dynamic(3)\&. +generated code, see libunwind\-dynamic(3libunwind). .PP .SH CACHING OF UNWIND INFO @@ -417,7 +419,7 @@ using stale data. For example, this would happen if libunwind were to cache information about a shared library which later on gets -unloaded (e.g., via \fIdlclose\fP(3)). +unloaded (e.g., via \fIdlclose\fP(3libunwind)). .PP To prevent the risk of using stale data, libunwind provides two @@ -428,7 +430,7 @@ unw_flush_cache(). The second facility is provided by unw_set_caching_policy(), which lets a program -select the exact caching policy in use for a given address\-space +select the exact caching policy in use for a given address space object. In particular, by selecting the policy UNW_CACHE_NONE, it is possible to turn off caching @@ -455,11 +457,11 @@ should be included. .TP \fB\-l\fPunwind - Linker\-switch to add when building a + Linker switch to add when building a program that does native (same platform) unwinding. .TP \fB\-l\fPunwind\-PLAT - Linker\-switch to add when + Linker switch to add when building a program that unwinds a program on platform PLAT\&. For example, to (cross\-)unwind an IA\-64 program, the linker switch \-lunwind\-ia64 @@ -470,33 +472,33 @@ multiple platforms. .SH SEE ALSO .PP -libunwind\-dynamic(3), -libunwind\-ia64(3), -libunwind\-ptrace(3), -libunwind\-setjmp(3), -unw_create_addr_space(3), -unw_destroy_addr_space(3), -unw_flush_cache(3), -unw_get_accessors(3), -unw_get_fpreg(3), -unw_get_proc_info(3), -unw_get_proc_name(3), -unw_get_reg(3), -unw_getcontext(3), -unw_init_local(3), -unw_init_remote(3), -unw_is_fpreg(3), -unw_is_signal_frame(3), -unw_regname(3), -unw_resume(3), -unw_set_caching_policy(3), -unw_set_cache_size(3), -unw_set_fpreg(3), -unw_set_reg(3), -unw_step(3), -unw_strerror(3), -_U_dyn_register(3), -_U_dyn_cancel(3) +libunwind\-dynamic(3libunwind), +libunwind\-ia64(3libunwind), +libunwind\-ptrace(3libunwind), +libunwind\-setjmp(3libunwind), +unw_create_addr_space(3libunwind), +unw_destroy_addr_space(3libunwind), +unw_flush_cache(3libunwind), +unw_get_accessors(3libunwind), +unw_get_fpreg(3libunwind), +unw_get_proc_info(3libunwind), +unw_get_proc_name(3libunwind), +unw_get_reg(3libunwind), +unw_getcontext(3libunwind), +unw_init_local(3libunwind), +unw_init_remote(3libunwind), +unw_is_fpreg(3libunwind), +unw_is_signal_frame(3libunwind), +unw_regname(3libunwind), +unw_resume(3libunwind), +unw_set_caching_policy(3libunwind), +unw_set_cache_size(3libunwind), +unw_set_fpreg(3libunwind), +unw_set_reg(3libunwind), +unw_step(3libunwind), +unw_strerror(3libunwind), +_U_dyn_register(3libunwind), +_U_dyn_cancel(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/libunwind.tex b/src/native/external/libunwind/doc/libunwind.tex index 8809ba5a36f83c..95d43a5317393e 100644 --- a/src/native/external/libunwind/doc/libunwind.tex +++ b/src/native/external/libunwind/doc/libunwind.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{libunwind}{David Mosberger-Tang}{Programming Library}{Introduction to libunwind}libunwind -- a (mostly) platform-independent unwind API +\begin{Name}{3libunwind}{libunwind}{David Mosberger-Tang}{Programming Library}{Introduction to libunwind}libunwind -- a (mostly) platform-independent unwind API \end{Name} \section{Synopsis} @@ -69,14 +69,14 @@ \section{Local Unwinding} within a running program. This is called \emph{local} unwinding. Say you want to unwind the stack while executing in some function \Func{F}(). In this function, you would call \Func{unw\_getcontext}() -to get a snapshot of the CPU registers (machine-state). Then you +to get a snapshot of the CPU registers (machine state). Then you initialize an \emph{unwind~cursor} based on this snapshot. This is done with a call to \Func{unw\_init\_local}(). The cursor now points to the current frame, that is, the stack frame that corresponds to the current activation of function \Func{F}(). The unwind cursor can then be moved ``up'' (towards earlier stack frames) by calling \Func{unw\_step}(). By repeatedly calling this routine, you can -uncover the entire call-chain that led to the activation of function +uncover the entire call chain that led to the activation of function \Func{F}(). A positive return value from \Func{unw\_step}() indicates that there are more frames in the chain, zero indicates that the end of the chain has been reached, and any negative value indicates that @@ -93,7 +93,7 @@ \section{Local Unwinding} approach, the program could move one step ``down'' simply by copying back \Var{prev} to \Var{curr} whenever that is necessary. In the most extreme case, a program could maintain a separate cursor for each call -frame and that way it could move up and down the callframe-chain at +frame and that way it could move up and down the callframe chain at will. Given an unwind cursor, it is possible to read and write the CPU @@ -135,11 +135,11 @@ \section{Local Unwinding} \Const{UNW\_LOCAL\_ONLY} before including the headerfile \File{$<$libunwind.h$>$}. It is perfectly OK for a single program to employ both local-only and generic unwinding. That is, whether or not -\Const{UNW\_LOCAL\_ONLY} is defined is a choice that each source-file -(compilation-unit) can make on its own. Independent of the setting(s) +\Const{UNW\_LOCAL\_ONLY} is defined is a choice that each source file +(compilation unit) can make on its own. Independent of the setting(s) of \Const{UNW\_LOCAL\_ONLY}, you'll always link the same library into the program (normally \Opt{-l}\File{unwind}). Furthermore, the -portion of \Prog{libunwind} that manages unwind-info for dynamically +portion of \Prog{libunwind} that manages unwind info for dynamically generated code is not affected by the setting of \Const{UNW\_LOCAL\_ONLY}. @@ -175,10 +175,10 @@ \section{Remote Unwinding} used by debuggers and instruction-set simulators, for example. Before you can unwind a remote process, you need to create a new -address-space object for that process. This is achieved with the +address space object for that process. This is achieved with the \Func{unw\_create\_addr\_space}() routine. The routine takes two arguments: a pointer to a set of \emph{accessor} routines and an -integer that specifies the byte-order of the target process. The +integer that specifies the byte order of the target process. The accessor routines provide \Func{libunwind} with the means to communicate with the remote process. In particular, there are callbacks to read and write the process's memory, its registers, and @@ -186,7 +186,7 @@ \section{Remote Unwinding} With the address space created, unwinding can be initiated by a call to \Func{unw\_init\_remote}(). This routine is very similar to -\Func{unw\_init\_local}(), except that it takes an address-space +\Func{unw\_init\_local}(), except that it takes an address space object and an opaque pointer as arguments. The routine uses these arguments to fetch the initial machine state. \Prog{Libunwind} never uses the opaque pointer on its own, but instead just passes it on to @@ -195,7 +195,7 @@ \section{Remote Unwinding} Once a cursor has been initialized with \Func{unw\_init\_remote}(), unwinding works exactly like in the local case. That is, you can use -\Func{unw\_step}() to move ``up'' in the call-chain, read and write +\Func{unw\_step}() to move ``up'' in the call chain, read and write registers, or resume execution at a particular stack frame by calling \Func{unw\_resume}. @@ -242,14 +242,14 @@ \section{Thread- and Signal-Safety} However, any given cursor may be accessed by only one thread at any given time. -To ensure thread-safety, some \Prog{libunwind} routines may have to +To ensure thread safety, some \Prog{libunwind} routines may have to use locking. Such routines \emph{must~not} be called from signal handlers (directly or indirectly) and are therefore \emph{not} signal-safe. The manual page for each \Prog{libunwind} routine identifies whether or not it is signal-safe, but as a general rule, any routine that may be needed for \emph{local} unwinding is signal-safe (e.g., \Func{unw\_step}() for local unwinding is -signal-safe). For remote-unwinding, \emph{none} of the +signal-safe). For remote unwinding, \emph{none} of the \Prog{libunwind} routines are guaranteed to be signal-safe. @@ -265,14 +265,14 @@ \section{Unwinding Through Dynamically Generated Code} The interface for registering and canceling dynamic unwind info has been designed for maximum efficiency, so as to minimize the -performance impact on JIT-compilers. In particular, both routines are +performance impact on JIT compilers. In particular, both routines are guaranteed to execute in ``constant time'' (O(1)) and the -data-structure encapsulating the dynamic unwind info has been designed +data structure encapsulating the dynamic unwind info has been designed to facilitate sharing, such that similar procedures can share much of the underlying information. For more information on the \Prog{libunwind} support for dynamically -generated code, see \SeeAlso{libunwind-dynamic(3)}. +generated code, see \SeeAlso{libunwind-dynamic}(3libunwind). \section{Caching of Unwind Info} @@ -282,7 +282,7 @@ \section{Caching of Unwind Info} during its lifetime, this creates a risk of \Prog{libunwind} using stale data. For example, this would happen if \Prog{libunwind} were to cache information about a shared library which later on gets -unloaded (e.g., via \Cmd{dlclose}{3}). +unloaded (e.g., via \Cmd{dlclose}{3libunwind}). To prevent the risk of using stale data, \Prog{libunwind} provides two facilities: first, it is possible to flush the cached information @@ -290,7 +290,7 @@ \section{Caching of Unwind Info} entire address space, if desired). This functionality is provided by \Func{unw\_flush\_cache}(). The second facility is provided by \Func{unw\_set\_caching\_policy}(), which lets a program -select the exact caching policy in use for a given address-space +select the exact caching policy in use for a given address space object. In particular, by selecting the policy \Const{UNW\_CACHE\_NONE}, it is possible to turn off caching completely, therefore eliminating the risk of stale data altogether @@ -308,9 +308,9 @@ \section{Files} the unwind target runs on platform \Var{PLAT}. For example, to unwind an IA-64 program, the header file \File{libunwind-ia64.h} should be included. -\item[\Opt{-l}\File{unwind}] Linker-switch to add when building a +\item[\Opt{-l}\File{unwind}] Linker switch to add when building a program that does native (same platform) unwinding. -\item[\Opt{-l}\File{unwind-}\Var{PLAT}] Linker-switch to add when +\item[\Opt{-l}\File{unwind-}\Var{PLAT}] Linker switch to add when building a program that unwinds a program on platform \Var{PLAT}. For example, to (cross-)unwind an IA-64 program, the linker switch \File{-lunwind-ia64} should be added. Note: multiple such switches @@ -320,33 +320,33 @@ \section{Files} \section{See Also} -\SeeAlso{libunwind-dynamic(3)}, -\SeeAlso{libunwind-ia64(3)}, -\SeeAlso{libunwind-ptrace(3)}, -\SeeAlso{libunwind-setjmp(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_destroy\_addr\_space(3)}, -\SeeAlso{unw\_flush\_cache(3)}, -\SeeAlso{unw\_get\_accessors(3)}, -\SeeAlso{unw\_get\_fpreg(3)}, -\SeeAlso{unw\_get\_proc\_info(3)}, -\SeeAlso{unw\_get\_proc\_name(3)}, -\SeeAlso{unw\_get\_reg(3)}, -\SeeAlso{unw\_getcontext(3)}, -\SeeAlso{unw\_init\_local(3)}, -\SeeAlso{unw\_init\_remote(3)}, -\SeeAlso{unw\_is\_fpreg(3)}, -\SeeAlso{unw\_is\_signal\_frame(3)}, -\SeeAlso{unw\_regname(3)}, -\SeeAlso{unw\_resume(3)}, -\SeeAlso{unw\_set\_caching\_policy(3)}, -\SeeAlso{unw\_set\_cache\_size(3)}, -\SeeAlso{unw\_set\_fpreg(3)}, -\SeeAlso{unw\_set\_reg(3)}, -\SeeAlso{unw\_step(3)}, -\SeeAlso{unw\_strerror(3)}, -\SeeAlso{\_U\_dyn\_register(3)}, -\SeeAlso{\_U\_dyn\_cancel(3)} +\SeeAlso{libunwind-dynamic}(3libunwind), +\SeeAlso{libunwind-ia64}(3libunwind), +\SeeAlso{libunwind-ptrace}(3libunwind), +\SeeAlso{libunwind-setjmp}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_destroy\_addr\_space}(3libunwind), +\SeeAlso{unw\_flush\_cache}(3libunwind), +\SeeAlso{unw\_get\_accessors}(3libunwind), +\SeeAlso{unw\_get\_fpreg}(3libunwind), +\SeeAlso{unw\_get\_proc\_info}(3libunwind), +\SeeAlso{unw\_get\_proc\_name}(3libunwind), +\SeeAlso{unw\_get\_reg}(3libunwind), +\SeeAlso{unw\_getcontext}(3libunwind), +\SeeAlso{unw\_init\_local}(3libunwind), +\SeeAlso{unw\_init\_remote}(3libunwind), +\SeeAlso{unw\_is\_fpreg}(3libunwind), +\SeeAlso{unw\_is\_signal\_frame}(3libunwind), +\SeeAlso{unw\_regname}(3libunwind), +\SeeAlso{unw\_resume}(3libunwind), +\SeeAlso{unw\_set\_caching\_policy}(3libunwind), +\SeeAlso{unw\_set\_cache\_size}(3libunwind), +\SeeAlso{unw\_set\_fpreg}(3libunwind), +\SeeAlso{unw\_set\_reg}(3libunwind), +\SeeAlso{unw\_step}(3libunwind), +\SeeAlso{unw\_strerror}(3libunwind), +\SeeAlso{\_U\_dyn\_register}(3libunwind), +\SeeAlso{\_U\_dyn\_cancel}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_apply_reg_state.man b/src/native/external/libunwind/doc/unw_apply_reg_state.man index 457f0c4dd17a47..10e02baa29c021 100644 --- a/src/native/external/libunwind/doc/unw_apply_reg_state.man +++ b/src/native/external/libunwind/doc/unw_apply_reg_state.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Wed Aug 16 11:09:44 PDT 2017 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_APPLY\\_REG\\_STATE" "3" "16 August 2017" "Programming Library " "Programming Library " +.TH "UNW\\_APPLY\\_REG\\_STATE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_apply_reg_state \-\- apply a register state update to a cursor @@ -39,16 +41,16 @@ which have been obtained by calling unw_reg_states_iterate\&. .PP On successful completion, unw_apply_reg_state() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_apply_reg_state() -is thread\-safe. If cursor cp +is thread safe. If cursor cp is -in the local address\-space, this routine is also safe to use from a +in the local address space, this routine is also safe to use from a signal handler. .PP .SH ERRORS @@ -64,20 +66,20 @@ was unable to locate unwind\-info for the procedure. .TP UNW_EBADVERSION - The unwind\-info for the procedure has + The unwind info for the procedure has version or format that is not understood by libunwind\&. .PP In addition, unw_apply_reg_state() may return any error returned by the access_mem() call\-back (see -unw_create_addr_space(3)). +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_reg_states_iterate(3) +libunwind(3libunwind), +unw_reg_states_iterate(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_apply_reg_state.tex b/src/native/external/libunwind/doc/unw_apply_reg_state.tex index c67cc3ebfafdeb..b109afd392359d 100644 --- a/src/native/external/libunwind/doc/unw_apply_reg_state.tex +++ b/src/native/external/libunwind/doc/unw_apply_reg_state.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_apply\_reg\_state}{David Mosberger-Tang}{Programming Library}{unw\_apply\_reg\_state}unw\_apply\_reg\_state -- apply a register state update to a cursor +\begin{Name}{3libunwind}{unw\_apply\_reg\_state}{David Mosberger-Tang}{Programming Library}{unw\_apply\_reg\_state}unw\_apply\_reg\_state -- apply a register state update to a cursor \end{Name} \section{Synopsis} @@ -25,13 +25,13 @@ \section{Description} \section{Return Value} On successful completion, \Func{unw\_apply\_reg\_state}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_apply\_reg\_state}() is thread-safe. If cursor \Var{cp} is -in the local address-space, this routine is also safe to use from a +\Func{unw\_apply\_reg\_state}() is thread safe. If cursor \Var{cp} is +in the local address space, this routine is also safe to use from a signal handler. \section{Errors} @@ -40,17 +40,17 @@ \section{Errors} \item[\Const{UNW\_EUNSPEC}] An unspecified error occurred. \item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to locate unwind-info for the procedure. -\item[\Const{UNW\_EBADVERSION}] The unwind-info for the procedure has +\item[\Const{UNW\_EBADVERSION}] The unwind info for the procedure has version or format that is not understood by \Prog{libunwind}. \end{Description} In addition, \Func{unw\_apply\_reg\_state}() may return any error returned by the \Func{access\_mem}() call-back (see -\Func{unw\_create\_addr\_space}(3)). +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_reg\_states\_iterate(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_reg\_states\_iterate}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_backtrace.man b/src/native/external/libunwind/doc/unw_backtrace.man index e1a4a9dfcad761..26b643a649c956 100644 --- a/src/native/external/libunwind/doc/unw_backtrace.man +++ b/src/native/external/libunwind/doc/unw_backtrace.man @@ -1,7 +1,7 @@ .\" *********************************** start of \input{common.tex} .\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Jan 5 15:33:00 2023 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -12,7 +12,7 @@ .fi .. -.TH "UNW\\_BACKTRACE" "3" "05 January 2023" "Programming Library " "Programming Library " +.TH "UNW\\_BACKTRACE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_backtrace \-\- return backtrace for the calling program @@ -91,8 +91,8 @@ stored. .SH SEE ALSO .PP -libunwind(3), -unw_step(3) +libunwind(3libunwind), +unw_step(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_backtrace.tex b/src/native/external/libunwind/doc/unw_backtrace.tex index 3e5152b6ef0bb8..4bd396ba38a428 100644 --- a/src/native/external/libunwind/doc/unw_backtrace.tex +++ b/src/native/external/libunwind/doc/unw_backtrace.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_backtrace}{David Mosberger-Tang}{Programming Library}{unw\_backtrace}unw\_backtrace -- return backtrace for the calling program +\begin{Name}{3libunwind}{unw\_backtrace}{David Mosberger-Tang}{Programming Library}{unw\_backtrace}unw\_backtrace -- return backtrace for the calling program \end{Name} \section{Synopsis} @@ -34,8 +34,8 @@ \section{Description} calling \Func{unw\_backtrace}(). In case you want to obtain the backtrace from a specific \Type{unw\_context\_t}, -you can call \Func{unw\_backtrace2} with that context passing \Const{0} for flag. -If the \Type{unw\_context_t} is known to be a signal frame (i.e., from the third argument +you can call \Func{unw\_backtrace2} with that context passing \Const{0} for flag. +If the \Type{unw\_context\_t} is known to be a signal frame (i.e., from the third argument in a sigaction handler on linux), \Func{unw\_backtrace2} can be used to collect only the frames before the signal frame passing the \Const{UNW\_INIT\_SIGNAL\_FRAME} flag. @@ -47,8 +47,8 @@ \section{Return Value} \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_step(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_step}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_create_addr_space.man b/src/native/external/libunwind/doc/unw_create_addr_space.man index 4aca13ecd8297e..b04be571da4d9c 100644 --- a/src/native/external/libunwind/doc/unw_create_addr_space.man +++ b/src/native/external/libunwind/doc/unw_create_addr_space.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 10:53:41 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_CREATE\\_ADDR\\_SPACE" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_CREATE\\_ADDR\\_SPACE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_create_addr_space \-\- create address space for remote unwinding @@ -32,54 +34,54 @@ byteorder); .PP The unw_create_addr_space() routine creates a new unwind -address\-space and initializes it based on the call\-back routines +address space and initializes it based on the callback routines passed via the ap pointer and the specified byteorder\&. -The call\-back routines are described in detail below. The +The callback routines are described in detail below. The byteorder -can be set to 0 to request the default byte\-order of -the unwind target. To request a particular byte\-order, +can be set to 0 to request the default byte order of +the unwind target. To request a particular byte order, byteorder can be set to any constant defined by \&. -In particular, __LITTLE_ENDIAN +In particular, UNW_LITTLE_ENDIAN would -request little\-endian byte\-order and __BIG_ENDIAN +request little\-endian byte order and UNW_BIG_ENDIAN would -request big\-endian byte\-order. Whether or not a particular byte\-order +request big\-endian byte order. Whether or not a particular byte order is supported depends on the target platform. .PP -.SH CALL\-BACK ROUTINES +.SH CALLBACK ROUTINES .PP Libunwind -uses a set of call\-back routines to access the -information it needs to unwind a chain of stack\-frames. These +uses a set of callback routines to access the +information it needs to unwind a chain of stack frames. These routines are specified via the ap argument, which points to a variable of type unw_accessors_t\&. The contents of this -variable is copied into the newly\-created address space, so the +variable is copied into the newly created address space, so the variable must remain valid only for the duration of the call to unw_create_addr_space(). .PP -The first argument to every call\-back routine is an address\-space +The first argument to every callback routine is an address space identifier (as) and the last argument is an arbitrary, -application\-specified void\-pointer (arg). +application specified void pointer (arg). When invoking a -call\-back routine, libunwind +callback routine, libunwind sets the as argument to the -address\-space on whose behalf the invocation is made and the arg +address space on whose behalf the invocation is made and the arg argument to the value that was specified when -unw_init_remote(3) +unw_init_remote(3libunwind) was called. .PP -The synopsis and a detailed description of every call\-back routine +The synopsis and a detailed description of every callback routine follows below. .PP -.SS CALL\-BACK ROUTINE SYNOPSIS +.SS CALLBACK ROUTINE SYNOPSIS .PP int find_proc_info(unw_addr_space_t @@ -169,19 +171,19 @@ unw_word_t *offp, .PP Libunwind invokes the find_proc_info() -call\-back to +callback to locate the information need to unwind a particular procedure. The ip -argument is an instruction\-address inside the procedure whose +argument is an instruction address inside the procedure whose information is needed. The pip argument is a pointer to the variable used to return the desired information. The type of this variable is unw_proc_info_t\&. See -unw_get_proc_info(3) +unw_get_proc_info(3libunwind) for details. Argument need_unwind_info -is zero if the call\-back does not need to +is zero if the callback does not need to provide values for the following members in the unw_proc_info_t structure: format, @@ -194,22 +196,22 @@ in these members. Furthermore, the contents of the memory addressed by the unwind_info member must remain valid until the info is released via the put_unwind_info -call\-back (see below). +callback (see below). .PP On successful completion, the find_proc_info() -call\-back must +callback must return zero. Otherwise, the negative value of one of the unw_error_t -error\-codes may be returned. In particular, this -call\-back may return \-UNW_ESTOPUNWIND +error codes may be returned. In particular, this +callback may return \-UNW_ESTOPUNWIND to signal the end of -the frame\-chain. +the frame chain. .PP .SS PUT_UNWIND_INFO .PP Libunwind invokes the put_unwind_info() -call\-back to +callback to release the resources (such as memory) allocated by a previous call to find_proc_info() with the need_unwind_info @@ -229,36 +231,36 @@ argument. .PP Libunwind invokes the get_dyn_info_list_addr() -call\-back to obtain the address of the head of the dynamic unwind\-info +callback to obtain the address of the head of the dynamic unwind info registration list. The variable stored at the returned address must have a type of unw_dyn_info_list_t (see -_U_dyn_register(3)). +_U_dyn_register(3libunwind)). The dliap argument is a pointer to a variable of type unw_word_t which is used to return the -address of the dynamic unwind\-info registration list. If no dynamic -unwind\-info registration list exist, the value pointed to by +address of the dynamic unwind info registration list. If no dynamic +unwind info registration list exist, the value pointed to by dliap must be cleared to zero. Libunwind will cache the value returned by get_dyn_info_list_addr() if caching is -enabled for the given address\-space. The cache can be cleared with a +enabled for the given address space. The cache can be cleared with a call to unw_flush_cache(). .PP On successful completion, the get_dyn_info_list_addr() -call\-back must return zero. Otherwise, the negative value of one of +callback must return zero. Otherwise, the negative value of one of the unw_error_t -error\-codes may be returned. +error codes may be returned. .PP .SS ACCESS_MEM .PP Libunwind invokes the access_mem() -call\-back to read -from or write to a word of memory in the target address\-space. The +callback to read +from or write to a word of memory in the target address space. The address of the word to be accessed is passed in argument addr\&. To read memory, libunwind sets argument write @@ -272,21 +274,21 @@ value and valp to point to the word that contains the value to be written. The word that valp points to is always in the -byte\-order of the host\-platform, regardless of the byte\-order of the -target. In other words, it is the responsibility of the call\-back -routine to convert between the target\&'s and the host\&'s byte\-order, if +byte order of the host platform, regardless of the byte order of the +target. In other words, it is the responsibility of the callback +routine to convert between the target\&'s and the host\&'s byte order, if necessary. .PP On successful completion, the access_mem() -call\-back must return zero. Otherwise, the negative value of one of +callback must return zero. Otherwise, the negative value of one of the unw_error_t -error\-codes may be returned. +error codes may be returned. .PP .SS ACCESS_REG .PP Libunwind invokes the access_reg() -call\-back to read +callback to read from or write to a scalar (non\-floating\-point) CPU register. The index of the register to be accessed is passed in argument regnum\&. @@ -301,22 +303,22 @@ write to a non\-zero value and valp to point to the word that contains the value to be written. The word that valp -points to is always in the byte\-order of the host\-platform, regardless -of the byte\-order of the target. In other words, it is the -responsibility of the call\-back routine to convert between the -target\&'s and the host\&'s byte\-order, if necessary. +points to is always in the byte order of the host platform, regardless +of the byte order of the target. In other words, it is the +responsibility of the callback routine to convert between the +target\&'s and the host\&'s byte order, if necessary. .PP On successful completion, the access_reg() -call\-back must +callback must return zero. Otherwise, the negative value of one of the unw_error_t -error\-codes may be returned. +error codes may be returned. .PP .SS ACCESS_FPREG .PP Libunwind invokes the access_fpreg() -call\-back to read +callback to read from or write to a floating\-point CPU register. The index of the register to be accessed is passed in argument regnum\&. To read a @@ -335,62 +337,62 @@ the variable of type unw_fpreg_t that contains the value to be written. The word that fpvalp points to is always in the -byte\-order of the host\-platform, regardless of the byte\-order of the -target. In other words, it is the responsibility of the call\-back -routine to convert between the target\&'s and the host\&'s byte\-order, if +byte order of the host platform, regardless of the byte order of the +target. In other words, it is the responsibility of the callback +routine to convert between the target\&'s and the host\&'s byte order, if necessary. .PP On successful completion, the access_fpreg() -call\-back must +callback must return zero. Otherwise, the negative value of one of the unw_error_t -error\-codes may be returned. +error codes may be returned. .PP .SS RESUME .PP Libunwind invokes the resume() -call\-back to resume +callback to resume execution in the target address space. Argument cp is the -unwind\-cursor that identifies the stack\-frame in which execution +unwind cursor that identifies the stack frame in which execution should resume. By the time libunwind invokes the resume -call\-back, it has already established the desired machine\- and -memory\-state via calls to the access_reg(), +callback, it has already established the desired machine and +memory state via calls to the access_reg(), access_fpreg, and access_mem() -call\-backs. Thus, all -the call\-back needs to do is perform whatever action is needed to +callbacks. Thus, all +the callback needs to do is perform whatever action is needed to actually resume execution. .PP The resume -call\-back is invoked only in response to a call to -unw_resume(3), +callback is invoked only in response to a call to +unw_resume(3libunwind), so applications which never invoke -unw_resume(3) +unw_resume(3libunwind) need not define the resume callback. .PP On successful completion, the resume() -call\-back must return +callback must return zero. Otherwise, the negative value of one of the unw_error_t -error\-codes may be returned. As a special case, -when resuming execution in the local address space, the call\-back will +error codes may be returned. As a special case, +when resuming execution in the local address space, the callback will not return on success. .PP .SS GET_PROC_NAME .PP Libunwind invokes the get_proc_name() -call\-back to -obtain the procedure\-name of a static (not dynamically generated) +callback to +obtain the procedure name of a static (not dynamically generated) procedure. Argument addr -is an instruction\-address within the +is an instruction address within the procedure whose name is to be obtained. The bufp argument is a -pointer to a character\-buffer used to return the procedure name. The +pointer to a character buffer used to return the procedure name. The size of this buffer is specified in argument buf_len\&. The returned name must be terminated by a NUL character. If the @@ -402,7 +404,7 @@ buffer set to the NUL character and \-UNW_ENOMEM must be returned. Argument offp is a pointer to a word which is used to -return the byte\-offset relative to the start of the procedure whose +return the byte offset relative to the start of the procedure whose name is being returned. For example, if procedure foo() starts at address 0x40003000, then invoking get_proc_name() @@ -414,10 +416,10 @@ pointed to by offp bytes long). .PP On successful completion, the get_proc_name() -call\-back must +callback must return zero. Otherwise, the negative value of one of the unw_error_t -error\-codes may be returned. +error codes may be returned. .PP .SH RETURN VALUE @@ -426,7 +428,7 @@ On successful completion, unw_create_addr_space() returns a non\-NULL value that represents the newly created -address\-space. Otherwise, NULL +address space. Otherwise, NULL is returned. .PP .SH THREAD AND SIGNAL SAFETY @@ -439,12 +441,12 @@ safe to use from a signal handler. .SH SEE ALSO .PP -_U_dyn_register(3), -libunwind(3), -unw_destroy_addr_space(3), -unw_get_proc_info(3), -unw_init_remote(3), -unw_resume(3) +_U_dyn_register(3libunwind), +libunwind(3libunwind), +unw_destroy_addr_space(3libunwind), +unw_get_proc_info(3libunwind), +unw_init_remote(3libunwind), +unw_resume(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_create_addr_space.tex b/src/native/external/libunwind/doc/unw_create_addr_space.tex index 8de0691f3a9206..818781d6b862f6 100644 --- a/src/native/external/libunwind/doc/unw_create_addr_space.tex +++ b/src/native/external/libunwind/doc/unw_create_addr_space.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_create\_addr\_space}{David Mosberger-Tang}{Programming Library}{unw\_create\_addr\_space}unw\_create\_addr\_space -- create address space for remote unwinding +\begin{Name}{3libunwind}{unw\_create\_addr\_space}{David Mosberger-Tang}{Programming Library}{unw\_create\_addr\_space}unw\_create\_addr\_space -- create address space for remote unwinding \end{Name} \section{Synopsis} @@ -17,39 +17,39 @@ \section{Synopsis} \section{Description} The \Func{unw\_create\_addr\_space}() routine creates a new unwind -address-space and initializes it based on the call-back routines +address space and initializes it based on the callback routines passed via the \Var{ap} pointer and the specified \Var{byteorder}. -The call-back routines are described in detail below. The -\Var{byteorder} can be set to 0 to request the default byte-order of -the unwind target. To request a particular byte-order, +The callback routines are described in detail below. The +\Var{byteorder} can be set to 0 to request the default byte order of +the unwind target. To request a particular byte order, \Var{byteorder} can be set to any constant defined by -\File{$<$endian.h$>$}. In particular, \Const{\_\_LITTLE\_ENDIAN} would -request little-endian byte-order and \Const{\_\_BIG\_ENDIAN} would -request big-endian byte-order. Whether or not a particular byte-order +\File{$<$endian.h$>$}. In particular, \Const{UNW\_LITTLE\_ENDIAN} would +request little-endian byte order and \Const{UNW\_BIG\_ENDIAN} would +request big-endian byte order. Whether or not a particular byte order is supported depends on the target platform. -\section{Call-back Routines} +\section{Callback Routines} -\Prog{Libunwind} uses a set of call-back routines to access the -information it needs to unwind a chain of stack-frames. These +\Prog{Libunwind} uses a set of callback routines to access the +information it needs to unwind a chain of stack frames. These routines are specified via the \Var{ap} argument, which points to a variable of type \Type{unw\_accessors\_t}. The contents of this -variable is copied into the newly-created address space, so the +variable is copied into the newly created address space, so the variable must remain valid only for the duration of the call to \Func{unw\_create\_addr\_space}(). -The first argument to every call-back routine is an address-space +The first argument to every callback routine is an address space identifier (\Var{as}) and the last argument is an arbitrary, -application-specified void-pointer (\Var{arg}). When invoking a -call-back routine, \Prog{libunwind} sets the \Var{as} argument to the -address-space on whose behalf the invocation is made and the \Var{arg} +application specified void pointer (\Var{arg}). When invoking a +callback routine, \Prog{libunwind} sets the \Var{as} argument to the +address space on whose behalf the invocation is made and the \Var{arg} argument to the value that was specified when -\Func{unw\_init\_remote}(3) was called. +\Func{unw\_init\_remote}(3libunwind) was called. -The synopsis and a detailed description of every call-back routine +The synopsis and a detailed description of every callback routine follows below. -\subsection{Call-back Routine Synopsis} +\subsection{Callback Routine Synopsis} \Type{int} \Func{find\_proc\_info}(\Type{unw\_addr\_space\_t} \Var{as},\\ \SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_word\_t} \Var{ip}, \Type{unw\_proc\_info\_t~*}\Var{pip},\\ @@ -76,31 +76,31 @@ \subsection{Call-back Routine Synopsis} \subsection{find\_proc\_info} -\Prog{Libunwind} invokes the \Func{find\_proc\_info}() call-back to +\Prog{Libunwind} invokes the \Func{find\_proc\_info}() callback to locate the information need to unwind a particular procedure. The -\Var{ip} argument is an instruction-address inside the procedure whose +\Var{ip} argument is an instruction address inside the procedure whose information is needed. The \Var{pip} argument is a pointer to the variable used to return the desired information. The type of this variable is \Type{unw\_proc\_info\_t}. See -\Func{unw\_get\_proc\_info(3)} for details. Argument -\Var{need\_unwind\_info} is zero if the call-back does not need to +\Func{unw\_get\_proc\_info}(3libunwind) for details. Argument +\Var{need\_unwind\_info} is zero if the callback does not need to provide values for the following members in the \Type{unw\_proc\_info\_t} structure: \Var{format}, \Var{unwind\_info\_size}, and \Var{unwind\_info}. If \Var{need\_unwind\_info} is non-zero, valid values need to be returned in these members. Furthermore, the contents of the memory addressed by the \Var{unwind\_info} member must remain valid until the info is -released via the \Func{put\_unwind\_info} call-back (see below). +released via the \Func{put\_unwind\_info} callback (see below). -On successful completion, the \Func{find\_proc\_info}() call-back must +On successful completion, the \Func{find\_proc\_info}() callback must return zero. Otherwise, the negative value of one of the -\Type{unw\_error\_t} error-codes may be returned. In particular, this -call-back may return -\Const{UNW\_ESTOPUNWIND} to signal the end of -the frame-chain. +\Type{unw\_error\_t} error codes may be returned. In particular, this +callback may return -\Const{UNW\_ESTOPUNWIND} to signal the end of +the frame chain. \subsection{put\_unwind\_info} -\Prog{Libunwind} invokes the \Func{put\_unwind\_info}() call-back to +\Prog{Libunwind} invokes the \Func{put\_unwind\_info}() callback to release the resources (such as memory) allocated by a previous call to \Func{find\_proc\_info}() with the \Var{need\_unwind\_info} argument set to a non-zero value. The \Var{pip} argument has the same value as @@ -113,44 +113,44 @@ \subsection{put\_unwind\_info} \subsection{get\_dyn\_info\_list\_addr} \Prog{Libunwind} invokes the \Func{get\_dyn\_info\_list\_addr}() -call-back to obtain the address of the head of the dynamic unwind-info +callback to obtain the address of the head of the dynamic unwind info registration list. The variable stored at the returned address must have a type of \Type{unw\_dyn\_info\_list\_t} (see -\Func{\_U\_dyn\_register}(3)). The \Var{dliap} argument is a pointer +\Func{\_U\_dyn\_register}(3libunwind)). The \Var{dliap} argument is a pointer to a variable of type \Type{unw\_word\_t} which is used to return the -address of the dynamic unwind-info registration list. If no dynamic -unwind-info registration list exist, the value pointed to by +address of the dynamic unwind info registration list. If no dynamic +unwind info registration list exist, the value pointed to by \Var{dliap} must be cleared to zero. \Prog{Libunwind} will cache the value returned by \Func{get\_dyn\_info\_list\_addr}() if caching is -enabled for the given address-space. The cache can be cleared with a +enabled for the given address space. The cache can be cleared with a call to \Func{unw\_flush\_cache}(). On successful completion, the \Func{get\_dyn\_info\_list\_addr}() -call-back must return zero. Otherwise, the negative value of one of -the \Type{unw\_error\_t} error-codes may be returned. +callback must return zero. Otherwise, the negative value of one of +the \Type{unw\_error\_t} error codes may be returned. \subsection{access\_mem} -\Prog{Libunwind} invokes the \Func{access\_mem}() call-back to read -from or write to a word of memory in the target address-space. The +\Prog{Libunwind} invokes the \Func{access\_mem}() callback to read +from or write to a word of memory in the target address space. The address of the word to be accessed is passed in argument \Var{addr}. To read memory, \Prog{libunwind} sets argument \Var{write} to zero and \Var{valp} to point to the word that receives the read value. To write memory, \Prog{libunwind} sets argument \Var{write} to a non-zero value and \Var{valp} to point to the word that contains the value to be written. The word that \Var{valp} points to is always in the -byte-order of the host-platform, regardless of the byte-order of the -target. In other words, it is the responsibility of the call-back -routine to convert between the target's and the host's byte-order, if +byte order of the host platform, regardless of the byte order of the +target. In other words, it is the responsibility of the callback +routine to convert between the target's and the host's byte order, if necessary. On successful completion, the \Func{access\_mem}() -call-back must return zero. Otherwise, the negative value of one of -the \Type{unw\_error\_t} error-codes may be returned. +callback must return zero. Otherwise, the negative value of one of +the \Type{unw\_error\_t} error codes may be returned. \subsection{access\_reg} -\Prog{Libunwind} invokes the \Func{access\_reg}() call-back to read +\Prog{Libunwind} invokes the \Func{access\_reg}() callback to read from or write to a scalar (non-floating-point) CPU register. The index of the register to be accessed is passed in argument \Var{regnum}. To read a register, \Prog{libunwind} sets argument @@ -158,18 +158,18 @@ \subsection{access\_reg} the read value. To write a register, \Prog{libunwind} sets argument \Var{write} to a non-zero value and \Var{valp} to point to the word that contains the value to be written. The word that \Var{valp} -points to is always in the byte-order of the host-platform, regardless -of the byte-order of the target. In other words, it is the -responsibility of the call-back routine to convert between the -target's and the host's byte-order, if necessary. +points to is always in the byte order of the host platform, regardless +of the byte order of the target. In other words, it is the +responsibility of the callback routine to convert between the +target's and the host's byte order, if necessary. -On successful completion, the \Func{access\_reg}() call-back must +On successful completion, the \Func{access\_reg}() callback must return zero. Otherwise, the negative value of one of the -\Type{unw\_error\_t} error-codes may be returned. +\Type{unw\_error\_t} error codes may be returned. \subsection{access\_fpreg} -\Prog{Libunwind} invokes the \Func{access\_fpreg}() call-back to read +\Prog{Libunwind} invokes the \Func{access\_fpreg}() callback to read from or write to a floating-point CPU register. The index of the register to be accessed is passed in argument \Var{regnum}. To read a register, \Prog{libunwind} sets argument \Var{write} to zero and @@ -178,67 +178,67 @@ \subsection{access\_fpreg} argument \Var{write} to a non-zero value and \Var{fpvalp} to point to the variable of type \Type{unw\_fpreg\_t} that contains the value to be written. The word that \Var{fpvalp} points to is always in the -byte-order of the host-platform, regardless of the byte-order of the -target. In other words, it is the responsibility of the call-back -routine to convert between the target's and the host's byte-order, if +byte order of the host platform, regardless of the byte order of the +target. In other words, it is the responsibility of the callback +routine to convert between the target's and the host's byte order, if necessary. -On successful completion, the \Func{access\_fpreg}() call-back must +On successful completion, the \Func{access\_fpreg}() callback must return zero. Otherwise, the negative value of one of the -\Type{unw\_error\_t} error-codes may be returned. +\Type{unw\_error\_t} error codes may be returned. \subsection{resume} -\Prog{Libunwind} invokes the \Func{resume}() call-back to resume +\Prog{Libunwind} invokes the \Func{resume}() callback to resume execution in the target address space. Argument \Var{cp} is the -unwind-cursor that identifies the stack-frame in which execution +unwind cursor that identifies the stack frame in which execution should resume. By the time \Prog{libunwind} invokes the \Func{resume} -call-back, it has already established the desired machine- and -memory-state via calls to the \Func{access\_reg}(), -\Func{access\_fpreg}, and \Func{access\_mem}() call-backs. Thus, all -the call-back needs to do is perform whatever action is needed to +callback, it has already established the desired machine and +memory state via calls to the \Func{access\_reg}(), +\Func{access\_fpreg}, and \Func{access\_mem}() callbacks. Thus, all +the callback needs to do is perform whatever action is needed to actually resume execution. -The \Func{resume} call-back is invoked only in response to a call to -\Func{unw\_resume}(3), so applications which never invoke -\Func{unw\_resume}(3) need not define the \Func{resume} callback. +The \Func{resume} callback is invoked only in response to a call to +\Func{unw\_resume}(3libunwind), so applications which never invoke +\Func{unw\_resume}(3libunwind) need not define the \Func{resume} callback. -On successful completion, the \Func{resume}() call-back must return +On successful completion, the \Func{resume}() callback must return zero. Otherwise, the negative value of one of the -\Type{unw\_error\_t} error-codes may be returned. As a special case, -when resuming execution in the local address space, the call-back will +\Type{unw\_error\_t} error codes may be returned. As a special case, +when resuming execution in the local address space, the callback will not return on success. \subsection{get\_proc\_name} -\Prog{Libunwind} invokes the \Func{get\_proc\_name}() call-back to -obtain the procedure-name of a static (not dynamically generated) -procedure. Argument \Var{addr} is an instruction-address within the +\Prog{Libunwind} invokes the \Func{get\_proc\_name}() callback to +obtain the procedure name of a static (not dynamically generated) +procedure. Argument \Var{addr} is an instruction address within the procedure whose name is to be obtained. The \Var{bufp} argument is a -pointer to a character-buffer used to return the procedure name. The +pointer to a character buffer used to return the procedure name. The size of this buffer is specified in argument \Var{buf\_len}. The returned name must be terminated by a NUL character. If the procedure's name is longer than \Var{buf\_len} bytes, it must be truncated to \Var{buf\_len}\Prog{-1} bytes, with the last byte in the buffer set to the NUL character and -\Const{UNW\_ENOMEM} must be returned. Argument \Var{offp} is a pointer to a word which is used to -return the byte-offset relative to the start of the procedure whose +return the byte offset relative to the start of the procedure whose name is being returned. For example, if procedure \Func{foo}() starts at address 0x40003000, then invoking \Func{get\_proc\_name}() with \Var{addr} set to 0x40003080 should return a value of 0x80 in the word pointed to by \Var{offp} (assuming the procedure is at least 0x80 bytes long). -On successful completion, the \Func{get\_proc\_name}() call-back must +On successful completion, the \Func{get\_proc\_name}() callback must return zero. Otherwise, the negative value of one of the -\Type{unw\_error\_t} error-codes may be returned. +\Type{unw\_error\_t} error codes may be returned. \section{Return Value} On successful completion, \Func{unw\_create\_addr\_space}() returns a non-\Const{NULL} value that represents the newly created -address-space. Otherwise, \Const{NULL} is returned. +address space. Otherwise, \Const{NULL} is returned. \section{Thread and Signal Safety} @@ -247,12 +247,12 @@ \section{Thread and Signal Safety} \section{See Also} -\SeeAlso{\_U\_dyn\_register(3)}, -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_destroy\_addr\_space(3)}, -\SeeAlso{unw\_get\_proc\_info(3)}, -\SeeAlso{unw\_init\_remote(3)}, -\SeeAlso{unw\_resume(3)} +\SeeAlso{\_U\_dyn\_register}(3libunwind), +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_destroy\_addr\_space}(3libunwind), +\SeeAlso{unw\_get\_proc\_info}(3libunwind), +\SeeAlso{unw\_init\_remote}(3libunwind), +\SeeAlso{unw\_resume}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_destroy_addr_space.man b/src/native/external/libunwind/doc/unw_destroy_addr_space.man index 90c9777efbadd9..6875d40617ef27 100644 --- a/src/native/external/libunwind/doc/unw_destroy_addr_space.man +++ b/src/native/external/libunwind/doc/unw_destroy_addr_space.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 12:09:49 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_DESTROY\\_ADDR\\_SPACE" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_DESTROY\\_ADDR\\_SPACE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_destroy_addr_space \-\- destroy unwind address space @@ -43,8 +45,8 @@ undefined behavior (e.g., the application may crash). .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_destroy_addr_space.tex b/src/native/external/libunwind/doc/unw_destroy_addr_space.tex index a66b10b4b0bb4e..fcba18c9bf7211 100644 --- a/src/native/external/libunwind/doc/unw_destroy_addr_space.tex +++ b/src/native/external/libunwind/doc/unw_destroy_addr_space.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_destroy\_addr\_space}{David Mosberger-Tang}{Programming Library}{unw\_destroy\_addr\_space}unw\_destroy\_addr\_space -- destroy unwind address space +\begin{Name}{3libunwind}{unw\_destroy\_addr\_space}{David Mosberger-Tang}{Programming Library}{unw\_destroy\_addr\_space}unw\_destroy\_addr\_space -- destroy unwind address space \end{Name} \section{Synopsis} @@ -26,8 +26,8 @@ \section{Description} \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_flush_cache.man b/src/native/external/libunwind/doc/unw_flush_cache.man index 627449effe2ad9..285edc448a6040 100644 --- a/src/native/external/libunwind/doc/unw_flush_cache.man +++ b/src/native/external/libunwind/doc/unw_flush_cache.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Fri Dec 2 16:09:33 PST 2016 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_FLUSH\\_CACHE" "3" "02 December 2016" "Programming Library " "Programming Library " +.TH "UNW\\_FLUSH\\_CACHE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_flush_cache \-\- flush cached info @@ -35,15 +37,15 @@ hi); .PP The unw_flush_cache() routine flushes all cached info as it -relates to address\-range lo +relates to address range lo to hi (non\-inclusive) in the -target address\-space as\&. +target address space as\&. In addition, all info cached for -address\-space as -that is not tied to a particular code\-range is +address space as +that is not tied to a particular code range is also flushed. For example, the address of the dynamic registration -list is not tied to a code\-range and its cached value (if any) is +list is not tied to a code range and its cached value (if any) is flushed by a call to this routine. The address range specified by lo and hi @@ -72,15 +74,15 @@ return a value. .PP The unw_flush_cache() -routine is thread\-safe as well as safe to +routine is thread safe as well as safe to use from a signal handler. .PP .SH SEE ALSO .PP -libunwind(3), -unw_set_caching_policy(3) -unw_set_cache_size(3) +libunwind(3libunwind), +unw_set_caching_policy(3libunwind) +unw_set_cache_size(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_flush_cache.tex b/src/native/external/libunwind/doc/unw_flush_cache.tex index 32319db5d15872..a1364740c6f65b 100644 --- a/src/native/external/libunwind/doc/unw_flush_cache.tex +++ b/src/native/external/libunwind/doc/unw_flush_cache.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_flush\_cache}{David Mosberger-Tang}{Programming Library}{unw\_flush\_cache}unw\_flush\_cache -- flush cached info +\begin{Name}{3libunwind}{unw\_flush\_cache}{David Mosberger-Tang}{Programming Library}{unw\_flush\_cache}unw\_flush\_cache -- flush cached info \end{Name} \section{Synopsis} @@ -17,11 +17,11 @@ \section{Synopsis} \section{Description} The \Func{unw\_flush\_cache}() routine flushes all cached info as it -relates to address-range \Var{lo} to \Var{hi} (non-inclusive) in the -target address-space \Var{as}. In addition, all info cached for -address-space \Var{as} that is not tied to a particular code-range is +relates to address range \Var{lo} to \Var{hi} (non-inclusive) in the +target address space \Var{as}. In addition, all info cached for +address space \Var{as} that is not tied to a particular code range is also flushed. For example, the address of the dynamic registration -list is not tied to a code-range and its cached value (if any) is +list is not tied to a code range and its cached value (if any) is flushed by a call to this routine. The address range specified by \Var{lo} and \Var{hi} should be understood as a hint: \Func{unw\_flush\_cache}() may flush more information than requested, @@ -38,14 +38,14 @@ \section{Return Value} \section{Thread and Signal Safety} -The \Func{unw\_flush\_cache}() routine is thread-safe as well as safe to +The \Func{unw\_flush\_cache}() routine is thread safe as well as safe to use from a signal handler. \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_set\_caching\_policy(3)} -\SeeAlso{unw\_set\_cache\_size(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_set\_caching\_policy}(3libunwind) +\SeeAlso{unw\_set\_cache\_size}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_accessors.man b/src/native/external/libunwind/doc/unw_get_accessors.man index 83fe4fcea6d673..7db87423592c5b 100644 --- a/src/native/external/libunwind/doc/unw_get_accessors.man +++ b/src/native/external/libunwind/doc/unw_get_accessors.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_GET\\_ACCESSORS" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_ACCESSORS" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_accessors \-\- get pointer to accessor call\-backs @@ -30,18 +32,18 @@ unw_accessors_t *unw_get_accessors(unw_addr_space_t as); The unw_get_accessors() routine returns a pointer to a unw_accessors_t -structure, which contains the call\-back +structure, which contains the callback routines that were specified when address space as was created -(see unw_create_addr_space(3)). +(see unw_create_addr_space(3libunwind)). The returned pointer is guaranteed to remain valid until address space as is destroyed -by a call to unw_destroy_addr_space(3). +by a call to unw_destroy_addr_space(3libunwind). .PP Note that unw_get_accessors() can be used to retrieve the -call\-back routines for the local address space +callback routines for the local address space unw_local_addr_space\&. .PP .SH RETURN VALUE @@ -58,15 +60,15 @@ structure. .PP The unw_get_accessors() -routine is thread\-safe as well as +routine is thread safe as well as safe to use from a signal handler. .PP .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3), -unw_destroy_addr_space(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +unw_destroy_addr_space(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_accessors.tex b/src/native/external/libunwind/doc/unw_get_accessors.tex index bf344a32de2e61..99233329f6163f 100644 --- a/src/native/external/libunwind/doc/unw_get_accessors.tex +++ b/src/native/external/libunwind/doc/unw_get_accessors.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_get\_accessors}{David Mosberger-Tang}{Programming Library}{unw\_get\_accessors}unw\_get\_accessors -- get pointer to accessor call-backs +\begin{Name}{3libunwind}{unw\_get\_accessors}{David Mosberger-Tang}{Programming Library}{unw\_get\_accessors}unw\_get\_accessors -- get pointer to accessor call-backs \end{Name} \section{Synopsis} @@ -17,14 +17,14 @@ \section{Synopsis} \section{Description} The \Func{unw\_get\_accessors}() routine returns a pointer to a -\Type{unw\_accessors\_t} structure, which contains the call-back +\Type{unw\_accessors\_t} structure, which contains the callback routines that were specified when address space \Var{as} was created -(see \Func{unw\_create\_addr\_space}(3)). The returned pointer is +(see \Func{unw\_create\_addr\_space}(3libunwind)). The returned pointer is guaranteed to remain valid until address space \Var{as} is destroyed -by a call to \Func{unw\_destroy\_addr\_space}(3). +by a call to \Func{unw\_destroy\_addr\_space}(3libunwind). Note that \Func{unw\_get\_accessors}() can be used to retrieve the -call-back routines for the local address space +callback routines for the local address space \Var{unw\_local\_addr\_space}. \section{Return Value} @@ -35,14 +35,14 @@ \section{Return Value} \section{Thread and Signal Safety} -The \Func{unw\_get\_accessors}() routine is thread-safe as well as +The \Func{unw\_get\_accessors}() routine is thread safe as well as safe to use from a signal handler. \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_destroy\_addr\_space(3)} +\SeeAlso{libunwind(3libunwind)}, +\SeeAlso{unw\_create\_addr\_space(3libunwind)}, +\SeeAlso{unw\_destroy\_addr\_space(3libunwind)} \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_elf_filename.man b/src/native/external/libunwind/doc/unw_get_elf_filename.man new file mode 100644 index 00000000000000..b615f7c099b013 --- /dev/null +++ b/src/native/external/libunwind/doc/unw_get_elf_filename.man @@ -0,0 +1,110 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} +'\" t +.\" Manual page created with latex2man on Fri Sep 15 20:49:35 2023 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_GET\\_ELF\\_FILENAME" "3libunwind" "15 September 2023" "Programming Library " "Programming Library " +.SH NAME +unw_get_elf_filename +\-\- get backing elf filename +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +int +unw_get_elf_filename(unw_cursor_t *cp, +char *bufp, +size_t +len, +unw_word_t *offp); +.br +.PP +.SH DESCRIPTION + +.PP +The unw_get_elf_filename() +routine returns the backing elf +filename of the current instruction pointer that created the stack frame +identified by argument cp\&. +The bufp +argument is a pointer +to a character buffer that is at least len +bytes long. This buffer +is used to return the name of the procedure. The offp +argument is +a pointer to a word that is used to return the byte offset of the instruction +pointer saved in the stack frame identified by cp, +relative to the +start of the elf file. For embedded system the symbol information may has +been stripped from a program, then unw_get_proc_name() +may be +completely unavailable, if the host side have the unstripped program with +debuginfo, then can use addr2line +command tool on host to get the +source file name and line number of the instruction pointer, with the elf +filename in bufp +and address in offp\&. +.PP +.SH RETURN VALUE + +.PP +On successful completion, unw_get_elf_filename() +returns 0. +Otherwise the negative value of one of the error codes below is +returned. +.PP +.SH THREAD AND SIGNAL SAFETY + +.PP +unw_get_elf_filename() +is thread safe. If cursor cp +is +in the local address space, this routine is also safe to use from a +signal handler. +.PP +.SH ERRORS + +.PP +.TP +UNW_EUNSPEC + An unspecified error occurred. +.TP +UNW_ENOINFO + Libunwind +was unable to determine +the elf filename of the instruction pointer. +.TP +UNW_ENOMEM + The elf filename is too long to fit +in the buffer provided. A truncated version of the name has been +returned. +.PP +.SH SEE ALSO + +.PP +libunwind(3libunwind), +unw_get_proc_info(3libunwind) +unw_get_proc_name(3libunwind) +unw_get_elf_filename_by_ip(3libunwind) +addr2line(1addr2line) +.PP +.SH AUTHOR + +.PP +Xiang Lin +.br +Email: \fBmyd.xia@gmail.com\fP +.br +.\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/native/external/libunwind/doc/unw_get_elf_filename.tex b/src/native/external/libunwind/doc/unw_get_elf_filename.tex new file mode 100644 index 00000000000000..ea6f99e80d0d8e --- /dev/null +++ b/src/native/external/libunwind/doc/unw_get_elf_filename.tex @@ -0,0 +1,71 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3libunwind}{unw\_get\_elf\_filename}{Xiang Lin}{Programming Library}{unw\_get\_elf\_filename}unw\_get\_elf\_filename -- get backing elf filename +\end{Name} + +\section{Synopsis} + +\File{\#include $<$libunwind.h$>$}\\ + +\Type{int} \Func{unw\_get\_elf\_filename}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{char~*}\Var{bufp}, \Type{size\_t} \Var{len}, \Type{unw\_word\_t~*}\Var{offp});\\ + +\section{Description} + +The \Func{unw\_get\_elf\_filename}() routine returns the backing elf +filename of the current instruction pointer that created the stack frame +identified by argument \Var{cp}. The \Var{bufp} argument is a pointer +to a character buffer that is at least \Var{len} bytes long. This buffer +is used to return the name of the procedure. The \Var{offp} argument is +a pointer to a word that is used to return the byte offset of the instruction +pointer saved in the stack frame identified by \Var{cp}, relative to the +start of the elf file. For embedded system the symbol information may has +been stripped from a program, then \Func{unw\_get\_proc\_name}() may be +completely unavailable, if the host side have the unstripped program with +debuginfo, then can use \Prog{addr2line} command tool on host to get the +source file name and line number of the instruction pointer, with the elf +filename in \Var{bufp} and address in \Var{offp}. + +\section{Return Value} + +On successful completion, \Func{unw\_get\_elf\_filename}() returns 0. +Otherwise the negative value of one of the error codes below is +returned. + +\section{Thread and Signal Safety} + +\Func{unw\_get\_elf\_filename}() is thread safe. If cursor \Var{cp} is +in the local address space, this routine is also safe to use from a +signal handler. + +\section{Errors} + +\begin{Description} +\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred. +\item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to determine + the elf filename of the instruction pointer. +\item[\Const{UNW\_ENOMEM}] The elf filename is too long to fit + in the buffer provided. A truncated version of the name has been + returned. +\end{Description} + +\section{See Also} + +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_get\_proc\_info}(3libunwind) +\SeeAlso{unw\_get\_proc\_name}(3libunwind) +\SeeAlso{unw\_get\_elf\_filename\_by\_ip}(3libunwind) +\SeeAlso{addr2line}(1addr2line) + +\section{Author} + +\noindent +Xiang Lin\\ +Email: \Email{myd.xia@gmail.com}\\ +\LatexManEnd + +\end{document} diff --git a/src/native/external/libunwind/doc/unw_get_elf_filename_by_ip.man b/src/native/external/libunwind/doc/unw_get_elf_filename_by_ip.man new file mode 100644 index 00000000000000..51b976de497ede --- /dev/null +++ b/src/native/external/libunwind/doc/unw_get_elf_filename_by_ip.man @@ -0,0 +1,120 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} +'\" t +.\" Manual page created with latex2man on Fri Sep 15 20:49:35 2023 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_GET\\_ELF\\_FILENAME\\_BY\\_IP" "3libunwind" "15 September 2023" "Programming Library " "Programming Library " +.SH NAME +unw_get_elf_filename_by_ip +\-\- get backing elf filename by instruction pointer +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +int +unw_get_elf_filename_by_ip(unw_addr_space_t as, +unw_word_t ip, +char *bufp, +size_t +len, +unw_word_t *offp, +void *arg); +.br +.PP +.SH DESCRIPTION + +.PP +The unw_get_elf_filename_by_ip() +routine returns the backing +elf filename of a instruction pointer just like unw_get_elf_filename(), +except that the name is looked up by instruction pointer (IP) instead +of a cursor. +.PP +The routine expects the following arguments: as +is the +address\-space in which the instruction pointer should be looked up. +For a look\-up in the local address\-space, +unw_local_addr_space +can be passed for this argument. +Argument ip +is the instruction\-pointer for which the elf filename +should be looked up. The bufp +argument is a pointer to +a character buffer that is at least len +bytes long. This buffer +is used to return the elf filename. The offp +argument +is a pointer to a word that is used to return the byte offset of the +instruction\-pointer relative to the start of the elf filename. +Lastly, arg +is the address space argument that should be used +when accessing the address space. It has the same purpose as the +argument of the same name for unw_init_remote(). +When +accessing the local address space (first argument is +unw_local_addr_space), +NULL +must be passed for this +argument. +.PP +.SH RETURN VALUE + +.PP +On successful completion, unw_get_elf_filename_by_ip() +returns 0. Otherwise the negative value of one of the error codes +below is returned. +.PP +.SH THREAD AND SIGNAL SAFETY + +.PP +unw_get_elf_filename_by_ip() +is thread safe. If the local +address\-space is passed in argument as, +this routine is also +safe to use from a signal handler. +.PP +.SH ERRORS + +.PP +.TP +UNW_EUNSPEC + An unspecified error occurred. +.TP +UNW_ENOINFO + Libunwind +was unable to determine +the elf filename of the instruction pointer. +.TP +UNW_ENOMEM + The elf filename is too long to fit +in the buffer provided. A truncated version of the name has been +returned. +.PP +.SH SEE ALSO + +.PP +libunwind(3libunwind), +unw_get_elf_filename(3libunwind), +unw_create_addr_space(3libunwind), +unw_init_remote(3libunwind) +.PP +.SH AUTHOR + +.PP +Xiang Lin +.br +Email: \fBmyd.xia@gmail.com\fP +.br +.\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/native/external/libunwind/doc/unw_get_elf_filename_by_ip.tex b/src/native/external/libunwind/doc/unw_get_elf_filename_by_ip.tex new file mode 100644 index 00000000000000..5d625ec9a22ee8 --- /dev/null +++ b/src/native/external/libunwind/doc/unw_get_elf_filename_by_ip.tex @@ -0,0 +1,78 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3libunwind}{unw\_get\_elf\_filename\_by\_ip}{Xiang Lin}{Programming Library}{unw\_get\_elf\_filename}unw\_get\_elf\_filename\_by\_ip -- get backing elf filename by instruction pointer +\end{Name} + +\section{Synopsis} + +\File{\#include $<$libunwind.h$>$}\\ + +\Type{int} \Func{unw\_get\_elf\_filename\_by\_ip}(\Type{unw\_addr\_space\_t~}\Var{as}, \Type{unw\_word\_t~}\Var{ip}, \Type{char~*}\Var{bufp}, \Type{size\_t} \Var{len}, \Type{unw\_word\_t~*}\Var{offp}, \Type{void~*}\Var{arg});\\ + +\section{Description} + +The \Func{unw\_get\_elf\_filename\_by\_ip}() routine returns the backing +elf filename of a instruction pointer just like \Func{unw\_get\_elf\_filename}(), +except that the name is looked up by instruction pointer (IP) instead +of a cursor. + +The routine expects the following arguments: \Var{as} is the +address-space in which the instruction pointer should be looked up. +For a look-up in the local address-space, +\Var{unw\_local\_addr\_space} can be passed for this argument. +Argument \Var{ip} is the instruction-pointer for which the elf filename +should be looked up. The \Var{bufp} argument is a pointer to +a character buffer that is at least \Var{len} bytes long. This buffer +is used to return the elf filename. The \Var{offp} argument +is a pointer to a word that is used to return the byte offset of the +instruction-pointer relative to the start of the elf filename. +Lastly, \Var{arg} is the address space argument that should be used +when accessing the address space. It has the same purpose as the +argument of the same name for \Func{unw\_init\_remote}(). When +accessing the local address space (first argument is +\Var{unw\_local\_addr\_space}), \Const{NULL} must be passed for this +argument. + +\section{Return Value} + +On successful completion, \Func{unw\_get\_elf\_filename\_by\_ip}() +returns 0. Otherwise the negative value of one of the error codes +below is returned. + +\section{Thread and Signal Safety} + +\Func{unw\_get\_elf\_filename\_by\_ip}() is thread safe. If the local +address-space is passed in argument \Var{as}, this routine is also +safe to use from a signal handler. + +\section{Errors} + +\begin{Description} +\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred. +\item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to determine + the elf filename of the instruction pointer. +\item[\Const{UNW\_ENOMEM}] The elf filename is too long to fit + in the buffer provided. A truncated version of the name has been + returned. +\end{Description} + +\section{See Also} + +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_get\_elf\_filename}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_init\_remote}(3libunwind) + +\section{Author} + +\noindent +Xiang Lin\\ +Email: \Email{myd.xia@gmail.com}\\ +\LatexManEnd + +\end{document} diff --git a/src/native/external/libunwind/doc/unw_get_fpreg.man b/src/native/external/libunwind/doc/unw_get_fpreg.man index 5e54ca13d3bb52..02f26b7317ad79 100644 --- a/src/native/external/libunwind/doc/unw_get_fpreg.man +++ b/src/native/external/libunwind/doc/unw_get_fpreg.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:45:59 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_GET\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_FPREG" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_fpreg \-\- get contents of floating\-point register @@ -38,20 +40,20 @@ in the stack frame identified by cursor cp and stores the value in the variable pointed to by valp\&. .PP The register numbering is target\-dependent and described in separate -manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target). +manual pages (e.g., libunwind\-ia64(3libunwind) for the IA\-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that cp is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee\-saved\&'') registers and frame\-related registers (such as the stack\-pointer). However, for signal frames (see -unw_is_signal_frame(3)), +unw_is_signal_frame(3libunwind)), it is usually possible to access all registers. .PP Note that unw_get_fpreg() can only read the contents of -floating\-point registers. See unw_get_fpreg(3) +floating\-point registers. See unw_get_fpreg(3libunwind) for a way to read registers which fit in a single word. .PP @@ -60,14 +62,14 @@ read registers which fit in a single word. .PP On successful completion, unw_get_fpreg() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_get_fpreg() -is thread\-safe as well as safe to use +is thread safe as well as safe to use from a signal handler. .PP .SH ERRORS @@ -88,17 +90,17 @@ access_reg(), and access_fpreg() call\-backs (see -unw_create_addr_space(3)). +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -libunwind\-ia64(3), -unw_get_reg(3), -unw_is_fpreg(3), -unw_is_signal_frame(3), -unw_set_fpreg(3) +libunwind(3libunwind), +libunwind\-ia64(3libunwind), +unw_get_reg(3libunwind), +unw_is_fpreg(3libunwind), +unw_is_signal_frame(3libunwind), +unw_set_fpreg(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_fpreg.tex b/src/native/external/libunwind/doc/unw_get_fpreg.tex index dd679adc06ab75..25f100bf355fa8 100644 --- a/src/native/external/libunwind/doc/unw_get_fpreg.tex +++ b/src/native/external/libunwind/doc/unw_get_fpreg.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_get\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_get\_fpreg}unw\_get\_fpreg -- get contents of floating-point register +\begin{Name}{3libunwind}{unw\_get\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_get\_fpreg}unw\_get\_fpreg -- get contents of floating-point register \end{Name} \section{Synopsis} @@ -21,28 +21,28 @@ \section{Description} and stores the value in the variable pointed to by \Var{valp}. The register numbering is target-dependent and described in separate -manual pages (e.g., libunwind-ia64(3) for the IA-64 target). +manual pages (e.g., libunwind-ia64(3libunwind) for the IA-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that \Var{cp} is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee-saved'') registers and frame-related registers (such as the stack-pointer). However, for signal frames (see -\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access +\Func{unw\_is\_signal\_frame}(3libunwind)), it is usually possible to access all registers. Note that \Func{unw\_get\_fpreg}() can only read the contents of -floating-point registers. See \Func{unw\_get\_fpreg}(3) for a way to +floating-point registers. See \Func{unw\_get\_fpreg}(3libunwind) for a way to read registers which fit in a single word. \section{Return Value} On successful completion, \Func{unw\_get\_fpreg}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_get\_fpreg}() is thread-safe as well as safe to use +\Func{unw\_get\_fpreg}() is thread safe as well as safe to use from a signal handler. \section{Errors} @@ -55,16 +55,16 @@ \section{Errors} In addition, \Func{unw\_get\_fpreg}() may return any error returned by the \Func{access\_mem}(), \Func{access\_reg}(), and \Func{access\_fpreg}() call-backs (see -\Func{unw\_create\_addr\_space}(3)). +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{libunwind-ia64(3)}, -\SeeAlso{unw\_get\_reg(3)}, -\SeeAlso{unw\_is\_fpreg(3)}, -\SeeAlso{unw\_is\_signal\_frame(3)}, -\SeeAlso{unw\_set\_fpreg(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{libunwind-ia64}(3libunwind), +\SeeAlso{unw\_get\_reg}(3libunwind), +\SeeAlso{unw\_is\_fpreg}(3libunwind), +\SeeAlso{unw\_is\_signal\_frame}(3libunwind), +\SeeAlso{unw\_set\_fpreg}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_proc_info.man b/src/native/external/libunwind/doc/unw_get_proc_info.man index 5853e1ea8e443a..047dc940dffe2e 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_info.man +++ b/src/native/external/libunwind/doc/unw_get_proc_info.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Sun Aug 29 23:45:06 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_GET\\_PROC\\_INFO" "3" "29 August 2021" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_PROC\\_INFO" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_proc_info \-\- get info on current procedure @@ -59,7 +61,7 @@ member is cleared to 0. .TP unw_word_t lsda The address of the -language\-specific data\-area (LSDA). This area normally contains +language\-specific data area (LSDA). This area normally contains language\-specific information needed during exception handling. If the procedure has no such area, this member is cleared to 0. .br @@ -73,11 +75,11 @@ member is cleared to 0. .br .TP unw_word_t gp - The global\-pointer of the + The global pointer of the procedure. On platforms that do not use a global pointer, this member may contain an undefined value. On all other platforms, it -must be set either to the correct global\-pointer value of the -procedure or to 0 if the proper global\-pointer cannot be +must be set either to the correct global pointer value of the +procedure or to 0 if the proper global pointer cannot be obtained for some reason. .br .TP @@ -86,23 +88,23 @@ unw_word_t flags currently no target\-independent flags. For the IA\-64 target, the flag UNW_PI_FLAG_IA64_RBS_SWITCH is set if the -procedure may switch the register\-backing store. +procedure may switch the register backing store. .br .TP int format - The format of the unwind\-info for this -procedure. If the unwind\-info consists of dynamic procedure info, + The format of the unwind info for this +procedure. If the unwind info consists of dynamic procedure info, format is equal to UNW_INFO_FORMAT_DYNAMIC\&. If the -unwind\-info consists of a (target\-specific) unwind table, it is +unwind info consists of a (target\-specific) unwind table, it is equal to UNW_INFO_FORMAT_TABLE\&. All other values are reserved for future use by libunwind\&. This member exists for use by the find_proc_info() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). The unw_get_proc_info() routine @@ -110,11 +112,11 @@ may return an undefined value in this member. .br .TP int unwind_info_size - The size of the unwind\-info + The size of the unwind info in bytes. This member exists for use by the find_proc_info() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). The unw_get_proc_info() routine @@ -122,13 +124,13 @@ may return an undefined value in this member. .br .TP void *unwind_info - The pointer to the unwind\-info. + The pointer to the unwind info. If no unwind info is available, this member must be set to NULL\&. This member exists for use by the find_proc_info() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). The unw_get_proc_info() routine @@ -151,16 +153,16 @@ separate procedure. .PP On successful completion, unw_get_proc_info() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_get_proc_info() -is thread\-safe. If cursor cp +is thread safe. If cursor cp is -in the local address\-space, this routine is also safe to use from a +in the local address space, this routine is also safe to use from a signal handler. .PP .SH ERRORS @@ -173,24 +175,24 @@ UNW_EUNSPEC UNW_ENOINFO Libunwind was unable to locate -unwind\-info for the procedure. +unwind info for the procedure. .TP UNW_EBADVERSION - The unwind\-info for the procedure has + The unwind info for the procedure has version or format that is not understood by libunwind\&. .PP In addition, unw_get_proc_info() may return any error returned by the access_mem() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3), -unw_get_proc_name(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +unw_get_proc_name(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_proc_info.tex b/src/native/external/libunwind/doc/unw_get_proc_info.tex index 00377e4177d312..41735fa8915565 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_info.tex +++ b/src/native/external/libunwind/doc/unw_get_proc_info.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_get\_proc\_info}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info}unw\_get\_proc\_info -- get info on current procedure +\begin{Name}{3libunwind}{unw\_get\_proc\_info}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info}unw\_get\_proc\_info -- get info on current procedure \end{Name} \section{Synopsis} @@ -32,44 +32,44 @@ \section{Description} cannot be determined (e.g., due to lack of unwind information), the \Var{end\_ip} member is cleared to 0. \\ \item[\Type{unw\_word\_t} \Var{lsda}] The address of the - language-specific data-area (LSDA). This area normally contains + language-specific data area (LSDA). This area normally contains language-specific information needed during exception handling. If the procedure has no such area, this member is cleared to 0. \\ \item[\Type{unw\_word\_t} \Var{handler}] The address of the exception handler routine. This is sometimes called the \emph{personality} routine. If the procedure does not define a personality routine, the \Var{handler} member is cleared to 0. \\ -\item[\Type{unw\_word\_t} \Var{gp}] The global-pointer of the +\item[\Type{unw\_word\_t} \Var{gp}] The global pointer of the procedure. On platforms that do not use a global pointer, this member may contain an undefined value. On all other platforms, it - must be set either to the correct global-pointer value of the - procedure or to 0 if the proper global-pointer cannot be + must be set either to the correct global pointer value of the + procedure or to 0 if the proper global pointer cannot be obtained for some reason. \\ \item[\Type{unw\_word\_t} \Var{flags}] A set of flags. There are currently no target-independent flags. For the IA-64 target, the flag \Const{UNW\_PI\_FLAG\_IA64\_RBS\_SWITCH} is set if the - procedure may switch the register-backing store.\\ -\item[\Type{int} \Var{format}] The format of the unwind-info for this - procedure. If the unwind-info consists of dynamic procedure info, + procedure may switch the register backing store.\\ +\item[\Type{int} \Var{format}] The format of the unwind info for this + procedure. If the unwind info consists of dynamic procedure info, \Var{format} is equal to \Const{UNW\_INFO\_FORMAT\_DYNAMIC}. If the - unwind-info consists of a (target-specific) unwind table, it is + unwind info consists of a (target-specific) unwind table, it is equal to \Const{UNW\_INFO\_FORMAT\_TABLE}. All other values are reserved for future use by \Prog{libunwind}. This member exists - for use by the \Func{find\_proc\_info}() call-back (see - \Func{unw\_create\_addr\_space}(3)). The + for use by the \Func{find\_proc\_info}() callback (see + \Func{unw\_create\_addr\_space}(3libunwind)). The \Func{unw\_get\_proc\_info}() routine may return an undefined value in this member. \\ -\item[\Type{int} \Var{unwind\_info\_size}] The size of the unwind-info +\item[\Type{int} \Var{unwind\_info\_size}] The size of the unwind info in bytes. This member exists for use by the - \Func{find\_proc\_info}() call-back (see - \Func{unw\_create\_addr\_space}(3)). The + \Func{find\_proc\_info}() callback (see + \Func{unw\_create\_addr\_space}(3libunwind)). The \Func{unw\_get\_proc\_info}() routine may return an undefined value in this member.\\ -\item[\Type{void~*}\Var{unwind\_info}] The pointer to the unwind-info. +\item[\Type{void~*}\Var{unwind\_info}] The pointer to the unwind info. If no unwind info is available, this member must be set to \Const{NULL}. This member exists for use by the - \Func{find\_proc\_info}() call-back (see - \Func{unw\_create\_addr\_space}(3)). The + \Func{find\_proc\_info}() callback (see + \Func{unw\_create\_addr\_space}(3libunwind)). The \Func{unw\_get\_proc\_info}() routine may return an undefined value in this member.\\ \end{description} @@ -84,13 +84,13 @@ \section{Description} \section{Return Value} On successful completion, \Func{unw\_get\_proc\_info}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_get\_proc\_info}() is thread-safe. If cursor \Var{cp} is -in the local address-space, this routine is also safe to use from a +\Func{unw\_get\_proc\_info}() is thread safe. If cursor \Var{cp} is +in the local address space, this routine is also safe to use from a signal handler. \section{Errors} @@ -98,19 +98,19 @@ \section{Errors} \begin{Description} \item[\Const{UNW\_EUNSPEC}] An unspecified error occurred. \item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to locate - unwind-info for the procedure. -\item[\Const{UNW\_EBADVERSION}] The unwind-info for the procedure has + unwind info for the procedure. +\item[\Const{UNW\_EBADVERSION}] The unwind info for the procedure has version or format that is not understood by \Prog{libunwind}. \end{Description} In addition, \Func{unw\_get\_proc\_info}() may return any error -returned by the \Func{access\_mem}() call-back (see -\Func{unw\_create\_addr\_space}(3)). +returned by the \Func{access\_mem}() callback (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_get\_proc\_name(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_get\_proc\_name}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.man b/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.man index 35771d0107a77a..360384c7b5fc19 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.man +++ b/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Sun Aug 29 23:45:06 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 11:45:59 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_GET\\_PROC\\_INFO\\_BY\\_IP" "3" "29 August 2021" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_PROC\\_INFO\\_BY\\_IP" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_proc_info_by_ip \-\- get procedure info by IP @@ -38,13 +40,13 @@ unw_get_proc_info(), except that the info is looked up by instruction\-pointer (IP) instead of a cursor. This is more flexible because it is possible to look up the info for an arbitrary procedure, -even if it is not part of the current call\-chain. However, since it +even if it is not part of the current call chain. However, since it is more flexible, it also tends to run slower (and often much slower) than unw_get_proc_info(). .PP The routine expects the following arguments: as is the -address\-space in which the instruction\-pointer should be looked up. +address\-space in which the instruction pointer should be looked up. For a look\-up in the local address\-space, unw_local_addr_space can be passed for this argument. @@ -55,11 +57,11 @@ is a pointer to a structure of type unw_proc_info_t which is used to return the info. Lastly, arg -is the address\-space argument that should be used -when accessing the address\-space. It has the same purpose as the +is the address space argument that should be used +when accessing the address space. It has the same purpose as the argument of the same name for unw_init_remote(). When -accessing the local address\-space (first argument is +accessing the local address space (first argument is unw_local_addr_space), NULL must be passed for this @@ -87,8 +89,8 @@ below is returned. .PP unw_get_proc_info_by_ip() -is thread\-safe. If the local -address\-space is passed in argument as, +is thread safe. If the local +address space is passed in argument as, this routine is also safe to use from a signal handler. .PP @@ -111,17 +113,17 @@ version or format that is not understood by libunwind\&. In addition, unw_get_proc_info_by_ip() may return any error returned by the access_mem() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3), -unw_get_proc_name(3), -unw_get_proc_info(3), -unw_init_remote(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +unw_get_proc_name(3libunwind), +unw_get_proc_info(3libunwind), +unw_init_remote(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.tex b/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.tex index 3c7c4af01db64c..36d8c05695477d 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.tex +++ b/src/native/external/libunwind/doc/unw_get_proc_info_by_ip.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_get\_proc\_info\_by\_ip}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info\_by\_ip}unw\_get\_proc\_info\_by\_ip -- get procedure info by IP +\begin{Name}{3libunwind}{unw\_get\_proc\_info\_by\_ip}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info\_by\_ip}unw\_get\_proc\_info\_by\_ip -- get procedure info by IP \end{Name} \section{Synopsis} @@ -21,21 +21,21 @@ \section{Description} \Func{unw\_get\_proc\_info}(), except that the info is looked up by instruction-pointer (IP) instead of a cursor. This is more flexible because it is possible to look up the info for an arbitrary procedure, -even if it is not part of the current call-chain. However, since it +even if it is not part of the current call chain. However, since it is more flexible, it also tends to run slower (and often much slower) than \Func{unw\_get\_proc\_info}(). The routine expects the following arguments: \Var{as} is the -address-space in which the instruction-pointer should be looked up. +address-space in which the instruction pointer should be looked up. For a look-up in the local address-space, \Var{unw\_local\_addr\_space} can be passed for this argument. Argument \Var{ip} is the instruction-pointer for which the procedure info should be looked up and \Var{pip} is a pointer to a structure of type \Type{unw\_proc\_info\_t} which is used to return the info. -Lastly, \Var{arg} is the address-space argument that should be used -when accessing the address-space. It has the same purpose as the +Lastly, \Var{arg} is the address space argument that should be used +when accessing the address space. It has the same purpose as the argument of the same name for \Func{unw\_init\_remote}(). When -accessing the local address-space (first argument is +accessing the local address space (first argument is \Var{unw\_local\_addr\_space}), \Const{NULL} must be passed for this argument. @@ -55,8 +55,8 @@ \section{Return Value} \section{Thread and Signal Safety} -\Func{unw\_get\_proc\_info\_by\_ip}() is thread-safe. If the local -address-space is passed in argument \Var{as}, this routine is also +\Func{unw\_get\_proc\_info\_by\_ip}() is thread safe. If the local +address space is passed in argument \Var{as}, this routine is also safe to use from a signal handler. \section{Errors} @@ -69,16 +69,16 @@ \section{Errors} version or format that is not understood by \Prog{libunwind}. \end{Description} In addition, \Func{unw\_get\_proc\_info\_by\_ip}() may return any -error returned by the \Func{access\_mem}() call-back (see -\Func{unw\_create\_addr\_space}(3)). +error returned by the \Func{access\_mem}() callback (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_get\_proc\_name(3)}, -\SeeAlso{unw\_get\_proc\_info(3)}, -\SeeAlso{unw\_init\_remote(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_get\_proc\_name}(3libunwind), +\SeeAlso{unw\_get\_proc\_info}(3libunwind), +\SeeAlso{unw\_init\_remote}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_proc_info_in_range.man b/src/native/external/libunwind/doc/unw_get_proc_info_in_range.man index 6b8836607fa019..556731f8015db7 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_info_in_range.man +++ b/src/native/external/libunwind/doc/unw_get_proc_info_in_range.man @@ -1,7 +1,7 @@ .\" *********************************** start of \input{common.tex} .\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Wed Jun 29 18:53:42 2022 +.\" Manual page created with latex2man on Tue Aug 29 11:45:59 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -12,7 +12,7 @@ .fi .. -.TH "UNW\\_GET\\_PROC\\_INFO\\_IN\\_RANGE" "3" "29 June 2022" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_PROC\\_INFO\\_IN\\_RANGE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_proc_info_in_range \-\- get procedure info in IP range and a frame index table @@ -42,9 +42,9 @@ routine returns the same kind of auxiliary information about a procedure as unw_get_proc_info_by_ip(), except that the info is looked up in -instruction\-pointer (IP) range and frame table instead of just at IP. This +instruction pointer (IP) range and frame table instead of just at IP. This is equally flexible because it is possible to look up the info for an arbitrary -procedure, even if it is not part of the current call\-chain. However, since it +procedure, even if it is not part of the current call chain. However, since it is more flexible, it also tends to run slower (and often much slower) than unw_get_proc_info(). .PP @@ -59,8 +59,8 @@ below is returned. .PP unw_get_proc_info_in_range() -is thread\-safe. If the local -address\-space is passed in argument as, +is thread safe. If the local +address space is passed in argument as, this routine is also safe to use from a signal handler. .PP @@ -86,17 +86,17 @@ UNW_EINVAL In addition, unw_get_proc_info_by_ip() may return any error returned by the access_mem() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_get_proc_info_in_range(3), -unw_create_addr_space(3), -unw_get_proc_name(3), -unw_get_proc_info(3) +libunwind(3libunwind), +unw_get_proc_info_in_range(3libunwind), +unw_create_addr_space(3libunwind), +unw_get_proc_name(3libunwind), +unw_get_proc_info(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_proc_info_in_range.tex b/src/native/external/libunwind/doc/unw_get_proc_info_in_range.tex index 8caaea85ad5404..59db019c482b64 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_info_in_range.tex +++ b/src/native/external/libunwind/doc/unw_get_proc_info_in_range.tex @@ -5,23 +5,23 @@ \begin{document} -\begin{Name}{3}{unw\_get\_proc\_info\_in\_range}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info\_in\_range}unw\_get\_proc\_info\_in\_range -- get procedure info in IP range and a frame index table +\begin{Name}{3libunwind}{unw\_get\_proc\_info\_in\_range}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info\_in\_range}unw\_get\_proc\_info\_in\_range -- get procedure info in IP range and a frame index table \end{Name} \section{Synopsis} \File{\#include $<$libunwind.h$>$}\\ -\Type{int} \Func{unw\_get\_proc\_info\_in\_range}(\Type{unw\_word\_t~}\Var{start_ip}, \Type{unw\_word\_t~}\Var{end_ip}, \Type{unw\_word\_t~}\Var{eh_frame_table}, \Type{unw\_word\_t~}\Var{eh_frame_table_len}, \Type{unw\_word\_t~}\Var{exidx_frame_table}, \Type{unw\_word\_t~}\Var{exidx_frame_table_len,}, \Type{unw\_addr\_space\_t~*}\Var{as}, \Type{void~*}\Var{arg});\\ +\Type{int} \Func{unw\_get\_proc\_info\_in\_range}(\Type{unw\_word\_t~}\Var{start\_ip}, \Type{unw\_word\_t~}\Var{end_ip}, \Type{unw\_word\_t~}\Var{eh_frame_table}, \Type{unw\_word\_t~}\Var{eh_frame_table_len}, \Type{unw\_word\_t~}\Var{exidx_frame_table}, \Type{unw\_word\_t~}\Var{exidx_frame_table_len,}, \Type{unw\_addr\_space\_t~*}\Var{as}, \Type{void~*}\Var{arg});\\ \section{Description} The \Func{unw\_get\_proc\_info\_in\_range}() routine returns the same kind of auxiliary information about a procedure as \Func{unw\_get\_proc\_info\_by\_ip}(), except that the info is looked up in -instruction-pointer (IP) range and frame table instead of just at IP. This +instruction pointer (IP) range and frame table instead of just at IP. This is equally flexible because it is possible to look up the info for an arbitrary -procedure, even if it is not part of the current call-chain. However, since it +procedure, even if it is not part of the current call chain. However, since it is more flexible, it also tends to run slower (and often much slower) than \Func{unw\_get\_proc\_info}(). @@ -33,8 +33,8 @@ \section{Return Value} \section{Thread and Signal Safety} -\Func{unw\_get\_proc\_info\_in\_range}() is thread-safe. If the local -address-space is passed in argument \Var{as}, this routine is also +\Func{unw\_get\_proc\_info\_in\_range}() is thread safe. If the local +address space is passed in argument \Var{as}, this routine is also safe to use from a signal handler. \section{Errors} @@ -48,16 +48,16 @@ \section{Errors} \item[\Const{UNW\_EINVAL}] An unsupported table encoding was specified. \end{Description} In addition, \Func{unw\_get\_proc\_info\_by\_ip}() may return any -error returned by the \Func{access\_mem}() call-back (see -\Func{unw\_create\_addr\_space}(3)). +error returned by the \Func{access\_mem}() callback (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_get\_proc\_info\_in\_range(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_get\_proc\_name(3)}, -\SeeAlso{unw\_get\_proc\_info(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_get\_proc\_info\_in\_range}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_get\_proc\_name}(3libunwind), +\SeeAlso{unw\_get\_proc\_info}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_proc_name.man b/src/native/external/libunwind/doc/unw_get_proc_name.man index 0240604823bc06..bcae61e9d60a75 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_name.man +++ b/src/native/external/libunwind/doc/unw_get_proc_name.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Sun Aug 29 23:45:06 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_GET\\_PROC\\_NAME" "3" "29 August 2021" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_PROC\\_NAME" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_proc_name \-\- get name of current procedure @@ -42,14 +44,14 @@ that is at least len bytes long. This buffer is used to return the name of the procedure. The offp argument is a pointer to a -word that is used to return the byte\-offset of the instruction\-pointer +word that is used to return the byte offset of the instruction\-pointer saved in the stack frame identified by cp, relative to the start of the procedure. For example, if procedure foo() starts at address 0x40003000, then invoking unw_get_proc_name() on a -stack frame with an instruction\-pointer value of 0x40003080 would +stack frame with an instruction pointer value of 0x40003080 would return a value of 0x80 in the word pointed to by offp (assuming the procedure is at least 0x80 bytes long). @@ -64,23 +66,23 @@ However, the offset returned through offp is always relative to the returned name, which ensures that the value (address) of the returned name plus the returned offset will always be equal to the -instruction\-pointer of the stack frame identified by cp\&. +instruction pointer of the stack frame identified by cp\&. .PP .SH RETURN VALUE .PP On successful completion, unw_get_proc_name() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_get_proc_name() -is thread\-safe. If cursor cp +is thread safe. If cursor cp is -in the local address\-space, this routine is also safe to use from a +in the local address space, this routine is also safe to use from a signal handler. .PP .SH ERRORS @@ -103,14 +105,14 @@ returned. In addition, unw_get_proc_name() may return any error returned by the access_mem() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_get_proc_info(3) +libunwind(3libunwind), +unw_get_proc_info(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_proc_name.tex b/src/native/external/libunwind/doc/unw_get_proc_name.tex index 028d6716728064..edcc357eff7087 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_name.tex +++ b/src/native/external/libunwind/doc/unw_get_proc_name.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_get\_proc\_name}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_name}unw\_get\_proc\_name -- get name of current procedure +\begin{Name}{3libunwind}{unw\_get\_proc\_name}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_name}unw\_get\_proc\_name -- get name of current procedure \end{Name} \section{Synopsis} @@ -21,11 +21,11 @@ \section{Description} \Var{cp}. The \Var{bufp} argument is a pointer to a character buffer that is at least \Var{len} bytes long. This buffer is used to return the name of the procedure. The \Var{offp} argument is a pointer to a -word that is used to return the byte-offset of the instruction-pointer +word that is used to return the byte offset of the instruction-pointer saved in the stack frame identified by \Var{cp}, relative to the start of the procedure. For example, if procedure \Func{foo}() starts at address 0x40003000, then invoking \Func{unw\_get\_proc\_name}() on a -stack frame with an instruction-pointer value of 0x40003080 would +stack frame with an instruction pointer value of 0x40003080 would return a value of 0x80 in the word pointed to by \Var{offp} (assuming the procedure is at least 0x80 bytes long). @@ -38,18 +38,18 @@ \section{Description} However, the offset returned through \Var{offp} is always relative to the returned name, which ensures that the value (address) of the returned name plus the returned offset will always be equal to the -instruction-pointer of the stack frame identified by \Var{cp}. +instruction pointer of the stack frame identified by \Var{cp}. \section{Return Value} On successful completion, \Func{unw\_get\_proc\_name}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_get\_proc\_name}() is thread-safe. If cursor \Var{cp} is -in the local address-space, this routine is also safe to use from a +\Func{unw\_get\_proc\_name}() is thread safe. If cursor \Var{cp} is +in the local address space, this routine is also safe to use from a signal handler. \section{Errors} @@ -63,13 +63,13 @@ \section{Errors} returned. \end{Description} In addition, \Func{unw\_get\_proc\_name}() may return any error -returned by the \Func{access\_mem}() call-back (see -\Func{unw\_create\_addr\_space}(3)). +returned by the \Func{access\_mem}() callback (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_get\_proc\_info(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_get\_proc\_info}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.man b/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.man index 70b10aaead2a1b..4537f261d6b4c3 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.man +++ b/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Mon Aug 30 08:48:42 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,10 +12,10 @@ .fi .. -.TH "UNW\\_GET\\_PROC\\_NAME\\_BY\\_IP" "3" "30 August 2021" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_PROC\\_NAME\\_BY\\_IP" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_proc_name_by_ip -\-\- get procedure name +\-\- get procedure name .PP .SH SYNOPSIS @@ -35,98 +37,98 @@ void *arg); .PP The unw_get_proc_name_by_ip() -routine returns the name of +routine returns the name of a procedure just like unw_get_proc_name(), -except that the -name is looked up by instruction\-pointer (IP) instead of a cursor. +except that the +name is looked up by instruction pointer (IP) instead of a cursor. .PP The routine expects the following arguments: as -is the -address\-space in which the instruction\-pointer should be looked up. -For a look\-up in the local address\-space, +is the +address\-space in which the instruction pointer should be looked up. +For a look\-up in the local address\-space, unw_local_addr_space -can be passed for this argument. +can be passed for this argument. Argument ip -is the instruction\-pointer for which the procedure +is the instruction\-pointer for which the procedure name should be looked up. The bufp -argument is a pointer to +argument is a pointer to a character buffer that is at least len -bytes long. This buffer +bytes long. This buffer is used to return the name of the procedure. The offp -argument -is a pointer to a word that is used to return the byte\-offset of the -instruction\-pointer relative to the start of the procedure. +argument +is a pointer to a word that is used to return the byte offset of the +instruction\-pointer relative to the start of the procedure. Lastly, arg -is the address\-space argument that should be used -when accessing the address\-space. It has the same purpose as the +is the address space argument that should be used +when accessing the address space. It has the same purpose as the argument of the same name for unw_init_remote(). -When -accessing the local address\-space (first argument is +When +accessing the local address space (first argument is unw_local_addr_space), NULL -must be passed for this -argument. -.PP -Note that on some platforms there is no reliable way to distinguish -between procedure names and ordinary labels. Furthermore, if symbol -information has been stripped from a program, procedure names may be -completely unavailable or may be limited to those exported via a -dynamic symbol table. In such cases, +must be passed for this +argument. +.PP +Note that on some platforms there is no reliable way to distinguish +between procedure names and ordinary labels. Furthermore, if symbol +information has been stripped from a program, procedure names may be +completely unavailable or may be limited to those exported via a +dynamic symbol table. In such cases, unw_get_proc_name_by_ip() -may return the name of a label -or a preceding (nearby) procedure. However, the offset returned +may return the name of a label +or a preceding (nearby) procedure. However, the offset returned through offp -is always relative to the returned name, which -ensures that the value (address) of the returned name plus the -returned offset will always be equal to the instruction\-pointer +is always relative to the returned name, which +ensures that the value (address) of the returned name plus the +returned offset will always be equal to the instruction pointer ip\&. .PP .SH RETURN VALUE .PP On successful completion, unw_get_proc_name_by_ip() -returns 0. Otherwise the negative value of one of the error\-codes -below is returned. +returns 0. Otherwise the negative value of one of the error codes +below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_get_proc_name_by_ip() -is thread\-safe. If the local +is thread safe. If the local address\-space is passed in argument as, -this routine is also -safe to use from a signal handler. +this routine is also +safe to use from a signal handler. .PP .SH ERRORS .PP .TP UNW_EUNSPEC - An unspecified error occurred. + An unspecified error occurred. .TP UNW_ENOINFO Libunwind -was unable to determine -the name of the procedure. +was unable to determine +the name of the procedure. .TP UNW_ENOMEM - The procedure name is too long to fit -in the buffer provided. A truncated version of the name has been -returned. + The procedure name is too long to fit +in the buffer provided. A truncated version of the name has been +returned. .PP In addition, unw_get_proc_name_by_ip() -may return any error +may return any error returned by the access_mem() -call\-back (see -unw_create_addr_space(3)). +callback (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3), -unw_get_proc_name(3), -unw_init_remote(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +unw_get_proc_name(3libunwind), +unw_init_remote(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.tex b/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.tex index cb59768070bc19..5dae010fbe5d02 100644 --- a/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.tex +++ b/src/native/external/libunwind/doc/unw_get_proc_name_by_ip.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_get\_proc\_name\_by\_ip}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_name}unw\_get\_proc\_name\_by\_ip -- get procedure name +\begin{Name}{3libunwind}{unw\_get\_proc\_name\_by\_ip}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_name}unw\_get\_proc\_name\_by\_ip -- get procedure name \end{Name} \section{Synopsis} @@ -18,22 +18,22 @@ \section{Description} The \Func{unw\_get\_proc\_name\_by\_ip}() routine returns the name of a procedure just like \Func{unw\_get\_proc\_name}(), except that the -name is looked up by instruction-pointer (IP) instead of a cursor. +name is looked up by instruction pointer (IP) instead of a cursor. The routine expects the following arguments: \Var{as} is the -address-space in which the instruction-pointer should be looked up. +address-space in which the instruction pointer should be looked up. For a look-up in the local address-space, \Var{unw\_local\_addr\_space} can be passed for this argument. Argument \Var{ip} is the instruction-pointer for which the procedure name should be looked up. The \Var{bufp} argument is a pointer to a character buffer that is at least \Var{len} bytes long. This buffer is used to return the name of the procedure. The \Var{offp} argument -is a pointer to a word that is used to return the byte-offset of the +is a pointer to a word that is used to return the byte offset of the instruction-pointer relative to the start of the procedure. -Lastly, \Var{arg} is the address-space argument that should be used -when accessing the address-space. It has the same purpose as the +Lastly, \Var{arg} is the address space argument that should be used +when accessing the address space. It has the same purpose as the argument of the same name for \Func{unw\_init\_remote}(). When -accessing the local address-space (first argument is +accessing the local address space (first argument is \Var{unw\_local\_addr\_space}), \Const{NULL} must be passed for this argument. @@ -46,18 +46,18 @@ \section{Description} or a preceding (nearby) procedure. However, the offset returned through \Var{offp} is always relative to the returned name, which ensures that the value (address) of the returned name plus the -returned offset will always be equal to the instruction-pointer +returned offset will always be equal to the instruction pointer \Var{ip}. \section{Return Value} On successful completion, \Func{unw\_get\_proc\_name\_by\_ip}() -returns 0. Otherwise the negative value of one of the error-codes +returns 0. Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_get\_proc\_name\_by\_ip}() is thread-safe. If the local +\Func{unw\_get\_proc\_name\_by\_ip}() is thread safe. If the local address-space is passed in argument \Var{as}, this routine is also safe to use from a signal handler. @@ -72,15 +72,15 @@ \section{Errors} returned. \end{Description} In addition, \Func{unw\_get\_proc\_name\_by\_ip}() may return any error -returned by the \Func{access\_mem}() call-back (see -\Func{unw\_create\_addr\_space}(3)). +returned by the \Func{access\_mem}() callback (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_get\_proc\_name(3)}, -\SeeAlso{unw\_init\_remote(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_get\_proc\_name}(3libunwind), +\SeeAlso{unw\_init\_remote}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_get_reg.man b/src/native/external/libunwind/doc/unw_get_reg.man index 83e8bb43b64f4b..da092cdd8c551f 100644 --- a/src/native/external/libunwind/doc/unw_get_reg.man +++ b/src/native/external/libunwind/doc/unw_get_reg.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_GET\\_REG" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_GET\\_REG" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_get_reg \-\- get register contents @@ -38,22 +40,22 @@ in the stack frame identified by cursor cp and stores the value in the word pointed to by valp\&. .PP -The register numbering is target\-dependent and described in separate -manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target). +The register numbering is target dependent and described in separate +manual pages (e.g., libunwind\-ia64(3libunwind) for the IA\-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that cp is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee\-saved\&'') registers and frame\-related registers (such as the stack\-pointer). However, for signal frames (see -unw_is_signal_frame(3)), +unw_is_signal_frame(3libunwind)), it is usually possible to access all registers. .PP Note that unw_get_reg() can only read the contents of registers whose values fit in a single word. See -unw_get_fpreg(3) +unw_get_fpreg(3libunwind) for a way to read registers which do not fit this constraint. .PP @@ -62,14 +64,14 @@ this constraint. .PP On successful completion, unw_get_reg() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_get_reg() -is thread\-safe as well as safe to use +is thread safe as well as safe to use from a signal handler. .PP .SH ERRORS @@ -89,17 +91,17 @@ the access_mem(), access_reg(), and access_fpreg() -call\-backs (see -unw_create_addr_space(3)). +callbacks (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -libunwind\-ia64(3), -unw_get_fpreg(3), -unw_is_signal_frame(3), -unw_set_reg(3) +libunwind(3libunwind), +libunwind\-ia64(3libunwind), +unw_get_fpreg(3libunwind), +unw_is_signal_frame(3libunwind), +unw_set_reg(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_get_reg.tex b/src/native/external/libunwind/doc/unw_get_reg.tex index b66e8c0dbb4265..203729bac919a5 100644 --- a/src/native/external/libunwind/doc/unw_get_reg.tex +++ b/src/native/external/libunwind/doc/unw_get_reg.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_get\_reg}{David Mosberger-Tang}{Programming Library}{unw\_get\_reg}unw\_get\_reg -- get register contents +\begin{Name}{3libunwind}{unw\_get\_reg}{David Mosberger-Tang}{Programming Library}{unw\_get\_reg}unw\_get\_reg -- get register contents \end{Name} \section{Synopsis} @@ -20,30 +20,30 @@ \section{Description} \Var{reg} in the stack frame identified by cursor \Var{cp} and stores the value in the word pointed to by \Var{valp}. -The register numbering is target-dependent and described in separate -manual pages (e.g., libunwind-ia64(3) for the IA-64 target). +The register numbering is target dependent and described in separate +manual pages (e.g., libunwind-ia64(3libunwind) for the IA-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that \Var{cp} is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee-saved'') registers and frame-related registers (such as the stack-pointer). However, for signal frames (see -\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access +\Func{unw\_is\_signal\_frame}(3libunwind)), it is usually possible to access all registers. Note that \Func{unw\_get\_reg}() can only read the contents of registers whose values fit in a single word. See -\Func{unw\_get\_fpreg}(3) for a way to read registers which do not fit +\Func{unw\_get\_fpreg}(3libunwind) for a way to read registers which do not fit this constraint. \section{Return Value} On successful completion, \Func{unw\_get\_reg}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_get\_reg}() is thread-safe as well as safe to use +\Func{unw\_get\_reg}() is thread safe as well as safe to use from a signal handler. \section{Errors} @@ -55,16 +55,16 @@ \section{Errors} \end{Description} In addition, \Func{unw\_get\_reg}() may return any error returned by the \Func{access\_mem}(), \Func{access\_reg}(), and -\Func{access\_fpreg}() call-backs (see -\Func{unw\_create\_addr\_space}(3)). +\Func{access\_fpreg}() callbacks (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{libunwind-ia64(3)}, -\SeeAlso{unw\_get\_fpreg(3)}, -\SeeAlso{unw\_is\_signal\_frame(3)}, -\SeeAlso{unw\_set\_reg(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{libunwind-ia64}(3libunwind), +\SeeAlso{unw\_get\_fpreg}(3libunwind), +\SeeAlso{unw\_is\_signal\_frame}(3libunwind), +\SeeAlso{unw\_set\_reg}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_getcontext.man b/src/native/external/libunwind/doc/unw_getcontext.man index 13725df9570cfa..2831402f8453cf 100644 --- a/src/native/external/libunwind/doc/unw_getcontext.man +++ b/src/native/external/libunwind/doc/unw_getcontext.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 12:09:48 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_GETCONTEXT" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_GETCONTEXT" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_getcontext \-\- get initial machine\-state @@ -31,12 +33,12 @@ unw_getcontext(unw_context_t *ucp); The unw_getcontext() routine initializes the context structure pointed to by ucp -with the machine\-state of the call\-site. The +with the machine state of the call site. The exact set of registers stored by unw_getcontext() is platform\-specific, but, in general, at least all preserved (``callee\-saved\&'') and all frame\-related registers, such as the -stack\-pointer, will be stored. +stack pointer, will be stored. .PP This routine is normally implemented as a macro and applications should not attempt to take its address. @@ -73,14 +75,14 @@ Otherwise, a value of \-1 is returned. .PP unw_getcontext() -is thread\-safe as well as safe to use +is thread safe as well as safe to use from a signal handler. .PP .SH SEE ALSO .PP -libunwind(3), -unw_init_local(3) +libunwind(3libunwind), +unw_init_local(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_getcontext.tex b/src/native/external/libunwind/doc/unw_getcontext.tex index fa3eb814b3f650..b0b54f658fe18e 100644 --- a/src/native/external/libunwind/doc/unw_getcontext.tex +++ b/src/native/external/libunwind/doc/unw_getcontext.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_getcontext}{David Mosberger-Tang}{Programming Library}{unw\_getcontext}unw\_getcontext -- get initial machine-state +\begin{Name}{3libunwind}{unw\_getcontext}{David Mosberger-Tang}{Programming Library}{unw\_getcontext}unw\_getcontext -- get initial machine-state \end{Name} \section{Synopsis} @@ -17,11 +17,11 @@ \section{Synopsis} \section{Description} The \Func{unw\_getcontext}() routine initializes the context structure -pointed to by \Var{ucp} with the machine-state of the call-site. The +pointed to by \Var{ucp} with the machine state of the call site. The exact set of registers stored by \Func{unw\_getcontext}() is platform-specific, but, in general, at least all preserved (``callee-saved'') and all frame-related registers, such as the -stack-pointer, will be stored. +stack pointer, will be stored. This routine is normally implemented as a macro and applications should not attempt to take its address. @@ -44,13 +44,13 @@ \section{Return Value} \section{Thread and Signal Safety} -\Func{unw\_getcontext}() is thread-safe as well as safe to use +\Func{unw\_getcontext}() is thread safe as well as safe to use from a signal handler. \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_init\_local(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_init\_local}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_init_local.man b/src/native/external/libunwind/doc/unw_init_local.man index 8b33c90ccfd72b..1674bf7f53af28 100644 --- a/src/native/external/libunwind/doc/unw_init_local.man +++ b/src/native/external/libunwind/doc/unw_init_local.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Sun Aug 29 23:45:06 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_INIT\\_LOCAL" "3" "29 August 2021" "Programming Library " "Programming Library " +.TH "UNW\\_INIT\\_LOCAL" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_init_local \-\- initialize cursor for local unwinding @@ -38,18 +40,18 @@ flag); The unw_init_local() routine initializes the unwind cursor pointed to by c -with the machine\-state in the context structure +with the machine state in the context structure pointed to by ctxt\&. -As such, the machine\-state pointed to by +As such, the machine state pointed to by ctxt identifies the initial stack frame at which unwinding -starts. The machine\-state is expected to be one provided by a call to +starts. The machine state is expected to be one provided by a call to unw_getcontext(); as such, the instruction pointer may point to the instruction after the last instruction of a function, and libunwind will back\-up the instruction pointer before beginning -a walk up the call stack. The machine\-state must remain valid for the +a walk up the call stack. The machine state must remain valid for the duration for which the cursor c is in use. .PP @@ -81,14 +83,14 @@ flag. .PP On successful completion, unw_init_local() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_init_local() -is thread\-safe as well as safe to use from a +is thread safe as well as safe to use from a signal handler. .PP .SH ERRORS @@ -114,8 +116,8 @@ wasn\&'t accessible. .SH SEE ALSO .PP -libunwind(3), -unw_init_remote(3) +libunwind(3libunwind), +unw_init_remote(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_init_local.tex b/src/native/external/libunwind/doc/unw_init_local.tex index aaba0ca75d4dd6..f8333b5e31c86c 100644 --- a/src/native/external/libunwind/doc/unw_init_local.tex +++ b/src/native/external/libunwind/doc/unw_init_local.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_init\_local}{David Mosberger-Tang}{Programming Library}{unw\_init\_local}unw\_init\_local -- initialize cursor for local unwinding +\begin{Name}{3libunwind}{unw\_init\_local}{David Mosberger-Tang}{Programming Library}{unw\_init\_local}unw\_init\_local -- initialize cursor for local unwinding \end{Name} \section{Synopsis} @@ -18,14 +18,14 @@ \section{Synopsis} \section{Description} The \Func{unw\_init\_local}() routine initializes the unwind cursor -pointed to by \Var{c} with the machine-state in the context structure -pointed to by \Var{ctxt}. As such, the machine-state pointed to by +pointed to by \Var{c} with the machine state in the context structure +pointed to by \Var{ctxt}. As such, the machine state pointed to by \Var{ctxt} identifies the initial stack frame at which unwinding -starts. The machine-state is expected to be one provided by a call to +starts. The machine state is expected to be one provided by a call to \Func{unw\_getcontext}(); as such, the instruction pointer may point to the instruction after the last instruction of a function, and \Prog{libunwind} will back-up the instruction pointer before beginning -a walk up the call stack. The machine-state must remain valid for the +a walk up the call stack. The machine state must remain valid for the duration for which the cursor \Var{c} is in use. The \Func{unw\_init\_local}() routine can be used only for unwinding in @@ -45,12 +45,12 @@ \section{Description} \section{Return Value} On successful completion, \Func{unw\_init\_local}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_init\_local}() is thread-safe as well as safe to use from a +\Func{unw\_init\_local}() is thread safe as well as safe to use from a signal handler. \section{Errors} @@ -67,7 +67,8 @@ \section{Errors} \section{See Also} -\SeeAlso{libunwind(3)}, \SeeAlso{unw\_init\_remote(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_init\_remote}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_init_remote.man b/src/native/external/libunwind/doc/unw_init_remote.man index 0acdac9617b75d..9bae9f6b3f20ef 100644 --- a/src/native/external/libunwind/doc/unw_init_remote.man +++ b/src/native/external/libunwind/doc/unw_init_remote.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_INIT\\_REMOTE" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_INIT\\_REMOTE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_init_remote \-\- initialize cursor for remote unwinding @@ -42,18 +44,18 @@ unw_local_addr_space address space created with unw_create_addr_space(). .PP The arg -void\-pointer tells the address space exactly what entity +opaque pointer tells the address space exactly what entity should be unwound. For example, if unw_local_addr_space is passed in as, then arg needs to be a pointer to a context structure containing the machine\-state of the initial stack frame. -However, other address\-spaces may instead expect a process\-id, a -thread\-id, or a pointer to an arbitrary structure which identifies the -stack\-frame chain to be unwound. In other words, the interpretation +However, other address spaces may instead expect a process ID, a +thread ID, or a pointer to an arbitrary structure which identifies the +stack frame chain to be unwound. In other words, the interpretation of arg -is entirely dependent on the address\-space in use; +is entirely dependent on the address space in use; libunwind never interprets the argument in any way on its own. .PP @@ -78,7 +80,7 @@ returned. .PP unw_init_remote() -is thread\-safe. If the local address\-space +is thread safe. If the local address space is passed in argument as, this routine is also safe to use from a signal handler. @@ -108,9 +110,9 @@ wasn\&'t accessible. .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3), -unw_init_local(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +unw_init_local(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_init_remote.tex b/src/native/external/libunwind/doc/unw_init_remote.tex index 9b4dc7997ae61f..bfb3367045f95b 100644 --- a/src/native/external/libunwind/doc/unw_init_remote.tex +++ b/src/native/external/libunwind/doc/unw_init_remote.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_init\_remote}{David Mosberger-Tang}{Programming Library}{unw\_init\_remote}unw\_init\_remote -- initialize cursor for remote unwinding +\begin{Name}{3libunwind}{unw\_init\_remote}{David Mosberger-Tang}{Programming Library}{unw\_init\_remote}unw\_init\_remote -- initialize cursor for remote unwinding \end{Name} \section{Synopsis} @@ -22,14 +22,14 @@ \section{Description} \Var{unw\_local\_addr\_space} (local address space) or to an arbitrary address space created with \Func{unw\_create\_addr\_space}(). -The \Var{arg} void-pointer tells the address space exactly what entity +The \Var{arg} opaque pointer tells the address space exactly what entity should be unwound. For example, if \Var{unw\_local\_addr\_space} is passed in \Var{as}, then \Var{arg} needs to be a pointer to a context structure containing the machine-state of the initial stack frame. -However, other address-spaces may instead expect a process-id, a -thread-id, or a pointer to an arbitrary structure which identifies the -stack-frame chain to be unwound. In other words, the interpretation -of \Var{arg} is entirely dependent on the address-space in use; +However, other address spaces may instead expect a process ID, a +thread ID, or a pointer to an arbitrary structure which identifies the +stack frame chain to be unwound. In other words, the interpretation +of \Var{arg} is entirely dependent on the address space in use; \Prog{libunwind} never interprets the argument in any way on its own. Note that \Func{unw\_init\_remote}() can be used to initiate unwinding @@ -46,7 +46,7 @@ \section{Return Value} \section{Thread and Signal Safety} -\Func{unw\_init\_remote}() is thread-safe. If the local address-space +\Func{unw\_init\_remote}() is thread safe. If the local address space is passed in argument \Var{as}, this routine is also safe to use from a signal handler. @@ -65,8 +65,9 @@ \section{Errors} \section{See Also} -\SeeAlso{libunwind(3)}, \SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_init\_local(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_init\_local}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_is_fpreg.man b/src/native/external/libunwind/doc/unw_is_fpreg.man index 0c26ec1bc740a2..9b42ed4ae7ce4c 100644 --- a/src/native/external/libunwind/doc/unw_is_fpreg.man +++ b/src/native/external/libunwind/doc/unw_is_fpreg.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_IS\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_IS\\_FPREG" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_is_fpreg \-\- check if a register is a floating\-point register @@ -50,17 +52,17 @@ of 0. .PP unw_is_fpreg() -is thread\-safe as well as safe to use +is thread safe as well as safe to use from a signal handler. .PP .SH SEE ALSO .PP -libunwind(3), -unw_get_reg(3), -unw_set_reg(3), -unw_get_fpreg(3), -unw_set_fpreg(3) +libunwind(3libunwind), +unw_get_reg(3libunwind), +unw_set_reg(3libunwind), +unw_get_fpreg(3libunwind), +unw_set_fpreg(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_is_fpreg.tex b/src/native/external/libunwind/doc/unw_is_fpreg.tex index c28cdc9be4fd23..6de950a6030d22 100644 --- a/src/native/external/libunwind/doc/unw_is_fpreg.tex +++ b/src/native/external/libunwind/doc/unw_is_fpreg.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_is\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_is\_fpreg}unw\_is\_fpreg -- check if a register is a floating-point register +\begin{Name}{3libunwind}{unw\_is\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_is\_fpreg}unw\_is\_fpreg -- check if a register is a floating-point register \end{Name} \section{Synopsis} @@ -30,16 +30,16 @@ \section{Return Value} \section{Thread and Signal Safety} -\Func{unw\_is\_fpreg}() is thread-safe as well as safe to use +\Func{unw\_is\_fpreg}() is thread safe as well as safe to use from a signal handler. \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_get\_reg(3)}, -\SeeAlso{unw\_set\_reg(3)}, -\SeeAlso{unw\_get\_fpreg(3)}, -\SeeAlso{unw\_set\_fpreg(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_get\_reg}(3libunwind), +\SeeAlso{unw\_set\_reg}(3libunwind), +\SeeAlso{unw\_get\_fpreg}(3libunwind), +\SeeAlso{unw\_set\_fpreg}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_is_signal_frame.man b/src/native/external/libunwind/doc/unw_is_signal_frame.man index d9a7cda7b5fe1c..8971c0f7d2fb00 100644 --- a/src/native/external/libunwind/doc/unw_is_signal_frame.man +++ b/src/native/external/libunwind/doc/unw_is_signal_frame.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:06:25 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_IS\\_SIGNAL\\_FRAME" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_IS\\_SIGNAL\\_FRAME" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_is_signal_frame \-\- check if current frame is a signal frame @@ -31,12 +33,15 @@ unw_is_signal_frame(unw_cursor_t *cp); The unw_is_signal_frame() routine returns a positive value if the current frame identified by cp -is a signal frame, and a -value of 0 otherwise. For the purpose of this discussion, a signal -frame is a frame that was created in response to a potentially -asynchronous interruption. For UNIX and UNIX\-like platforms, such -frames are normally created by the kernel when delivering a signal. -In a kernel\-environment, a signal frame might, for example, correspond +is a signal frame, +also known as a signal trampoline, +and a value of 0 otherwise. +For the purpose of this discussion, +a signal frame is a frame that was created in response to a potentially +asynchronous interruption. +For UNIX and UNIX\-like platforms, +such frames are normally created by the kernel when delivering a signal. +In a kernel environment, a signal frame might, for example, correspond to a frame created in response to a device interrupt. .PP Signal frames are somewhat unusual because the asynchronous nature of @@ -49,14 +54,14 @@ that are normally treated as scratch (``caller\-saved\&'') registers. On successful completion, unw_is_signal_frame() returns a positive value if the current frame is a signal frame, or 0 if it is -not. Otherwise, a negative value of one of the error\-codes below is +not. Otherwise, a negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_is_signal_frame() -is thread\-safe as well as safe to use +is thread safe as well as safe to use from a signal handler. .PP .SH ERRORS @@ -71,11 +76,11 @@ whether or not the current frame is a signal frame. .SH SEE ALSO .PP -libunwind(3), -unw_get_reg(3), -unw_set_reg(3), -unw_get_fpreg(3), -unw_set_fpreg(3) +libunwind(3libunwind), +unw_get_reg(3libunwind), +unw_set_reg(3libunwind), +unw_get_fpreg(3libunwind), +unw_set_fpreg(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_is_signal_frame.tex b/src/native/external/libunwind/doc/unw_is_signal_frame.tex index f262e5600c1df7..61f2b722a11f0a 100644 --- a/src/native/external/libunwind/doc/unw_is_signal_frame.tex +++ b/src/native/external/libunwind/doc/unw_is_signal_frame.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_is\_signal\_frame}{David Mosberger-Tang}{Programming Library}{unw\_is\_signal\_frame}unw\_is\_signal\_frame -- check if current frame is a signal frame +\begin{Name}{3libunwind}{unw\_is\_signal\_frame}{David Mosberger-Tang}{Programming Library}{unw\_is\_signal\_frame}unw\_is\_signal\_frame -- check if current frame is a signal frame \end{Name} \section{Synopsis} @@ -17,12 +17,15 @@ \section{Synopsis} \section{Description} The \Func{unw\_is\_signal\_frame}() routine returns a positive value -if the current frame identified by \Var{cp} is a signal frame, and a -value of 0 otherwise. For the purpose of this discussion, a signal -frame is a frame that was created in response to a potentially -asynchronous interruption. For UNIX and UNIX-like platforms, such -frames are normally created by the kernel when delivering a signal. -In a kernel-environment, a signal frame might, for example, correspond +if the current frame identified by \Var{cp} is a signal frame, +also known as a signal trampoline, +and a value of 0 otherwise. +For the purpose of this discussion, +a signal frame is a frame that was created in response to a potentially +asynchronous interruption. +For UNIX and UNIX-like platforms, +such frames are normally created by the kernel when delivering a signal. +In a kernel environment, a signal frame might, for example, correspond to a frame created in response to a device interrupt. Signal frames are somewhat unusual because the asynchronous nature of @@ -33,12 +36,12 @@ \section{Return Value} On successful completion, \Func{unw\_is\_signal\_frame}() returns a positive value if the current frame is a signal frame, or 0 if it is -not. Otherwise, a negative value of one of the error-codes below is +not. Otherwise, a negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_is\_signal\_frame}() is thread-safe as well as safe to use +\Func{unw\_is\_signal\_frame}() is thread safe as well as safe to use from a signal handler. \section{Errors} @@ -50,11 +53,11 @@ \section{Errors} \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_get\_reg(3)}, -\SeeAlso{unw\_set\_reg(3)}, -\SeeAlso{unw\_get\_fpreg(3)}, -\SeeAlso{unw\_set\_fpreg(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_get\_reg}(3libunwind), +\SeeAlso{unw\_set\_reg}(3libunwind), +\SeeAlso{unw\_get\_fpreg}(3libunwind), +\SeeAlso{unw\_set\_fpreg}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_reg_states_iterate.man b/src/native/external/libunwind/doc/unw_reg_states_iterate.man index 0c18cf964c1eb9..b037303c371b4a 100644 --- a/src/native/external/libunwind/doc/unw_reg_states_iterate.man +++ b/src/native/external/libunwind/doc/unw_reg_states_iterate.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Sun Aug 29 23:45:06 CEST 2021 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_REG\\_STATES\\_ITERATE" "3" "29 August 2021" "Programming Library " "Programming Library " +.TH "UNW\\_REG\\_STATES\\_ITERATE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_reg_states_iterate \-\- get register state info on current procedure @@ -87,15 +89,15 @@ On successful completion, unw_reg_states_iterate() returns 0. If the callback function returns a nonzero value, that indicates failure and the function returns immediately. Otherwise the negative -value of one of the error\-codes below is returned. +value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_reg_states_iterate() -is thread\-safe. If cursor cp +is thread safe. If cursor cp is -in the local address\-space, this routine is also safe to use from a +in the local address space, this routine is also safe to use from a signal handler. .PP .SH ERRORS @@ -118,13 +120,13 @@ In addition, unw_reg_states_iterate() may return any error returned by the access_mem() call\-back (see -unw_create_addr_space(3)). +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_apply_reg_state(3) +libunwind(3libunwind), +unw_apply_reg_state(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_reg_states_iterate.tex b/src/native/external/libunwind/doc/unw_reg_states_iterate.tex index c350b53394ab03..2fea77d613835f 100644 --- a/src/native/external/libunwind/doc/unw_reg_states_iterate.tex +++ b/src/native/external/libunwind/doc/unw_reg_states_iterate.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_reg\_states\_iterate}{David Mosberger-Tang}{Programming Library}{unw\_reg\_states\_iterate}unw\_reg\_states\_iterate -- get register state info on current procedure +\begin{Name}{3libunwind}{unw\_reg\_states\_iterate}{David Mosberger-Tang}{Programming Library}{unw\_reg\_states\_iterate}unw\_reg\_states\_iterate -- get register state info on current procedure \end{Name} \section{Synopsis} @@ -46,12 +46,12 @@ \section{Return Value} On successful completion, \Func{unw\_reg\_states\_iterate}() returns 0. If the callback function returns a nonzero value, that indicates failure and the function returns immediately. Otherwise the negative -value of one of the error-codes below is returned. +value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_reg\_states\_iterate}() is thread-safe. If cursor \Var{cp} is -in the local address-space, this routine is also safe to use from a +\Func{unw\_reg\_states\_iterate}() is thread safe. If cursor \Var{cp} is +in the local address space, this routine is also safe to use from a signal handler. \section{Errors} @@ -65,12 +65,12 @@ \section{Errors} \end{Description} In addition, \Func{unw\_reg\_states\_iterate}() may return any error returned by the \Func{access\_mem}() call-back (see -\Func{unw\_create\_addr\_space}(3)). +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_apply\_reg\_state(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_apply\_reg\_state}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_regname.man b/src/native/external/libunwind/doc/unw_regname.man index 1e3e2dbc6ea1fe..bcb733f3c6af48 100644 --- a/src/native/external/libunwind/doc/unw_regname.man +++ b/src/native/external/libunwind/doc/unw_regname.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_REGNAME" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_REGNAME" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_regname \-\- get register name @@ -49,13 +51,13 @@ string. .PP The unw_regname() -routine is thread\-safe as well as safe to +routine is thread safe as well as safe to use from a signal handler. .PP .SH SEE ALSO .PP -libunwind(3) +libunwind(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_regname.tex b/src/native/external/libunwind/doc/unw_regname.tex index 94b6434194d6f2..d215a36ad9b892 100644 --- a/src/native/external/libunwind/doc/unw_regname.tex +++ b/src/native/external/libunwind/doc/unw_regname.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_regname}{David Mosberger-Tang}{Programming Library}{unw\_regname}unw\_regname -- get register name +\begin{Name}{3libunwind}{unw\_regname}{David Mosberger-Tang}{Programming Library}{unw\_regname}unw\_regname -- get register name \end{Name} \section{Synopsis} @@ -29,12 +29,12 @@ \section{Return Value} \section{Thread and Signal Safety} -The \Func{unw\_regname}() routine is thread-safe as well as safe to +The \Func{unw\_regname}() routine is thread safe as well as safe to use from a signal handler. \section{See Also} -\SeeAlso{libunwind(3)} +\SeeAlso{libunwind}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_resume.man b/src/native/external/libunwind/doc/unw_resume.man index 1bf38327bf00ed..9f95c8c3f9330e 100644 --- a/src/native/external/libunwind/doc/unw_resume.man +++ b/src/native/external/libunwind/doc/unw_resume.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_RESUME" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_RESUME" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_resume \-\- resume execution in a particular stack frame @@ -86,7 +88,7 @@ handlers (aka, ``personality routines\&''). If a program needs this, it will have to do so on its own by obtaining the unw_proc_info_t of each unwound frame and appropriately processing its unwind handler and language\-specific data area (lsda). These steps are generally -dependent on the target\-platform and are regulated by the +dependent on the target platform and are regulated by the processor\-specific ABI (application\-binary interface). .PP .SH RETURN VALUE @@ -131,9 +133,9 @@ is not valid. .SH SEE ALSO .PP -libunwind(3), -unw_set_reg(3), -sigprocmask(2) +libunwind(3libunwind), +unw_set_reg(3libunwind), +sigprocmask(2) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_resume.tex b/src/native/external/libunwind/doc/unw_resume.tex index 38b18248ab66f2..e4f7b7ce7f45d3 100644 --- a/src/native/external/libunwind/doc/unw_resume.tex +++ b/src/native/external/libunwind/doc/unw_resume.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_resume}{David Mosberger-Tang}{Programming Library}{unw\_resume}unw\_resume -- resume execution in a particular stack frame +\begin{Name}{3libunwind}{unw\_resume}{David Mosberger-Tang}{Programming Library}{unw\_resume}unw\_resume -- resume execution in a particular stack frame \end{Name} \section{Synopsis} @@ -55,7 +55,7 @@ \section{Description} will have to do so on its own by obtaining the \Type{unw\_proc\_info\_t} of each unwound frame and appropriately processing its unwind handler and language-specific data area (lsda). These steps are generally -dependent on the target-platform and are regulated by the +dependent on the target platform and are regulated by the processor-specific ABI (application-binary interface). \section{Return Value} @@ -84,9 +84,9 @@ \section{Errors} \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_set\_reg(3)}, -sigprocmask(2) +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_set\_reg}(3libunwind), +\SeeAlso{sigprocmask}(2) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_set_cache_size.man b/src/native/external/libunwind/doc/unw_set_cache_size.man index 34bbc53961450c..5a975d8efc1a93 100644 --- a/src/native/external/libunwind/doc/unw_set_cache_size.man +++ b/src/native/external/libunwind/doc/unw_set_cache_size.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Fri Jan 13 08:33:21 PST 2017 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_SET\\_CACHE\\_SIZE" "3" "13 January 2017" "Programming Library " "Programming Library " +.TH "UNW\\_SET\\_CACHE\\_SIZE" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_set_cache_size \-\- set unwind cache size @@ -72,10 +74,10 @@ established because the application is out of memory. .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3), -unw_set_caching_policy(3), -unw_flush_cache(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +unw_set_caching_policy(3libunwind), +unw_flush_cache(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_set_cache_size.tex b/src/native/external/libunwind/doc/unw_set_cache_size.tex index 1bd7e00df7c231..de23f76cf2e58b 100644 --- a/src/native/external/libunwind/doc/unw_set_cache_size.tex +++ b/src/native/external/libunwind/doc/unw_set_cache_size.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_set\_cache\_size}{Dave Watson}{Programming Library}{unw\_set\_cache\_size}unw\_set\_cache\_size -- set unwind cache size +\begin{Name}{3libunwind}{unw\_set\_cache\_size}{Dave Watson}{Programming Library}{unw\_set\_cache\_size}unw\_set\_cache\_size -- set unwind cache size \end{Name} \section{Synopsis} @@ -43,10 +43,10 @@ \section{Errors} \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_set\_caching\_policy(3)}, -\SeeAlso{unw\_flush\_cache(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_set\_caching\_policy}(3libunwind), +\SeeAlso{unw\_flush\_cache}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_set_caching_policy.man b/src/native/external/libunwind/doc/unw_set_caching_policy.man index 4862ea545e5d45..64267b2a3658a2 100644 --- a/src/native/external/libunwind/doc/unw_set_caching_policy.man +++ b/src/native/external/libunwind/doc/unw_set_caching_policy.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Fri Dec 2 16:09:33 PST 2016 +.\" Manual page created with latex2man on Tue Aug 29 11:41:44 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_SET\\_CACHING\\_POLICY" "3" "02 December 2016" "Programming Library " "Programming Library " +.TH "UNW\\_SET\\_CACHING\\_POLICY" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_set_caching_policy \-\- set unwind caching policy @@ -71,7 +73,7 @@ unw_flush_cache() would have to be called (at least) for the address\-range that was covered by the shared library. .PP -For address spaces created via unw_create_addr_space(3), +For address spaces created via unw_create_addr_space(3libunwind), caching is turned off by default. For the local address space unw_local_addr_space, caching is turned on by default. @@ -103,10 +105,10 @@ established because the application is out of memory. .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3), -unw_set_cache_size(3), -unw_flush_cache(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +unw_set_cache_size(3libunwind), +unw_flush_cache(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_set_caching_policy.tex b/src/native/external/libunwind/doc/unw_set_caching_policy.tex index 3a4b07e84af0f3..abe20b11eddbeb 100644 --- a/src/native/external/libunwind/doc/unw_set_caching_policy.tex +++ b/src/native/external/libunwind/doc/unw_set_caching_policy.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_set\_caching\_policy}{David Mosberger-Tang}{Programming Library}{unw\_set\_caching\_policy}unw\_set\_caching\_policy -- set unwind caching policy +\begin{Name}{3libunwind}{unw\_set\_caching\_policy}{David Mosberger-Tang}{Programming Library}{unw\_set\_caching\_policy}unw\_set\_caching\_policy -- set unwind caching policy \end{Name} \section{Synopsis} @@ -41,7 +41,7 @@ \section{Description} \Func{unw\_flush\_cache}() would have to be called (at least) for the address-range that was covered by the shared library. -For address spaces created via \Func{unw\_create\_addr\_space}(3), +For address spaces created via \Func{unw\_create\_addr\_space}(3libunwind), caching is turned off by default. For the local address space \Func{unw\_local\_addr\_space}, caching is turned on by default. @@ -65,10 +65,10 @@ \section{Errors} \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)}, -\SeeAlso{unw\_set\_cache\_size(3)}, -\SeeAlso{unw\_flush\_cache(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{unw\_set\_cache\_size}(3libunwind), +\SeeAlso{unw\_flush\_cache}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_set_fpreg.man b/src/native/external/libunwind/doc/unw_set_fpreg.man index 6cefa54623ca2f..548feae7c4cb53 100644 --- a/src/native/external/libunwind/doc/unw_set_fpreg.man +++ b/src/native/external/libunwind/doc/unw_set_fpreg.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:06:25 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_SET\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_SET\\_FPREG" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_set_fpreg \-\- set contents of floating\-point register @@ -40,20 +42,20 @@ to the value passed in val\&. .PP The register numbering is target\-dependent and described in separate -manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target). +manual pages (e.g., libunwind\-ia64(3libunwind) for the IA\-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that cp is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee\-saved\&'') registers and frame\-related registers (such as the stack\-pointer). However, for signal frames (see -unw_is_signal_frame(3)), +unw_is_signal_frame(3libunwind)), it is usually possible to access all registers. .PP Note that unw_set_fpreg() can only write the contents of -floating\-point registers. See unw_set_reg(3) +floating\-point registers. See unw_set_reg(3libunwind) for a way to write registers which fit in a single word. .PP @@ -62,14 +64,14 @@ write registers which fit in a single word. .PP On successful completion, unw_set_fpreg() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY .PP unw_set_fpreg() -is thread\-safe as well as safe to use +is thread safe as well as safe to use from a signal handler. .PP .SH ERRORS @@ -93,18 +95,18 @@ the access_mem(), access_reg(), and access_fpreg() -call\-backs (see -unw_create_addr_space(3)). +callbacks (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -libunwind\-ia64(3), -unw_get_fpreg(3), -unw_is_fpreg(3), -unw_is_signal_frame(3), -unw_set_reg(3) +libunwind(3libunwind), +libunwind\-ia64(3libunwind), +unw_get_fpreg(3libunwind), +unw_is_fpreg(3libunwind), +unw_is_signal_frame(3libunwind), +unw_set_reg(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_set_fpreg.tex b/src/native/external/libunwind/doc/unw_set_fpreg.tex index aaf7fb25a761eb..36b74b73f5e3a6 100644 --- a/src/native/external/libunwind/doc/unw_set_fpreg.tex +++ b/src/native/external/libunwind/doc/unw_set_fpreg.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_set\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_set\_fpreg}unw\_set\_fpreg -- set contents of floating-point register +\begin{Name}{3libunwind}{unw\_set\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_set\_fpreg}unw\_set\_fpreg -- set contents of floating-point register \end{Name} \section{Synopsis} @@ -21,28 +21,28 @@ \section{Description} value passed in \Var{val}. The register numbering is target-dependent and described in separate -manual pages (e.g., libunwind-ia64(3) for the IA-64 target). +manual pages (e.g., libunwind-ia64(3libunwind) for the IA-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that \Var{cp} is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee-saved'') registers and frame-related registers (such as the stack-pointer). However, for signal frames (see -\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access +\Func{unw\_is\_signal\_frame}(3libunwind)), it is usually possible to access all registers. Note that \Func{unw\_set\_fpreg}() can only write the contents of -floating-point registers. See \Func{unw\_set\_reg}(3) for a way to +floating-point registers. See \Func{unw\_set\_reg}(3libunwind) for a way to write registers which fit in a single word. \section{Return Value} On successful completion, \Func{unw\_set\_fpreg}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} -\Func{unw\_set\_fpreg}() is thread-safe as well as safe to use +\Func{unw\_set\_fpreg}() is thread safe as well as safe to use from a signal handler. \section{Errors} @@ -56,17 +56,17 @@ \section{Errors} \end{Description} In addition, \Func{unw\_set\_fpreg}() may return any error returned by the \Func{access\_mem}(), \Func{access\_reg}(), and -\Func{access\_fpreg}() call-backs (see -\Func{unw\_create\_addr\_space}(3)). +\Func{access\_fpreg}() callbacks (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{libunwind-ia64(3)}, -\SeeAlso{unw\_get\_fpreg(3)}, -\SeeAlso{unw\_is\_fpreg(3)}, -\SeeAlso{unw\_is\_signal\_frame(3)}, -\SeeAlso{unw\_set\_reg(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{libunwind-ia64}(3libunwind), +\SeeAlso{unw\_get\_fpreg}(3libunwind), +\SeeAlso{unw\_is\_fpreg}(3libunwind), +\SeeAlso{unw\_is\_signal\_frame}(3libunwind), +\SeeAlso{unw\_set\_reg}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_set_iterate_phdr_function.man b/src/native/external/libunwind/doc/unw_set_iterate_phdr_function.man new file mode 100644 index 00000000000000..c1f8eb2923af44 --- /dev/null +++ b/src/native/external/libunwind/doc/unw_set_iterate_phdr_function.man @@ -0,0 +1,83 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} +'\" t +.\" Manual page created with latex2man on Tue Aug 29 11:10:10 2023 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_SET\\_ITERATE\\_PHDR\\_FUNCTION" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " +.SH NAME +unw_set_iterate_phdr_function +\-\- set dl_iterate_phdr +implementation +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +typedef int +(*unw_iterate_phdr_callback_t)(struct dl_phdr_info *, +size_t, +void *); +.br +typedef int +(*unw_iterate_phdr_func_t)(unw_iterate_phdr_callback_t, +void *); +.br +.PP +void +unw_set_iterate_phdr_function(unw_addr_space_t +as, +unw_iterate_phdr_func_t +function); +.br +.PP +.SH DESCRIPTION + +.PP +The unw_set_iterate_phdr_function() +routine sets the dl_iterate_phdr +implementation of address space as +to the function by argument function\&. +The function +will be called whenever libunwind +needs to iterate over the program headers of the application. +This is normally done by calling dl_iterate_phdr, +but this function is not signal safe. +With the help of a custom implementation caching and iterating over the program headers is also possible in an signal\-safe manner. +Though the burden lies on the user of libunwind\&. +.PP +.SH THREAD AND SIGNAL SAFETY + +.PP +unw_set_iterate_phdr_function() +is thread safe. If the local address space +is passed in argument as, +this routine is also safe to use from +a signal handler. +.PP +.SH SEE ALSO + +.PP +libunwind(3libunwind), +unw_create_addr_space(3libunwind), +dl_iterate_phdr(3libunwind), +.PP +.SH AUTHOR + +.PP +Bert Wesarg +.br +Email: \fBbert.wesarg@googlemail.com\fP +.br +WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&. +.\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/native/external/libunwind/doc/unw_set_iterate_phdr_function.tex b/src/native/external/libunwind/doc/unw_set_iterate_phdr_function.tex new file mode 100644 index 00000000000000..beba287800ddce --- /dev/null +++ b/src/native/external/libunwind/doc/unw_set_iterate_phdr_function.tex @@ -0,0 +1,57 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3libunwind}{unw\_set\_iterate\_phdr\_function}{Bert Wesarg}{Programming Library}{unw\_set\_iterate\_phdr\_function}unw\_set\_iterate\_phdr\_function -- set \Func{dl\_iterate\_phdr} implementation +\end{Name} + +\section{Synopsis} + + +\File{\#include $<$libunwind.h$>$}\\ + +\noindent +\Type{typedef~int} +\Func{(*unw\_iterate\_phdr\_callback\_t)}(\Type{struct~dl\_phdr\_info~*}, + \Type{size\_t}, \Type{void~*});\\ +\noindent +\Type{typedef~int} \Func{(*unw\_iterate\_phdr\_func\_t)}(\Type{unw\_iterate\_phdr\_callback\_t}, + \Type{void~*});\\ + +\noindent +\Type{void} \Func{unw\_set\_iterate\_phdr\_function}(\Type{unw\_addr\_space\_t} + \Var{as}, \Type{unw\_iterate\_phdr\_func\_t} \Var{function});\\ + +\section{Description} + +The \Func{unw\_set\_iterate\_phdr\_function}() routine sets the \Func{dl\_iterate\_phdr} implementation of address space \Var{as} to the function by argument \Var{function}. +The \Var{function} will be called whenever \Prog{libunwind} needs to iterate over the program headers of the application. +This is normally done by calling \Func{dl\_iterate\_phdr}, but this function is not signal safe. +With the help of a custom implementation caching and iterating over the program headers is also possible in an signal-safe manner. +Though the burden lies on the user of \Prog{libunwind}. + +\section{Thread and Signal Safety} + +\Func{unw\_set\_iterate\_phdr\_function}() is thread safe. If the local address space +is passed in argument \Var{as}, this routine is also safe to use from +a signal handler. + + +\section{See Also} + +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind), +\SeeAlso{dl\_iterate\_phdr}(3libunwind), + +\section{Author} + +\noindent +Bert Wesarg\\ +Email: \Email{bert.wesarg@googlemail.com}\\ +WWW: \URL{http://www.nongnu.org/libunwind/}. +\LatexManEnd + +\end{document} diff --git a/src/native/external/libunwind/doc/unw_set_reg.man b/src/native/external/libunwind/doc/unw_set_reg.man index 5d57045f747515..39ee2686edff38 100644 --- a/src/native/external/libunwind/doc/unw_set_reg.man +++ b/src/native/external/libunwind/doc/unw_set_reg.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 11:06:25 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_SET\\_REG" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_SET\\_REG" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_set_reg \-\- set register contents @@ -39,22 +41,22 @@ in the stack frame identified by cursor cp to the value passed in val\&. .PP -The register numbering is target\-dependent and described in separate -manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target). +The register numbering is target dependent and described in separate +manual pages (e.g., libunwind\-ia64(3libunwind) for the IA\-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that cp is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee\-saved\&'') registers and frame\-related registers (such as the -stack\-pointer). However, for signal frames (see -unw_is_signal_frame(3)), +stack pointer). However, for signal frames (see +unw_is_signal_frame(3libunwind)), it is usually possible to access all registers. .PP Note that unw_set_reg() can only write the contents of registers whose values fit in a single word. See -unw_set_fpreg(3) +unw_set_fpreg(3libunwind) for a way to write registers which do not fit this constraint. .PP @@ -63,7 +65,7 @@ fit this constraint. .PP On successful completion, unw_set_reg() returns 0. -Otherwise the negative value of one of the error\-codes below is +Otherwise the negative value of one of the error codes below is returned. .PP .SH THREAD AND SIGNAL SAFETY @@ -94,17 +96,17 @@ the access_mem(), access_reg(), and access_fpreg() -call\-backs (see -unw_create_addr_space(3)). +callbacks (see +unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -libunwind\-ia64(3), -unw_get_reg(3), -unw_is_signal_frame(3), -unw_set_fpreg(3) +libunwind(3libunwind), +libunwind\-ia64(3libunwind), +unw_get_reg(3libunwind), +unw_is_signal_frame(3libunwind), +unw_set_fpreg(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_set_reg.tex b/src/native/external/libunwind/doc/unw_set_reg.tex index 2421846be59e78..47a4091fe23e16 100644 --- a/src/native/external/libunwind/doc/unw_set_reg.tex +++ b/src/native/external/libunwind/doc/unw_set_reg.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_set\_reg}{David Mosberger-Tang}{Programming Library}{unw\_set\_reg}unw\_set\_reg -- set register contents +\begin{Name}{3libunwind}{unw\_set\_reg}{David Mosberger-Tang}{Programming Library}{unw\_set\_reg}unw\_set\_reg -- set register contents \end{Name} \section{Synopsis} @@ -20,25 +20,25 @@ \section{Description} \Var{reg} in the stack frame identified by cursor \Var{cp} to the value passed in \Var{val}. -The register numbering is target-dependent and described in separate -manual pages (e.g., libunwind-ia64(3) for the IA-64 target). +The register numbering is target dependent and described in separate +manual pages (e.g., libunwind-ia64(3libunwind) for the IA-64 target). Furthermore, the exact set of accessible registers may depend on the type of frame that \Var{cp} is referring to. For ordinary stack frames, it is normally possible to access only the preserved (``callee-saved'') registers and frame-related registers (such as the -stack-pointer). However, for signal frames (see -\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access +stack pointer). However, for signal frames (see +\Func{unw\_is\_signal\_frame}(3libunwind)), it is usually possible to access all registers. Note that \Func{unw\_set\_reg}() can only write the contents of registers whose values fit in a single word. See -\Func{unw\_set\_fpreg}(3) for a way to write registers which do not +\Func{unw\_set\_fpreg}(3libunwind) for a way to write registers which do not fit this constraint. \section{Return Value} On successful completion, \Func{unw\_set\_reg}() returns 0. -Otherwise the negative value of one of the error-codes below is +Otherwise the negative value of one of the error codes below is returned. \section{Thread and Signal Safety} @@ -57,16 +57,16 @@ \section{Errors} \end{Description} In addition, \Func{unw\_set\_reg}() may return any error returned by the \Func{access\_mem}(), \Func{access\_reg}(), and -\Func{access\_fpreg}() call-backs (see -\Func{unw\_create\_addr\_space}(3)). +\Func{access\_fpreg}() callbacks (see +\Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{libunwind-ia64(3)}, -\SeeAlso{unw\_get\_reg(3)}, -\SeeAlso{unw\_is\_signal\_frame(3)}, -\SeeAlso{unw\_set\_fpreg(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{libunwind-ia64}(3libunwind), +\SeeAlso{unw\_get\_reg}(3libunwind), +\SeeAlso{unw\_is\_signal\_frame}(3libunwind), +\SeeAlso{unw\_set\_fpreg}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_step.man b/src/native/external/libunwind/doc/unw_step.man index 54da1b2f3d62a1..ef1373175e12fb 100644 --- a/src/native/external/libunwind/doc/unw_step.man +++ b/src/native/external/libunwind/doc/unw_step.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007 +.\" Manual page created with latex2man on Tue Aug 29 10:53:42 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_STEP" "3" "16 August 2007" "Programming Library " "Programming Library " +.TH "UNW\\_STEP" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_step \-\- advance to next stack frame @@ -87,13 +89,13 @@ get_dyn_info_list_addr(), access_mem(), access_reg(), or access_fpreg() -call\-backs (see unw_create_addr_space(3)). +call\-backs (see unw_create_addr_space(3libunwind)). .PP .SH SEE ALSO .PP -libunwind(3), -unw_create_addr_space(3) +libunwind(3libunwind), +unw_create_addr_space(3libunwind) .PP .SH AUTHOR diff --git a/src/native/external/libunwind/doc/unw_step.tex b/src/native/external/libunwind/doc/unw_step.tex index 106bd9ba99c0c7..6180f583828a5d 100644 --- a/src/native/external/libunwind/doc/unw_step.tex +++ b/src/native/external/libunwind/doc/unw_step.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_step}{David Mosberger-Tang}{Programming Library}{unw\_step}unw\_step -- advance to next stack frame +\begin{Name}{3libunwind}{unw\_step}{David Mosberger-Tang}{Programming Library}{unw\_step}unw\_step -- advance to next stack frame \end{Name} \section{Synopsis} @@ -50,12 +50,12 @@ \section{Errors} In addition, \Func{unw\_step}() may return any error returned by the \Func{find\_proc\_info}(), \Func{get\_dyn\_info\_list\_addr}(), \Func{access\_mem}(), \Func{access\_reg}(), or \Func{access\_fpreg}() -call-backs (see \Func{unw\_create\_addr\_space}(3)). +call-backs (see \Func{unw\_create\_addr\_space}(3libunwind)). \section{See Also} -\SeeAlso{libunwind(3)}, -\SeeAlso{unw\_create\_addr\_space(3)} +\SeeAlso{libunwind}(3libunwind), +\SeeAlso{unw\_create\_addr\_space}(3libunwind) \section{Author} diff --git a/src/native/external/libunwind/doc/unw_strerror.man b/src/native/external/libunwind/doc/unw_strerror.man index 467c44d26204c3..63767c9bbc3634 100644 --- a/src/native/external/libunwind/doc/unw_strerror.man +++ b/src/native/external/libunwind/doc/unw_strerror.man @@ -1,5 +1,7 @@ +.\" *********************************** start of \input{common.tex} +.\" *********************************** end of \input{common.tex} '\" t -.\" Manual page created with latex2man on Wed Aug 18 16:51:29 CEST 2004 +.\" Manual page created with latex2man on Tue Aug 29 10:53:42 2023 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +12,7 @@ .fi .. -.TH "UNW\\_STRERROR" "3" "18 August 2004" "Programming Library " "Programming Library " +.TH "UNW\\_STRERROR" "3libunwind" "29 August 2023" "Programming Library " "Programming Library " .SH NAME unw_strerror \-\- get text corresponding to error code @@ -53,11 +55,11 @@ from a signal handler. .PP Thomas Hallgren -.br +.br BEA Systems -.br +.br Stockholm, Sweden -.br +.br Email: \fBthallgre@bea.com\fP .br .\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/native/external/libunwind/doc/unw_strerror.tex b/src/native/external/libunwind/doc/unw_strerror.tex index 7cad011768d73d..77599ca93f3c4e 100644 --- a/src/native/external/libunwind/doc/unw_strerror.tex +++ b/src/native/external/libunwind/doc/unw_strerror.tex @@ -5,7 +5,7 @@ \begin{document} -\begin{Name}{3}{unw\_strerror}{Thomas Hallgren}{Programming Library}{unw\_strerror}unw\_strerror -- get text corresponding to error code +\begin{Name}{3libunwind}{unw\_strerror}{Thomas Hallgren}{Programming Library}{unw\_strerror}unw\_strerror -- get text corresponding to error code \end{Name} \section{Synopsis} diff --git a/src/native/external/libunwind/include/compiler.h b/src/native/external/libunwind/include/compiler.h index 22939483cddb1e..3d8519347ba081 100644 --- a/src/native/external/libunwind/include/compiler.h +++ b/src/native/external/libunwind/include/compiler.h @@ -31,6 +31,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define COMPILER_H #ifdef __GNUC__ +#ifndef __has_attribute +# define __has_attribute(x) (0) +#endif # define CONST_ATTR __attribute__((__const__)) # define UNUSED __attribute__((unused)) # define NOINLINE __attribute__((noinline)) @@ -40,9 +43,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) # define ALWAYS_INLINE inline __attribute__((always_inline)) # define HIDDEN __attribute__((visibility ("hidden"))) +# if __has_attribute(fallthrough) +# define FALLTHROUGH __attribute__((fallthrough)) +# else +# define FALLTHROUGH +# endif # else # define ALWAYS_INLINE # define HIDDEN +# define FALLTHROUGH # endif # define WEAK __attribute__((weak)) # if (__GNUC__ >= 3) @@ -60,6 +69,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # define NORETURN # define ALIAS(name) # define HIDDEN +# define FALLTHROUGH # define WEAK # define likely(x) (x) # define unlikely(x) (x) diff --git a/src/native/external/libunwind/include/dwarf.h b/src/native/external/libunwind/include/dwarf.h index dd9014b7177bcf..4fd1dba02d08fe 100644 --- a/src/native/external/libunwind/include/dwarf.h +++ b/src/native/external/libunwind/include/dwarf.h @@ -32,12 +32,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ struct dwarf_cursor; /* forward-declaration */ struct elf_dyn_info; -#include "dwarf-config.h" - #ifdef HAVE_CONFIG_H # include "config.h" #endif +#include "dwarf-config.h" + #ifndef UNW_REMOTE_ONLY #if defined(HAVE_LINK_H) #include diff --git a/src/native/external/libunwind/include/dwarf_i.h b/src/native/external/libunwind/include/dwarf_i.h index 58f8034012e1c8..0f47082adbb732 100644 --- a/src/native/external/libunwind/include/dwarf_i.h +++ b/src/native/external/libunwind/include/dwarf_i.h @@ -43,8 +43,8 @@ typedef union __attribute__ ((packed)) dwarf_misaligned_value_t; static inline int -dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - int8_t *val, void *arg) +dwarf_reads8 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + int8_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; @@ -54,8 +54,8 @@ dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, } static inline int -dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - int16_t *val, void *arg) +dwarf_reads16 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + int16_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; @@ -65,8 +65,8 @@ dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, } static inline int -dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - int32_t *val, void *arg) +dwarf_reads32 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + int32_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; @@ -76,8 +76,8 @@ dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, } static inline int -dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - int64_t *val, void *arg) +dwarf_reads64 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + int64_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; @@ -87,8 +87,8 @@ dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, } static inline int -dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - uint8_t *val, void *arg) +dwarf_readu8 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + uint8_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; @@ -98,8 +98,8 @@ dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, } static inline int -dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - uint16_t *val, void *arg) +dwarf_readu16 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + uint16_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; @@ -109,8 +109,8 @@ dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, } static inline int -dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - uint32_t *val, void *arg) +dwarf_readu32 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + uint32_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; @@ -120,8 +120,8 @@ dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, } static inline int -dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - uint64_t *val, void *arg) +dwarf_readu64 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr, + uint64_t *val, void *arg UNUSED) { dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; diff --git a/src/native/external/libunwind/include/libunwind-aarch64.h b/src/native/external/libunwind/include/libunwind-aarch64.h index 63be0530a4e8dd..7751e4eb8be5e9 100644 --- a/src/native/external/libunwind/include/libunwind-aarch64.h +++ b/src/native/external/libunwind/include/libunwind-aarch64.h @@ -2,6 +2,7 @@ Copyright (C) 2001-2004 Hewlett-Packard Co Contributed by David Mosberger-Tang Copyright (C) 2013 Linaro Limited + Copyright 2022 Blackberry Limited This file is part of libunwind. @@ -35,6 +36,7 @@ extern "C" { #include #include #include +#include #ifndef UNW_EMPTY_STRUCT # define UNW_EMPTY_STRUCT uint8_t unused; @@ -62,6 +64,8 @@ typedef int64_t unw_sword_t; typedef long double unw_tdep_fpreg_t; +#define UNW_WORD_MAX UINT64_MAX + typedef struct { /* no aarch64-specific auxiliary proc-info */ @@ -228,9 +232,6 @@ typedef struct #else /* On AArch64, we can directly use ucontext_t as the unwind context. */ typedef ucontext_t unw_tdep_context_t; -#if defined(__FreeBSD__) -typedef ucontext_t unw_fpsimd_context_t; -#endif #endif @@ -238,9 +239,11 @@ typedef ucontext_t unw_fpsimd_context_t; #include "libunwind-dynamic.h" #if defined(__FreeBSD__) -#define UNW_BASE register uint64_t unw_base __asm__ ("x0") = (uint64_t) unw_ctx->uc_mcontext.mc_gpregs.gp_x[0]; +# define UNW_BASE register uint64_t unw_base __asm__ ("x0") = (uint64_t) unw_ctx->uc_mcontext.mc_gpregs.gp_x; +#elif defined(__QNX__) +# define UNW_BASE register uint64_t unw_base __asm__ ("x0") = (uint64_t) unw_ctx->uc_mcontext.cpu.gpr; #else -#define UNW_BASE register uint64_t unw_base __asm__ ("x0") = (uint64_t) unw_ctx->uc_mcontext.regs; +# define UNW_BASE register uint64_t unw_base __asm__ ("x0") = (uint64_t) unw_ctx->uc_mcontext.regs; #endif #define unw_tdep_getcontext(uc) ({ \ diff --git a/src/native/external/libunwind/include/libunwind-arm.h b/src/native/external/libunwind/include/libunwind-arm.h index 4ac1fd38258e68..6cfa577d67336f 100644 --- a/src/native/external/libunwind/include/libunwind-arm.h +++ b/src/native/external/libunwind/include/libunwind-arm.h @@ -31,6 +31,7 @@ extern "C" { #include #include +#include #ifndef UNW_EMPTY_STRUCT # define UNW_EMPTY_STRUCT uint8_t unused; @@ -55,6 +56,8 @@ typedef int32_t unw_sword_t; typedef long double unw_tdep_fpreg_t; +#define UNW_WORD_MAX UINT32_MAX + typedef enum { UNW_ARM_R0, @@ -271,9 +274,9 @@ unw_tdep_context_t; avoid altering any registers after unw_resume. */ #ifdef __SOFTFP__ -#define VSTMIA "nop\n" /* align return address to value stored by stmia */ +#define VSTMIA "nop\n\t" /* align return address to value stored by stmia */ #else -#define VSTMIA "vstmia %[base], {d0-d15}\n" /* this also aligns return address to value stored by stmia */ +#define VSTMIA "vstmia %[base], {d0-d15}\n\t" /* this also aligns return address to value stored by stmia */ #endif #ifndef __thumb__ @@ -282,32 +285,32 @@ unw_tdep_context_t; register unsigned long *r0 __asm__ ("r0"); \ register unsigned long *unw_base __asm__ ("r1") = unw_ctx->regs; \ __asm__ __volatile__ ( \ - "mov r0, #0\n" \ - "stmia %[base]!, {r0-r15}\n" \ + "mov r0, #0\n\t" \ + "stmia %[base]!, {r0-r15}\n\t" \ VSTMIA \ : [r0] "=r" (r0) : [base] "r" (unw_base) : "memory"); \ (int)r0; }) #else /* __thumb__ */ -#define unw_tdep_getcontext(uc) ({ \ - unw_tdep_context_t *unw_ctx = (uc); \ - register unsigned long *r0 __asm__ ("r0"); \ - register unsigned long *unw_base __asm__ ("r1") = unw_ctx->regs; \ - __asm__ __volatile__ ( \ - ".align 2\n" \ - "bx pc\n" \ - "nop\n" \ - ".code 32\n" \ - "mov r0, #0\n" \ - "stmia %[base], {r0-r14}\n" \ - "adr r0, ret%=+1\n" \ - "stmia %[base]!, {r0}\n" \ - VSTMIA \ - "orr r0, pc, #1\n" \ - "bx r0\n" \ - ".code 16\n" \ - "mov r0, #0\n" \ - "ret%=:\n" \ - : [r0] "=r" (r0), [base] "+r" (unw_base) : : "memory", "cc"); \ +#define unw_tdep_getcontext(uc) ({ \ + unw_tdep_context_t *unw_ctx = (uc); \ + register unsigned long *r0 __asm__ ("r0"); \ + register unsigned long *unw_base __asm__ ("r1") = unw_ctx->regs; \ + __asm__ __volatile__ ( \ + ".align 2\n\t" \ + "bx pc\n\t" \ + "nop\n\t" \ + ".code 32\n\t" \ + "mov r0, #0\n\t" \ + "stmia %[base]!, {r0-r14}\n\t" \ + "adr r0, ret%=+1\n\t" \ + "stmia %[base]!, {r0}\n\t" \ + VSTMIA \ + "orr r0, pc, #1\n\t" \ + "bx r0\n\t" \ + ".code 16\n\t" \ + "mov r0, #0\n\t" \ + "ret%=:\n" \ + : [r0] "=r" (r0), [base] "+r" (unw_base) : : "memory", "cc"); \ (int)r0; }) #endif diff --git a/src/native/external/libunwind/include/libunwind-common.h.in b/src/native/external/libunwind/include/libunwind-common.h.in index 7360a0284b25dd..893fdd69916ddb 100644 --- a/src/native/external/libunwind/include/libunwind-common.h.in +++ b/src/native/external/libunwind/include/libunwind-common.h.in @@ -208,6 +208,18 @@ typedef struct unw_accessors int (*get_proc_name) (unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *); + /* Optional call back to obtain the name of a elf file where the ip belongs to. + This callback is optional and may be set to NULL. */ + int (*get_elf_filename) (unw_addr_space_t, unw_word_t, char *, size_t, + unw_word_t *, void *); + + /* Optional call back to obtain the start and end ip of a procedure. + * procedure ip range is [start, end), the range is without end. + * This callback is optional and may be set to NULL. + */ + int (*get_proc_ip_range) (unw_addr_space_t, unw_word_t, unw_word_t *, + unw_word_t *, void *); + /* Optional call back to return a mask to be used with pointer * authentication on arm64. * @@ -249,6 +261,10 @@ typedef struct unw_save_loc } unw_save_loc_t; +struct dl_phdr_info; +typedef int (*unw_iterate_phdr_callback_t) (struct dl_phdr_info *, size_t, void *); +typedef int (*unw_iterate_phdr_func_t) (unw_iterate_phdr_callback_t, void *); + /* These routines work both for local and remote unwinding. */ #define unw_local_addr_space UNW_OBJ(local_addr_space) @@ -274,8 +290,11 @@ unw_save_loc_t; #define unw_is_signal_frame UNW_OBJ(is_signal_frame) #define unw_get_proc_name UNW_OBJ(get_proc_name) #define unw_get_proc_name_by_ip UNW_OBJ(get_proc_name_by_ip) +#define unw_get_elf_filename UNW_OBJ(get_elf_filename) +#define unw_get_elf_filename_by_ip UNW_OBJ(get_elf_filename_by_ip) #define unw_set_caching_policy UNW_OBJ(set_caching_policy) #define unw_set_cache_size UNW_OBJ(set_cache_size) +#define unw_set_iterate_phdr_function UNW_OBJ(set_iterate_phdr_function) #define unw_regname UNW_ARCH_OBJ(regname) #define unw_flush_cache UNW_ARCH_OBJ(flush_cache) #define unw_strerror UNW_ARCH_OBJ(strerror) @@ -287,6 +306,7 @@ extern unw_accessors_t *unw_get_accessors_int (unw_addr_space_t); extern void unw_flush_cache (unw_addr_space_t, unw_word_t, unw_word_t); extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t); extern int unw_set_cache_size (unw_addr_space_t, size_t, int); +extern void unw_set_iterate_phdr_function (unw_addr_space_t, unw_iterate_phdr_func_t); extern const char *unw_regname (unw_regnum_t); extern int unw_init_local (unw_cursor_t *, unw_context_t *); @@ -314,6 +334,9 @@ extern int unw_is_signal_frame (unw_cursor_t *); extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *); extern int unw_get_proc_name_by_ip (unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *); +extern int unw_get_elf_filename (unw_cursor_t *, char *, size_t, unw_word_t *); +extern int unw_get_elf_filename_by_ip (unw_addr_space_t, unw_word_t, char *, + size_t, unw_word_t *, void *); extern const char *unw_strerror (int); extern int unw_backtrace (void **, int); extern int unw_backtrace2 (void **, int, unw_context_t*, int); diff --git a/src/native/external/libunwind/include/libunwind-coredump.h b/src/native/external/libunwind/include/libunwind-coredump.h index 3c7814140f940d..83a974af484c12 100644 --- a/src/native/external/libunwind/include/libunwind-coredump.h +++ b/src/native/external/libunwind/include/libunwind-coredump.h @@ -62,6 +62,8 @@ extern int _UCD_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, int, void *); extern int _UCD_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *); +extern int _UCD_get_elf_filename (unw_addr_space_t, unw_word_t, char *, size_t, + unw_word_t *, void *); extern int _UCD_resume (unw_addr_space_t, unw_cursor_t *, void *); extern unw_accessors_t _UCD_accessors; diff --git a/src/native/external/libunwind/include/libunwind-hppa.h b/src/native/external/libunwind/include/libunwind-hppa.h index 7013aa772682db..ad592db85b20c5 100644 --- a/src/native/external/libunwind/include/libunwind-hppa.h +++ b/src/native/external/libunwind/include/libunwind-hppa.h @@ -30,8 +30,13 @@ extern "C" { #endif #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET hppa #define UNW_TARGET_HPPA 1 @@ -47,6 +52,8 @@ extern "C" { typedef uint32_t unw_word_t; typedef int32_t unw_sword_t; +#define UNW_WORD_MAX UINT32_MAX + typedef union { struct { unw_word_t bits[2]; } raw; @@ -97,6 +104,7 @@ hppa_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -110,6 +118,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no PA-RISC-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-ia64.h b/src/native/external/libunwind/include/libunwind-ia64.h index 0cc4f39eaab1e4..49741f0e35833a 100644 --- a/src/native/external/libunwind/include/libunwind-ia64.h +++ b/src/native/external/libunwind/include/libunwind-ia64.h @@ -27,8 +27,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define LIBUNWIND_H #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -69,6 +74,8 @@ extern "C" { typedef uint64_t unw_word_t; typedef int64_t unw_sword_t; +#define UNW_WORD_MAX UINT64_MAX + /* On IA-64, we want to access the contents of floating-point registers as a pair of "words", but to ensure 16-byte alignment, we make it a union that contains a "long double". This will do the @@ -83,6 +90,7 @@ unw_tdep_fpreg_t; typedef struct { /* no ia64-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-loongarch64.h b/src/native/external/libunwind/include/libunwind-loongarch64.h index 1e9366ed3ed2b6..7f768cd89e000e 100644 --- a/src/native/external/libunwind/include/libunwind-loongarch64.h +++ b/src/native/external/libunwind/include/libunwind-loongarch64.h @@ -32,8 +32,13 @@ extern "C" { #endif #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET loongarch64 #define UNW_TARGET_LOONGARCH64 1 @@ -53,6 +58,8 @@ typedef int64_t unw_sword_t; typedef long double unw_tdep_fpreg_t; +#define UNW_WORD_MAX UINT64_MAX + typedef enum { UNW_LOONGARCH64_R0, @@ -109,7 +116,7 @@ loongarch64_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -119,7 +126,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no loongarch64-specific auxiliary proc-info */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-mips.h b/src/native/external/libunwind/include/libunwind-mips.h index d1cc1b7e280a2b..9cb5051eea3501 100644 --- a/src/native/external/libunwind/include/libunwind-mips.h +++ b/src/native/external/libunwind/include/libunwind-mips.h @@ -30,12 +30,17 @@ extern "C" { #endif #include +#include #include #ifdef mips # undef mips #endif +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET mips #define UNW_TARGET_MIPS 1 @@ -55,8 +60,10 @@ extern "C" { ABIs, and 64-bit wide for N64 ABI. */ #if _MIPS_SIM == _ABI64 typedef uint64_t unw_word_t; +# define UNW_WORD_MAX UINT64_MAX #else typedef uint32_t unw_word_t; +# define UNW_WORD_MAX UINT32_MAX #endif typedef int32_t unw_sword_t; @@ -127,6 +134,7 @@ mips_abi_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -139,6 +147,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no mips-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-nto.h b/src/native/external/libunwind/include/libunwind-nto.h new file mode 100644 index 00000000000000..50d72c65a203d7 --- /dev/null +++ b/src/native/external/libunwind/include/libunwind-nto.h @@ -0,0 +1,69 @@ +/** + * Public interface for the QNX Neutrino remote unwinding library. + * + * This library provides helper routines to make it possible to use libunwind + * via the QNX Neutrino procfs. + */ +/* + * Copyright 2020, 2022 QNX Blackberry Limited. + * + * 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_NTO_H +#define LIBUNWIND_NTO_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +static const pthread_t LUT_ALL_THREADS = -1; + +/** + * Helper routines to make it easy to unwind using devctl() on unw_nto. + */ +extern void *unw_nto_create(pid_t, pthread_t); +extern void unw_nto_destroy(void *); + +extern int unw_nto_find_proc_info(unw_addr_space_t, unw_word_t, unw_proc_info_t *, int, void *); +extern void unw_nto_put_unwind_info(unw_addr_space_t, unw_proc_info_t *, void *); +extern int unw_nto_get_dyn_info_list_addr(unw_addr_space_t, unw_word_t *, void *); +extern int unw_nto_access_mem(unw_addr_space_t, unw_word_t, unw_word_t *, int, void *); +extern int unw_nto_access_reg(unw_addr_space_t, unw_regnum_t, unw_word_t *, int, void *); +extern int unw_nto_access_fpreg(unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, int, void *); +extern int unw_nto_get_proc_name(unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *); +extern int unw_nto_get_proc_ip_range (unw_addr_space_t as, unw_word_t ip, unw_word_t *start, unw_word_t *end, void *); +extern int unw_nto_get_elf_filename(unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *); +extern int unw_nto_resume(unw_addr_space_t, unw_cursor_t *, void *); + +/** + * A handy pre-defined accessor with all of the above. + */ +extern unw_accessors_t unw_nto_accessors; + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + +#endif /* LIBUNWIND_NTO_H */ diff --git a/src/native/external/libunwind/include/libunwind-ppc32.h b/src/native/external/libunwind/include/libunwind-ppc32.h index 47ebfde5a3cf3a..303597c02d9307 100644 --- a/src/native/external/libunwind/include/libunwind-ppc32.h +++ b/src/native/external/libunwind/include/libunwind-ppc32.h @@ -37,8 +37,13 @@ extern "C" { #endif #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET ppc32 #define UNW_TARGET_PPC32 1 @@ -67,9 +72,11 @@ extern "C" { #if __WORDSIZE==32 typedef uint32_t unw_word_t; typedef int32_t unw_sword_t; +# define UNW_WORD_MAX UINT32_MAX #else typedef uint64_t unw_word_t; typedef int64_t unw_sword_t; +# define UNW_WORD_MAX UINT64_MAX #endif typedef long double unw_tdep_fpreg_t; @@ -175,6 +182,7 @@ ppc32_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -192,6 +200,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no ppc32-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-ppc64.h b/src/native/external/libunwind/include/libunwind-ppc64.h index fed478bedcd715..1ce48bf7e95ccb 100644 --- a/src/native/external/libunwind/include/libunwind-ppc64.h +++ b/src/native/external/libunwind/include/libunwind-ppc64.h @@ -37,8 +37,13 @@ extern "C" { #endif #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET ppc64 #define UNW_TARGET_PPC64 1 @@ -67,9 +72,11 @@ extern "C" { #if __WORDSIZE==32 typedef uint32_t unw_word_t; typedef int32_t unw_sword_t; +#define UNW_WORD_MAX UINT32_MAX #else typedef uint64_t unw_word_t; typedef int64_t unw_sword_t; +#define UNW_WORD_MAX UINT64_MAX #endif typedef double unw_tdep_fpreg_t; @@ -239,6 +246,7 @@ ppc64_abi_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -256,6 +264,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no ppc64-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-ptrace.h b/src/native/external/libunwind/include/libunwind-ptrace.h index 916dbd246bf5b4..419f60efe91f35 100644 --- a/src/native/external/libunwind/include/libunwind-ptrace.h +++ b/src/native/external/libunwind/include/libunwind-ptrace.h @@ -53,6 +53,8 @@ extern int _UPT_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, int, void *); extern int _UPT_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *); +extern int _UPT_get_elf_filename (unw_addr_space_t, unw_word_t, char *, size_t, + unw_word_t *, void *); extern int _UPT_resume (unw_addr_space_t, unw_cursor_t *, void *); extern unw_accessors_t _UPT_accessors; diff --git a/src/native/external/libunwind/include/libunwind-riscv.h b/src/native/external/libunwind/include/libunwind-riscv.h index e74db0f93183aa..55605fe779a600 100644 --- a/src/native/external/libunwind/include/libunwind-riscv.h +++ b/src/native/external/libunwind/include/libunwind-riscv.h @@ -34,8 +34,13 @@ extern "C" { #include #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET riscv #define UNW_TARGET_RISCV 1 @@ -52,9 +57,11 @@ extern "C" { #if __riscv_xlen == 32 typedef uint32_t unw_word_t; typedef int32_t unw_sword_t; +# define UNW_WORD_MAX UINT32_MAX #elif __riscv_xlen == 64 typedef uint64_t unw_word_t; typedef int64_t unw_sword_t; +# define UNW_WORD_MAX UINT64_MAX #endif #if __riscv_flen == 64 @@ -157,7 +164,7 @@ riscv_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -167,7 +174,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no riscv-specific auxiliary proc-info */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-s390x.h b/src/native/external/libunwind/include/libunwind-s390x.h index ebda40d57af9b6..7d38a747b6b03e 100644 --- a/src/native/external/libunwind/include/libunwind-s390x.h +++ b/src/native/external/libunwind/include/libunwind-s390x.h @@ -36,6 +36,10 @@ extern "C" { #include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET s390x #define UNW_TARGET_S390X 1 @@ -53,6 +57,8 @@ typedef int64_t unw_sword_t; typedef double unw_tdep_fpreg_t; +#define UNW_WORD_MAX UINT64_MAX + typedef enum { /* general purpose registers */ @@ -114,7 +120,7 @@ s390x_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -124,7 +130,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no s390x-specific auxiliary proc-info */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-sh.h b/src/native/external/libunwind/include/libunwind-sh.h index 927f61ff42bdad..2218c6c602c683 100644 --- a/src/native/external/libunwind/include/libunwind-sh.h +++ b/src/native/external/libunwind/include/libunwind-sh.h @@ -32,8 +32,13 @@ extern "C" { #include #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET sh #define UNW_TARGET_SH 1 @@ -52,6 +57,8 @@ typedef int32_t unw_sword_t; typedef long double unw_tdep_fpreg_t; +#define UNW_WORD_MAX UINT32_MAX + typedef enum { UNW_SH_R0, @@ -91,6 +98,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -99,6 +107,7 @@ unw_tdep_save_loc_t; typedef struct { /* no sh-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind-tilegx.h b/src/native/external/libunwind/include/libunwind-tilegx.h deleted file mode 100644 index 0f84ea65ee3657..00000000000000 --- a/src/native/external/libunwind/include/libunwind-tilegx.h +++ /dev/null @@ -1,161 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 - -#define UNW_TARGET tilegx -#define UNW_TARGET_TILEGX 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 4096 - -/* The size of a "word" varies on TILEGX. This type is used for memory - addresses and register values. */ -typedef uint64_t unw_word_t; -typedef int64_t unw_sword_t; - -typedef long double unw_tdep_fpreg_t; - -typedef enum -{ - UNW_TILEGX_R0, - UNW_TILEGX_R1, - UNW_TILEGX_R2, - UNW_TILEGX_R3, - UNW_TILEGX_R4, - UNW_TILEGX_R5, - UNW_TILEGX_R6, - UNW_TILEGX_R7, - UNW_TILEGX_R8, - UNW_TILEGX_R9, - UNW_TILEGX_R10, - UNW_TILEGX_R11, - UNW_TILEGX_R12, - UNW_TILEGX_R13, - UNW_TILEGX_R14, - UNW_TILEGX_R15, - UNW_TILEGX_R16, - UNW_TILEGX_R17, - UNW_TILEGX_R18, - UNW_TILEGX_R19, - UNW_TILEGX_R20, - UNW_TILEGX_R21, - UNW_TILEGX_R22, - UNW_TILEGX_R23, - UNW_TILEGX_R24, - UNW_TILEGX_R25, - UNW_TILEGX_R26, - UNW_TILEGX_R27, - UNW_TILEGX_R28, - UNW_TILEGX_R29, - UNW_TILEGX_R30, - UNW_TILEGX_R31, - UNW_TILEGX_R32, - UNW_TILEGX_R33, - UNW_TILEGX_R34, - UNW_TILEGX_R35, - UNW_TILEGX_R36, - UNW_TILEGX_R37, - UNW_TILEGX_R38, - UNW_TILEGX_R39, - UNW_TILEGX_R40, - UNW_TILEGX_R41, - UNW_TILEGX_R42, - UNW_TILEGX_R43, - UNW_TILEGX_R44, - UNW_TILEGX_R45, - UNW_TILEGX_R46, - UNW_TILEGX_R47, - UNW_TILEGX_R48, - UNW_TILEGX_R49, - UNW_TILEGX_R50, - UNW_TILEGX_R51, - UNW_TILEGX_R52, - UNW_TILEGX_R53, - UNW_TILEGX_R54, - UNW_TILEGX_R55, - - /* FIXME: Other registers! */ - - UNW_TILEGX_PC, - /* For TILEGX, the CFA is the value of SP (r54) at the call site in the - previous frame. */ - UNW_TILEGX_CFA, - - UNW_TDEP_LAST_REG = UNW_TILEGX_PC, - - UNW_TDEP_IP = UNW_TILEGX_R55, /* R55 is link register for Tilegx */ - UNW_TDEP_SP = UNW_TILEGX_R54, - UNW_TDEP_EH = UNW_TILEGX_R0 /* FIXME. */ -} tilegx_regnum_t; - -typedef enum -{ - UNW_TILEGX_ABI_N64 = 2 -} tilegx_abi_t; - -#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for TILEGX. */ - -typedef struct unw_tdep_save_loc -{ - /* Additional target-dependent info on a save location. */ -} unw_tdep_save_loc_t; - -typedef ucontext_t unw_tdep_context_t; - -#include "libunwind-dynamic.h" - -typedef struct -{ - /* no tilegx-specific auxiliary proc-info */ -} unw_tdep_proc_info_t; - -#include "libunwind-common.h" - -#define unw_tdep_getcontext getcontext - -#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) -extern int unw_tdep_is_fpreg (int); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* LIBUNWIND_H */ diff --git a/src/native/external/libunwind/include/libunwind-x86.h b/src/native/external/libunwind/include/libunwind-x86.h index d3b741d3f3f9f0..cd42c60e49496d 100644 --- a/src/native/external/libunwind/include/libunwind-x86.h +++ b/src/native/external/libunwind/include/libunwind-x86.h @@ -32,6 +32,7 @@ extern "C" { #include #include +#include #include #ifndef UNW_EMPTY_STRUCT @@ -53,6 +54,8 @@ extern "C" { typedef uint32_t unw_word_t; typedef int32_t unw_sword_t; +#define UNW_WORD_MAX UINT32_MAX + typedef union { struct { uint8_t b[4]; } val32; struct { uint8_t b[10]; } val80; diff --git a/src/native/external/libunwind/include/libunwind-x86_64.h b/src/native/external/libunwind/include/libunwind-x86_64.h index 78eb541afb303c..a2fea33b3ba313 100644 --- a/src/native/external/libunwind/include/libunwind-x86_64.h +++ b/src/native/external/libunwind/include/libunwind-x86_64.h @@ -34,8 +34,13 @@ extern "C" { #include #include +#include #include +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT uint8_t unused; +#endif + #define UNW_TARGET x86_64 #define UNW_TARGET_X86_64 1 @@ -53,6 +58,8 @@ typedef int64_t unw_sword_t; typedef long double unw_tdep_fpreg_t; +#define UNW_WORD_MAX UINT64_MAX + typedef enum { UNW_X86_64_RAX, @@ -111,7 +118,7 @@ x86_64_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -121,7 +128,7 @@ typedef ucontext_t unw_tdep_context_t; typedef struct { /* no x86-64-specific auxiliary proc-info */ - char unused; + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/src/native/external/libunwind/include/libunwind.h.in b/src/native/external/libunwind/include/libunwind.h.in index 0ac692b71f74f6..5ed37ea575c138 100644 --- a/src/native/external/libunwind/include/libunwind.h.in +++ b/src/native/external/libunwind/include/libunwind.h.in @@ -23,8 +23,6 @@ # include "libunwind-x86.h" #elif defined __x86_64__ # include "libunwind-x86_64.h" -#elif defined __tilegx__ -# include "libunwind-tilegx.h" #elif defined __s390x__ # include "libunwind-s390x.h" #elif defined __riscv || defined __riscv__ diff --git a/src/native/external/libunwind/include/libunwind_i.h b/src/native/external/libunwind/include/libunwind_i.h index 3ca146258f6d28..1dbcb6a86d0f1b 100644 --- a/src/native/external/libunwind/include/libunwind_i.h +++ b/src/native/external/libunwind/include/libunwind_i.h @@ -51,6 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include +#include #include #include #include @@ -58,6 +59,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include +#if defined(HAVE_SYS_SYSCALL_H) +# include /* For SYS_xxx definitions */ +#endif + #if defined(HAVE_ELF_H) # include #elif defined(HAVE_SYS_ELF_H) @@ -121,8 +126,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ static inline int byte_order_is_valid(int byte_order) { - return byte_order != UNW_BIG_ENDIAN - && byte_order != UNW_LITTLE_ENDIAN; + return byte_order == UNW_BIG_ENDIAN + || byte_order == UNW_LITTLE_ENDIAN; } static inline int @@ -146,7 +151,7 @@ target_is_big_endian(void) #ifdef DEBUG # define UNW_DEBUG 1 #else -# define UNW_DEBUG 0 +# undef UNW_DEBUG #endif /* Make it easy to write thread-safe code which may or may not be @@ -157,6 +162,7 @@ target_is_big_endian(void) #pragma weak pthread_mutex_init #pragma weak pthread_mutex_lock #pragma weak pthread_mutex_unlock +#pragma weak pthread_sigmask #define mutex_init(l) \ (pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0) @@ -184,8 +190,11 @@ static inline void mark_as_used(void *v UNUSED) { } #if defined(CONFIG_BLOCK_SIGNALS) +/* SIGPROCMASK ignores return values, so we do not have to correct for pthread_sigmask() returning + errno on failure when sigprocmask() returns -1. */ # define SIGPROCMASK(how, new_mask, old_mask) \ - sigprocmask((how), (new_mask), (old_mask)) + (pthread_sigmask != NULL ? pthread_sigmask((how), (new_mask), (old_mask)) \ + : sigprocmask((how), (new_mask), (old_mask))) #else # define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask) #endif @@ -213,14 +222,46 @@ do { \ #define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */ +/* Provide an internal syscall version of mmap to improve signal safety. */ +static ALWAYS_INLINE void * +mi_mmap (void *addr, size_t len, int prot, int flags, int fd, off_t offset) +{ +#if defined(SYS_mmap) && !defined(__i386__) + /* Where supported, bypass libc and invoke the syscall directly. */ +# if defined(__FreeBSD__) // prefer over syscall on *BSD + long int ret = __syscall (SYS_mmap, addr, len, prot, flags, fd, offset); +# else + long int ret = syscall (SYS_mmap, addr, len, prot, flags, fd, offset); +# endif + // @todo this is very likely Linux specific + if ((unsigned long int)ret > -4096UL) + return MAP_FAILED; + else + return (void *)ret; +#else + /* Where direct syscalls are not supported, forward to the libc call. */ + return mmap (addr, len, prot, flags, fd, offset); +#endif +} + +/* Provide an internal syscall version of munmap to improve signal safety. */ +static ALWAYS_INLINE int +mi_munmap (void *addr, size_t len) +{ +#ifdef SYS_munmap + return syscall (SYS_munmap, addr, len); +#else + return munmap (addr, len); +#endif +} + #ifndef MAP_ANONYMOUS # define MAP_ANONYMOUS MAP_ANON #endif #define GET_MEMORY(mem, size) \ do { \ - /* Hopefully, mmap() goes straight through to a system call stub... */ \ - mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \ - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ + mem = mi_mmap (NULL, size, PROT_READ | PROT_WRITE, \ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ if (mem == MAP_FAILED) \ mem = NULL; \ } while (0) @@ -261,28 +302,53 @@ extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg); extern unw_dyn_info_list_t _U_dyn_info_list; extern pthread_mutex_t _U_dyn_info_list_lock; -#if UNW_DEBUG -#define unwi_debug_level UNWI_ARCH_OBJ(debug_level) +#define unw_address_is_valid UNWI_ARCH_OBJ(address_is_valid) +HIDDEN bool unw_address_is_valid(unw_word_t, size_t); + + +#if defined(UNW_DEBUG) +# define unwi_debug_level UNWI_ARCH_OBJ(debug_level) extern long unwi_debug_level; +# include # include -# define Debug(level, /* format */ ...) \ -do { \ - if (unwi_debug_level >= level) \ - { \ - int _n = level; \ - if (_n > 16) \ - _n = 16; \ - fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \ - fprintf (stderr, /* format */ __VA_ARGS__); \ - } \ -} while (0) +# include + +#define Debug(level, ...) _unw_debug(level, __FUNCTION__, __VA_ARGS__) + +/** + * Send a debug message to stderr. + * + * This function may be called from within a signal handler context where + * fprintf(3) is not safe to call. The write(2) call is safe, however, and we're + * going to have to assume that snprintf(3) is signal safe otherwise it's pretty + * pointless to use Debug() calls anywhere. + */ +static inline void _unw_debug(int level, char const * const fname, char const * const fmt, ...) +{ + if (unwi_debug_level >= level) + { + enum { buf_size = 512 }; + char buf[buf_size]; + + if (level > 16) level = 16; + int bcount = snprintf (buf, buf_size, "%*c>%s: ", level, ' ', fname); + int res = write(STDERR_FILENO, buf, bcount); + + va_list ap; + va_start(ap, fmt); + bcount = vsnprintf (buf, buf_size, fmt, ap); + va_end(ap); + res = write(STDERR_FILENO, buf, bcount); + (void)res; /* silence "variable set but not used" warning */ + } +} # define Dprintf(/* format */ ...) \ fprintf (stderr, /* format */ __VA_ARGS__) -#else +#else /* defined(UNW_DEBUG) */ # define Debug(level, /* format */ ...) # define Dprintf( /* format */ ...) -#endif +#endif /* defined(UNW_DEBUG) */ static ALWAYS_INLINE int print_error (const char *string) @@ -292,7 +358,7 @@ print_error (const char *string) HIDDEN extern long unw_page_size; -static inline unw_word_t uwn_page_start(unw_word_t addr) +static inline unw_word_t unw_page_start(unw_word_t addr) { return addr & ~(unw_page_size - 1); } @@ -326,7 +392,7 @@ struct elf_dyn_info static inline void invalidate_edi (struct elf_dyn_info *edi) { if (edi->ei.image) - munmap (edi->ei.image, edi->ei.size); + mi_munmap (edi->ei.image, edi->ei.size); memset (edi, 0, sizeof (*edi)); edi->di_cache.format = -1; edi->di_debug.format = -1; diff --git a/src/native/external/libunwind/include/remote.h b/src/native/external/libunwind/include/remote.h index 814e532cfa5ea4..99839f6622b862 100644 --- a/src/native/external/libunwind/include/remote.h +++ b/src/native/external/libunwind/include/remote.h @@ -8,8 +8,8 @@ #ifdef UNW_LOCAL_ONLY static inline int -fetch8 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int8_t *valp, void *arg) +fetch8 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, + unw_word_t *addr, int8_t *valp, void *arg UNUSED) { *valp = *(int8_t *) (uintptr_t) *addr; *addr += 1; @@ -17,8 +17,8 @@ fetch8 (unw_addr_space_t as, unw_accessors_t *a, } static inline int -fetch16 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int16_t *valp, void *arg) +fetch16 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, + unw_word_t *addr, int16_t *valp, void *arg UNUSED) { *valp = *(int16_t *) (uintptr_t) *addr; *addr += 2; @@ -26,8 +26,8 @@ fetch16 (unw_addr_space_t as, unw_accessors_t *a, } static inline int -fetch32 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int32_t *valp, void *arg) +fetch32 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, + unw_word_t *addr, int32_t *valp, void *arg UNUSED) { *valp = *(int32_t *) (uintptr_t) *addr; *addr += 4; @@ -35,8 +35,8 @@ fetch32 (unw_addr_space_t as, unw_accessors_t *a, } static inline int -fetchw (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, unw_word_t *valp, void *arg) +fetchw (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, + unw_word_t *addr, unw_word_t *valp, void *arg UNUSED) { *valp = *(unw_word_t *) (uintptr_t) *addr; *addr += sizeof (unw_word_t); diff --git a/src/native/external/libunwind/include/remote/win/unistd.h b/src/native/external/libunwind/include/remote/win/unistd.h index d4ff227871b919..b20c38490c9ac5 100644 --- a/src/native/external/libunwind/include/remote/win/unistd.h +++ b/src/native/external/libunwind/include/remote/win/unistd.h @@ -28,4 +28,10 @@ long sysconf(int name); #define _SC_PAGESIZE 11 +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#define S_ISREG(x) 0 + #endif // _MSC_VER diff --git a/src/native/external/libunwind/include/tdep-aarch64/jmpbuf.h b/src/native/external/libunwind/include/tdep-aarch64/jmpbuf.h index 3f01a442baf909..8479bf2b587536 100644 --- a/src/native/external/libunwind/include/tdep-aarch64/jmpbuf.h +++ b/src/native/external/libunwind/include/tdep-aarch64/jmpbuf.h @@ -27,7 +27,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* FIXME for AArch64 */ +#if defined __FreeBSD__ +#define JB_SP 1 +#define JB_RP 13 +#define JB_MASK_SAVED 0 +#define JB_MASK 22 +#define _JB_STK_SHIFT 0 +#else #define JB_SP 13 #define JB_RP 14 #define JB_MASK_SAVED 15 #define JB_MASK 16 +#endif diff --git a/src/native/external/libunwind/include/tdep-aarch64/libunwind_i.h b/src/native/external/libunwind/include/tdep-aarch64/libunwind_i.h index d96833a219e4fa..ec1a2e91afd643 100644 --- a/src/native/external/libunwind/include/tdep-aarch64/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-aarch64/libunwind_i.h @@ -78,6 +78,9 @@ struct unw_addr_space { struct unw_accessors acc; int big_endian; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ @@ -96,16 +99,18 @@ struct cursor { AARCH64_SCF_NONE, AARCH64_SCF_LINUX_RT_SIGFRAME, + AARCH64_SCF_FREEBSD_RT_SIGFRAME, + AARCH64_SCF_QNX_RT_SIGFRAME, } sigcontext_format; unw_word_t sigcontext_addr; unw_word_t sigcontext_sp; unw_word_t sigcontext_pc; int validate; - ucontext_t *uc; + unw_context_t *uc; }; -static inline ucontext_t * +static inline unw_context_t * dwarf_get_uc(const struct dwarf_cursor *cursor) { const struct cursor *c = (struct cursor *) cursor->as_arg; @@ -273,7 +278,6 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) #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. */ @@ -312,11 +316,10 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) extern atomic_bool tdep_init_done; extern void tdep_init (void); -extern void tdep_init_mem_validate (void); extern int 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 void *tdep_uc_addr (unw_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); @@ -328,6 +331,6 @@ extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); extern void tdep_stash_frame (struct dwarf_cursor *c, struct dwarf_reg_state *rs); -extern int tdep_getcontext_trace (unw_tdep_context_t *); +extern int tdep_getcontext_trace (unw_context_t *); #endif /* AARCH64_LIBUNWIND_I_H */ diff --git a/src/native/external/libunwind/include/tdep-arm/libunwind_i.h b/src/native/external/libunwind/include/tdep-arm/libunwind_i.h index 5bd28c953a6199..35b13c79fbaca0 100644 --- a/src/native/external/libunwind/include/tdep-arm/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-arm/libunwind_i.h @@ -64,6 +64,9 @@ struct unw_addr_space { struct unw_accessors acc; int big_endian; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ diff --git a/src/native/external/libunwind/include/tdep-hppa/libunwind_i.h b/src/native/external/libunwind/include/tdep-hppa/libunwind_i.h index fd5910d0125a34..1b6757fb13610c 100644 --- a/src/native/external/libunwind/include/tdep-hppa/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-hppa/libunwind_i.h @@ -46,6 +46,9 @@ unw_tdep_frame_t; struct unw_addr_space { struct unw_accessors acc; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ diff --git a/src/native/external/libunwind/include/tdep-ia64/libunwind_i.h b/src/native/external/libunwind/include/tdep-ia64/libunwind_i.h index 5b0defc8ef1096..04ca58f5170a2c 100644 --- a/src/native/external/libunwind/include/tdep-ia64/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-ia64/libunwind_i.h @@ -97,6 +97,9 @@ struct unw_addr_space struct unw_accessors acc; int big_endian; int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */ +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; diff --git a/src/native/external/libunwind/include/tdep-loongarch64/libunwind_i.h b/src/native/external/libunwind/include/tdep-loongarch64/libunwind_i.h index a16870f4737d55..d21c9229766e34 100644 --- a/src/native/external/libunwind/include/tdep-loongarch64/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-loongarch64/libunwind_i.h @@ -45,6 +45,9 @@ struct unw_addr_space { struct unw_accessors acc; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ @@ -230,10 +233,8 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_get_ip(c) ((c)->dwarf.ip) extern atomic_bool tdep_init_done; -#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) 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); diff --git a/src/native/external/libunwind/include/tdep-mips/libunwind_i.h b/src/native/external/libunwind/include/tdep-mips/libunwind_i.h index 343a195141be8d..b0e623499d053d 100644 --- a/src/native/external/libunwind/include/tdep-mips/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-mips/libunwind_i.h @@ -54,6 +54,9 @@ struct unw_addr_space mips_abi_t abi; unsigned int addr_size; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ diff --git a/src/native/external/libunwind/include/tdep-ppc32/libunwind_i.h b/src/native/external/libunwind/include/tdep-ppc32/libunwind_i.h index b9100e6ac894c7..46d4f5a8ed9d68 100644 --- a/src/native/external/libunwind/include/tdep-ppc32/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-ppc32/libunwind_i.h @@ -52,6 +52,9 @@ unw_tdep_frame_t; struct unw_addr_space { struct unw_accessors acc; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ diff --git a/src/native/external/libunwind/include/tdep-ppc64/libunwind_i.h b/src/native/external/libunwind/include/tdep-ppc64/libunwind_i.h index 48227c76e20916..a93d5693184334 100644 --- a/src/native/external/libunwind/include/tdep-ppc64/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-ppc64/libunwind_i.h @@ -54,6 +54,9 @@ struct unw_addr_space struct unw_accessors acc; int big_endian; ppc64_abi_t abi; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ diff --git a/src/native/external/libunwind/include/tdep-riscv/libunwind_i.h b/src/native/external/libunwind/include/tdep-riscv/libunwind_i.h index 4404a47510a4ce..951de12a0bc942 100644 --- a/src/native/external/libunwind/include/tdep-riscv/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-riscv/libunwind_i.h @@ -60,6 +60,9 @@ struct unw_addr_space int big_endian; unsigned int addr_size; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ @@ -161,7 +164,6 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) { char *valp = (char *) &val; unw_word_t addr; - int ret; if (DWARF_IS_NULL_LOC (loc)) return -UNW_EBADREG; @@ -185,7 +187,6 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) { char *valp = (char *) &val; unw_word_t addr; - int ret; if (DWARF_IS_NULL_LOC (loc)) return -UNW_EBADREG; @@ -247,7 +248,6 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #endif /* !UNW_LOCAL_ONLY */ #define tdep_getcontext_trace unw_getcontext -#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) #define tdep_init_done UNW_OBJ(init_done) #define tdep_init UNW_OBJ(init) /* Platforms that support UNW_INFO_FORMAT_TABLE need to define @@ -286,7 +286,6 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) extern atomic_bool tdep_init_done; extern void tdep_init (void); -extern void tdep_init_mem_validate (void); extern int 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); diff --git a/src/native/external/libunwind/include/tdep-s390x/libunwind_i.h b/src/native/external/libunwind/include/tdep-s390x/libunwind_i.h index ba75c0742f62cd..a6af60c9c61d5f 100644 --- a/src/native/external/libunwind/include/tdep-s390x/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-s390x/libunwind_i.h @@ -42,6 +42,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ struct unw_addr_space { struct unw_accessors acc; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ @@ -203,7 +206,6 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_getcontext_trace unw_getcontext #define tdep_init_done UNW_OBJ(init_done) -#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) #define tdep_init UNW_OBJ(init) /* Platforms that support UNW_INFO_FORMAT_TABLE need to define tdep_search_unwind_table. */ @@ -242,7 +244,6 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) extern atomic_bool tdep_init_done; extern void tdep_init (void); -extern void tdep_init_mem_validate (void); extern int 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); diff --git a/src/native/external/libunwind/include/tdep-sh/libunwind_i.h b/src/native/external/libunwind/include/tdep-sh/libunwind_i.h index 7b4fe0023b4d52..4f4a5cdd067517 100644 --- a/src/native/external/libunwind/include/tdep-sh/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-sh/libunwind_i.h @@ -47,6 +47,9 @@ struct unw_addr_space { struct unw_accessors acc; int big_endian; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ diff --git a/src/native/external/libunwind/include/tdep-tilegx/dwarf-config.h b/src/native/external/libunwind/include/tdep-tilegx/dwarf-config.h deleted file mode 100644 index 93bc6aaecced65..00000000000000 --- a/src/native/external/libunwind/include/tdep-tilegx/dwarf-config.h +++ /dev/null @@ -1,50 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 dwarf_config_h -#define dwarf_config_h - -/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not - explicitly defined. */ -#define DWARF_NUM_PRESERVED_REGS 188 - -#define DWARF_REGNUM_MAP_LENGTH (56 + 2) - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) - -/* 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; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ -#endif -} dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/native/external/libunwind/include/tdep-tilegx/jmpbuf.h b/src/native/external/libunwind/include/tdep-tilegx/jmpbuf.h deleted file mode 100644 index 3afe9e46cc499a..00000000000000 --- a/src/native/external/libunwind/include/tdep-tilegx/jmpbuf.h +++ /dev/null @@ -1,33 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -/* FIXME for Tilegx! */ - -#define JB_SP 4 -#define JB_RP 5 -#define JB_MASK_SAVED 6 -#define JB_MASK 7 diff --git a/src/native/external/libunwind/include/tdep-tilegx/libunwind_i.h b/src/native/external/libunwind/include/tdep-tilegx/libunwind_i.h deleted file mode 100644 index dc4cb7fdb2e0e1..00000000000000 --- a/src/native/external/libunwind/include/tdep-tilegx/libunwind_i.h +++ /dev/null @@ -1,260 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 TILEGX_LIBUNWIND_I_H -#define TILEGX_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include -#include - -# include "elf64.h" -#include "mempool.h" -#include "dwarf.h" - -typedef struct -{ - /* no Tilegx-specific fast trace */ -} unw_tdep_frame_t; - -struct unw_addr_space -{ - struct unw_accessors acc; - - int big_endian; - tilegx_abi_t abi; - unsigned int addr_size; - - unw_caching_policy_t caching_policy; - _Atomic uint32_t cache_generation; - 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; -}; - -#define tdep_big_endian(as) ((as)->big_endian) - -struct cursor -{ - struct dwarf_cursor dwarf; /* must be first */ - unw_word_t sigcontext_addr; - unw_word_t sigcontext_sp; - unw_word_t sigcontext_pc; -}; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifndef UNW_REMOTE_ONLY -typedef long tilegx_reg_t; -#endif - -#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_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -#define DWARF_IS_REG_LOC(l) 0 -#define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -#define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -/* Tilegx has no FP. */ -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - - *val = *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - - *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ -#define DWARF_LOC_TYPE_FP (1 << 0) -#define DWARF_LOC_TYPE_REG (1 << 1) -#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_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -#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_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -#define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -/* TILEGX has no fp. */ -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_needs_initialization UNW_OBJ(needs_initialization) -#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_uc_addr UNW_ARCH_OBJ(uc_addr) -#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,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) - -#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) - -extern atomic_bool tdep_init_done; - -extern void tdep_init (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 (ucontext_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 /* TILEGX_LIBUNWIND_I_H */ diff --git a/src/native/external/libunwind/include/tdep-x86/jmpbuf.h b/src/native/external/libunwind/include/tdep-x86/jmpbuf.h index 521dfa6992b36e..625dac32693445 100644 --- a/src/native/external/libunwind/include/tdep-x86/jmpbuf.h +++ b/src/native/external/libunwind/include/tdep-x86/jmpbuf.h @@ -38,5 +38,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define JB_RP 0 #define JB_MASK_SAVED 11 #define JB_MASK 7 +#define _JB_STK_SHIFT 4 #endif diff --git a/src/native/external/libunwind/include/tdep-x86/libunwind_i.h b/src/native/external/libunwind/include/tdep-x86/libunwind_i.h index ad4edc2f5ac849..58e583c3b3f27a 100644 --- a/src/native/external/libunwind/include/tdep-x86/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-x86/libunwind_i.h @@ -46,6 +46,9 @@ unw_tdep_frame_t; struct unw_addr_space { struct unw_accessors acc; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ diff --git a/src/native/external/libunwind/include/tdep-x86_64/jmpbuf.h b/src/native/external/libunwind/include/tdep-x86_64/jmpbuf.h index b2e5332b059661..c5dd87a777af96 100644 --- a/src/native/external/libunwind/include/tdep-x86_64/jmpbuf.h +++ b/src/native/external/libunwind/include/tdep-x86_64/jmpbuf.h @@ -37,8 +37,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define JB_SP 2 #define JB_RP 0 +#ifdef __amd64__ +#define JB_MASK_SAVED 11 +#else /* Pretend the ip cannot be 0 and mask is always saved */ #define JB_MASK_SAVED 0 +#endif #define JB_MASK 9 +#define _JB_STK_SHIFT 8 #endif diff --git a/src/native/external/libunwind/include/tdep-x86_64/libunwind_i.h b/src/native/external/libunwind/include/tdep-x86_64/libunwind_i.h index ff0436a09c42a2..7ec16aafdcdc02 100644 --- a/src/native/external/libunwind/include/tdep-x86_64/libunwind_i.h +++ b/src/native/external/libunwind/include/tdep-x86_64/libunwind_i.h @@ -65,6 +65,9 @@ unw_tdep_frame_t; struct unw_addr_space { struct unw_accessors acc; +#ifndef UNW_REMOTE_ONLY + unw_iterate_phdr_func_t iterate_phdr_function; +#endif unw_caching_policy_t caching_policy; _Atomic uint32_t cache_generation; unw_word_t dyn_generation; /* see dyn-common.h */ @@ -172,7 +175,7 @@ dwarf_is_null_loc(dwarf_loc_t l) #endif /* !UNW_LOCAL_ONLY */ static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +dwarf_getfp (struct dwarf_cursor *c UNUSED, dwarf_loc_t loc, unw_fpreg_t *val UNUSED) { if (DWARF_IS_NULL_LOC (loc)) return -UNW_EBADREG; @@ -181,7 +184,7 @@ dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) } static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +dwarf_putfp (struct dwarf_cursor *c UNUSED, dwarf_loc_t loc, unw_fpreg_t val UNUSED) { if (DWARF_IS_NULL_LOC (loc)) return -UNW_EBADREG; @@ -224,7 +227,6 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) #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. */ @@ -269,7 +271,6 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) extern atomic_bool tdep_init_done; extern void tdep_init (void); -extern void tdep_init_mem_validate (void); extern int 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); @@ -288,9 +289,9 @@ extern void tdep_fetch_frame (struct dwarf_cursor *c, unw_word_t ip, extern int tdep_cache_frame (struct dwarf_cursor *c); extern void tdep_reuse_frame (struct dwarf_cursor *c, int frame); +#endif extern void tdep_stash_frame (struct dwarf_cursor *c, struct dwarf_reg_state *rs); -#endif extern int tdep_getcontext_trace (unw_tdep_context_t *); extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); diff --git a/src/native/external/libunwind/include/tdep/dwarf-config.h b/src/native/external/libunwind/include/tdep/dwarf-config.h index a37f4220e3574d..67ebcc934bd429 100644 --- a/src/native/external/libunwind/include/tdep/dwarf-config.h +++ b/src/native/external/libunwind/include/tdep/dwarf-config.h @@ -23,8 +23,6 @@ # include "tdep-x86/dwarf-config.h" #elif defined __x86_64__ || defined __amd64__ # include "tdep-x86_64/dwarf-config.h" -#elif defined __tilegx__ -# include "tdep-tilegx/dwarf-config.h" #elif defined __riscv || defined __riscv__ # include "tdep-riscv/dwarf-config.h" #elif defined __loongarch64 diff --git a/src/native/external/libunwind/include/tdep/jmpbuf.h b/src/native/external/libunwind/include/tdep/jmpbuf.h index 01b9ee0245e82c..0c033336ae949a 100644 --- a/src/native/external/libunwind/include/tdep/jmpbuf.h +++ b/src/native/external/libunwind/include/tdep/jmpbuf.h @@ -21,8 +21,6 @@ # include "tdep-x86/jmpbuf.h" #elif defined __x86_64__ # include "tdep-x86_64/jmpbuf.h" -#elif defined __tilegx__ -# include "tdep-tilegx/jmpbuf.h" #elif defined __riscv || defined __riscv__ # include "tdep-riscv/jmpbuf.h" #elif defined __loongarch64 diff --git a/src/native/external/libunwind/include/tdep/libunwind_i.h.in b/src/native/external/libunwind/include/tdep/libunwind_i.h.in index 1bacc3a8235ead..f026744665dceb 100644 --- a/src/native/external/libunwind/include/tdep/libunwind_i.h.in +++ b/src/native/external/libunwind/include/tdep/libunwind_i.h.in @@ -23,8 +23,6 @@ # include "tdep-x86/libunwind_i.h" #elif defined __x86_64__ # 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" #elif defined __riscv || defined __riscv__ diff --git a/src/native/external/libunwind/src/CMakeLists.txt b/src/native/external/libunwind/src/CMakeLists.txt index eee31afa6aae4a..0284d584bb7d76 100644 --- a/src/native/external/libunwind/src/CMakeLists.txt +++ b/src/native/external/libunwind/src/CMakeLists.txt @@ -21,6 +21,7 @@ elseif(TARGET_AARCH64) endif() SET(libunwind_ptrace_la_SOURCES + mi/init.c ptrace/_UPT_elf.c ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c @@ -28,6 +29,7 @@ SET(libunwind_ptrace_la_SOURCES ptrace/_UPT_find_proc_info.c ptrace/_UPT_get_dyn_info_list_addr.c ptrace/_UPT_put_unwind_info.c ptrace/_UPT_get_proc_name.c ptrace/_UPT_reg_offset.c ptrace/_UPT_resume.c + ptrace/_UPT_get_elf_filename.c ) SET(libunwind_coredump_la_SOURCES @@ -38,7 +40,9 @@ SET(libunwind_coredump_la_SOURCES coredump/_UCD_elf_map_image.c coredump/_UCD_find_proc_info.c coredump/_UCD_get_proc_name.c + coredump/_UCD_get_elf_filename.c + mi/init.c coredump/_UPT_elf.c coredump/_UPT_access_fpreg.c coredump/_UPT_get_dyn_info_list_addr.c @@ -58,6 +62,8 @@ SET(libunwind_la_SOURCES_generic mi/Gget_fpreg.c mi/Gset_fpreg.c mi/Gset_caching_policy.c mi/Gset_cache_size.c + mi/Gset_iterate_phdr_function.c + mi/Gget_elf_filename.c ) SET(libunwind_la_SOURCES_os_linux @@ -141,6 +147,8 @@ SET(libunwind_la_SOURCES_local_nounwind mi/Lget_fpreg.c mi/Lset_fpreg.c mi/Lset_caching_policy.c mi/Lset_cache_size.c + mi/Lset_iterate_phdr_function.c + mi/Lget_elf_filename.c ) SET(libunwind_la_SOURCES_local diff --git a/src/native/external/libunwind/src/Makefile.am b/src/native/external/libunwind/src/Makefile.am index 9bfb5ded1a52f0..63041fd306f010 100644 --- a/src/native/external/libunwind/src/Makefile.am +++ b/src/native/external/libunwind/src/Makefile.am @@ -1,179 +1,328 @@ -SOVERSION=8:1:0 # See comments at end of file. +# +# This file is a part of the libunwind project. +# +# 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: +# +# 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. +# + +# Set the DSO versions +SOVERSION=9:0:1 # See comments at end of file. SETJMP_SO_VERSION=0:0:0 COREDUMP_SO_VERSION=0:0:0 + # # Don't link with start-files since we don't use any constructors/destructors: # COMMON_SO_LDFLAGS = $(LDFLAGS_NOSTARTFILES) -lib_LIBRARIES = +# +# Which libraries to build and install +# +# Order is important here. The names of the libraries need to end up in reverse +# dependency order for `make install` to do its job properly. +# lib_LTLIBRARIES = if !REMOTE_ONLY -lib_LTLIBRARIES += libunwind.la -if BUILD_PTRACE -lib_LTLIBRARIES += libunwind-ptrace.la + lib_LTLIBRARIES += libunwind.la +endif +if ARCH_AARCH64 + lib_LTLIBRARIES += libunwind-aarch64.la +endif +if ARCH_ARM + lib_LTLIBRARIES += libunwind-arm.la +endif +if ARCH_HPPA + lib_LTLIBRARIES += libunwind-hppa.la +endif +if ARCH_IA64 + lib_LTLIBRARIES += libunwind-ia64.la +endif +if ARCH_LOONGARCH64 + lib_LTLIBRARIES += libunwind-loongarch64.la +endif +if ARCH_MIPS + lib_LTLIBRARIES += libunwind-mips.la +endif +if ARCH_PPC32 + lib_LTLIBRARIES += libunwind-ppc32.la +endif +if ARCH_PPC64 + lib_LTLIBRARIES += libunwind-ppc64.la +endif +if ARCH_RISCV + lib_LTLIBRARIES += libunwind-riscv.la +endif +if ARCH_S390X + lib_LTLIBRARIES += libunwind-s390x.la endif +if ARCH_SH + lib_LTLIBRARIES += libunwind-sh.la +endif +if ARCH_X86 + lib_LTLIBRARIES += libunwind-x86.la +endif +if ARCH_X86_64 + lib_LTLIBRARIES += libunwind-x86_64.la +endif + if BUILD_COREDUMP -lib_LTLIBRARIES += libunwind-coredump.la + lib_LTLIBRARIES += libunwind-coredump.la endif +if BUILD_NTO + lib_LTLIBRARIES += libunwind-nto.la +endif +if BUILD_PTRACE + lib_LTLIBRARIES += libunwind-ptrace.la +endif +if BUILD_SETJMP + lib_LTLIBRARIES += libunwind-setjmp.la endif noinst_HEADERS = noinst_LTLIBRARIES = +if USE_ELF32 +libunwind_elf_libs = libunwind-elf32.la +endif +if USE_ELF64 +libunwind_elf_libs = libunwind-elf64.la +endif +if USE_ELFXX +libunwind_elf_libs = libunwind-elfxx.la +endif + +# If local unwinding is being built, link in the local unwinding functions +libunwind_libadd = +if !REMOTE_ONLY + libunwind_libadd += libunwind.la -lc +endif + +### pkg-config: pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libunwind-generic.pc if !REMOTE_ONLY pkgconfig_DATA += unwind/libunwind.pc endif - +if BUILD_COREDUMP +pkgconfig_DATA += coredump/libunwind-coredump.pc +endif if BUILD_PTRACE pkgconfig_DATA += ptrace/libunwind-ptrace.pc endif - if BUILD_SETJMP pkgconfig_DATA += setjmp/libunwind-setjmp.pc endif -if BUILD_COREDUMP -pkgconfig_DATA += coredump/libunwind-coredump.pc -endif - -### libunwind-ptrace: -libunwind_ptrace_la_SOURCES = \ - ptrace/_UPT_elf.c \ - ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c \ - ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c \ - ptrace/_UPT_create.c ptrace/_UPT_destroy.c \ - ptrace/_UPT_find_proc_info.c ptrace/_UPT_get_dyn_info_list_addr.c \ - ptrace/_UPT_put_unwind_info.c ptrace/_UPT_get_proc_name.c \ - ptrace/_UPT_reg_offset.c ptrace/_UPT_resume.c -noinst_HEADERS += ptrace/_UPT_internal.h - ### libunwind-coredump: -libunwind_coredump_la_SOURCES = \ - coredump/_UCD_accessors.c \ - coredump/_UCD_create.c \ - coredump/_UCD_destroy.c \ - coredump/_UCD_access_mem.c \ - coredump/_UCD_elf_map_image.c \ - coredump/_UCD_find_proc_info.c \ - coredump/_UCD_get_proc_name.c \ - coredump/_UCD_corefile_elf.c \ - coredump/ucd_file_table.c \ +noinst_HEADERS += coredump/_UCD_internal.h \ + coredump/_UCD_lib.h \ + coredump/ucd_file_table.h +libunwind_coredump_la_SOURCES = \ + coredump/_UCD_access_mem.c \ + coredump/_UCD_accessors.c \ + coredump/_UCD_corefile_elf.c \ + coredump/_UCD_create.c \ + coredump/_UCD_destroy.c \ + coredump/_UCD_elf_map_image.c \ + coredump/ucd_file_table.c \ + coredump/_UCD_find_proc_info.c \ + coredump/_UCD_get_proc_name.c \ + coredump/_UCD_get_elf_filename.c \ \ - coredump/_UPT_elf.c \ - coredump/_UPT_access_fpreg.c \ + mi/init.c \ + coredump/_UPT_elf.c \ + coredump/_UPT_access_fpreg.c \ coredump/_UPT_get_dyn_info_list_addr.c \ - coredump/_UPT_put_unwind_info.c \ + coredump/_UPT_put_unwind_info.c \ coredump/_UPT_resume.c -libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ - -version-info $(COREDUMP_SO_VERSION) -libunwind_coredump_la_LIBADD = $(LIBLZMA) $(LIBZ) -noinst_HEADERS += coredump/_UCD_internal.h \ - coredump/_UCD_lib.h \ - coredump/ucd_file_table.h +libunwind_coredump_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(COREDUMP_SO_VERSION) +libunwind_coredump_la_LIBADD = \ + libunwind-$(arch).la \ + $(LIBLZMA) $(LIBZ) + +### libunwind-nto: +noinst_HEADERS += nto/unw_nto_internal.h +libunwind_nto_la_SOURCES = \ + mi/init.c \ + nto/unw_nto_access_fpreg.c \ + nto/unw_nto_access_mem.c \ + nto/unw_nto_accessors.c \ + nto/unw_nto_access_reg.c \ + nto/unw_nto_create.c \ + nto/unw_nto_destroy.c \ + nto/unw_nto_elf.c \ + nto/unw_nto_find_proc_info.c \ + nto/unw_nto_get_dyn_info_list_addr.c \ + nto/unw_nto_get_proc_name.c \ + nto/unw_nto_get_elf_filename.c \ + nto/unw_nto_put_unwind_info.c \ + nto/unw_nto_resume.c +libunwind_nto_la_LIBADD = \ + libunwind-$(arch).la \ + $(libunwind_libadd) -### libunwind-setjmp: -libunwind_setjmp_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ - -version-info $(SETJMP_SO_VERSION) - -if USE_ELF32 -LIBUNWIND_ELF = libunwind-elf32.la -endif -if USE_ELF64 -LIBUNWIND_ELF = libunwind-elf64.la -endif -if USE_ELFXX -LIBUNWIND_ELF = libunwind-elfxx.la -endif +### libunwind-ptrace: +noinst_HEADERS += ptrace/_UPT_internal.h +libunwind_ptrace_la_SOURCES = \ + mi/init.c \ + ptrace/_UPT_access_fpreg.c \ + ptrace/_UPT_access_mem.c \ + ptrace/_UPT_accessors.c \ + ptrace/_UPT_access_reg.c \ + ptrace/_UPT_create.c \ + ptrace/_UPT_destroy.c \ + ptrace/_UPT_elf.c \ + ptrace/_UPT_find_proc_info.c \ + ptrace/_UPT_get_dyn_info_list_addr.c \ + ptrace/_UPT_get_proc_name.c \ + ptrace/_UPT_get_elf_filename.c \ + ptrace/_UPT_put_unwind_info.c \ + ptrace/_UPT_reg_offset.c \ + ptrace/_UPT_resume.c +libunwind_ptrace_la_LIBADD = \ + libunwind-$(arch).la \ + $(LIBLZMA) $(LIBZ) -libunwind_setjmp_la_LIBADD = $(LIBUNWIND_ELF) \ - libunwind-$(arch).la \ - libunwind.la -lc -libunwind_setjmp_la_SOURCES = setjmp/longjmp.c \ - setjmp/siglongjmp.c -noinst_HEADERS += setjmp/setjmp_i.h +### libunwind-setjmp: +noinst_HEADERS += setjmp/setjmp_i.h +libunwind_setjmp_la_SOURCES = \ + mi/init.c \ + setjmp/longjmp.c \ + setjmp/siglongjmp.c +libunwind_setjmp_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SETJMP_SO_VERSION) +libunwind_setjmp_la_LIBADD = \ + $(libunwind_elf_libs) \ + libunwind-$(arch).la \ + $(libunwind_libadd) ### libunwind: libunwind_la_LIBADD = # List of arch-independent files needed by both local-only and generic # libraries: -libunwind_la_SOURCES_common = \ - $(libunwind_la_SOURCES_os) \ - mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c +libunwind_la_SOURCES_common = \ + $(libunwind_la_SOURCES_os) \ + mi/init.c \ + mi/flush_cache.c \ + mi/mempool.c \ + mi/strerror.c # List of arch-independent files needed by generic library (libunwind-$ARCH): -libunwind_la_SOURCES_generic = \ - mi/Gdyn-extract.c mi/Gdyn-remote.c mi/Gfind_dynamic_proc_info.c \ - mi/Gget_accessors.c \ - mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \ - mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \ - mi/Gget_reg.c mi/Gset_reg.c \ - mi/Gget_fpreg.c mi/Gset_fpreg.c \ - mi/Gset_caching_policy.c \ - mi/Gset_cache_size.c +libunwind_la_SOURCES_generic = \ + mi/Gaddress_validator.c \ + mi/Gdestroy_addr_space.c \ + mi/Gdyn-extract.c \ + mi/Gdyn-remote.c \ + mi/Gfind_dynamic_proc_info.c \ + mi/Gget_accessors.c \ + mi/Gget_fpreg.c \ + mi/Gget_proc_info_by_ip.c \ + mi/Gget_proc_name.c \ + mi/Gget_reg.c \ + mi/Gput_dynamic_unwind_info.c \ + mi/Gset_cache_size.c \ + mi/Gset_caching_policy.c \ + mi/Gset_fpreg.c \ + mi/Gset_iterate_phdr_function.c \ + mi/Gset_reg.c \ + mi/Gget_elf_filename.c if SUPPORT_CXX_EXCEPTIONS -libunwind_la_SOURCES_local_unwind = \ - unwind/Backtrace.c unwind/DeleteException.c \ - unwind/FindEnclosingFunction.c unwind/ForcedUnwind.c \ - unwind/GetBSP.c unwind/GetCFA.c unwind/GetDataRelBase.c \ - unwind/GetGR.c unwind/GetIP.c unwind/GetLanguageSpecificData.c \ - unwind/GetRegionStart.c unwind/GetTextRelBase.c \ - unwind/RaiseException.c unwind/Resume.c \ - unwind/Resume_or_Rethrow.c unwind/SetGR.c unwind/SetIP.c \ - unwind/GetIPInfo.c +libunwind_la_SOURCES_local_unwind = \ + unwind/Backtrace.c \ + unwind/DeleteException.c \ + unwind/FindEnclosingFunction.c \ + unwind/ForcedUnwind.c \ + unwind/GetBSP.c \ + unwind/GetCFA.c \ + unwind/GetDataRelBase.c \ + unwind/GetGR.c \ + unwind/GetIP.c \ + unwind/GetIPInfo.c \ + unwind/GetLanguageSpecificData.c \ + unwind/GetRegionStart.c \ + unwind/GetTextRelBase.c \ + unwind/RaiseException.c \ + unwind/Resume.c \ + unwind/Resume_or_Rethrow.c \ + unwind/SetGR.c \ + unwind/SetIP.c # _ReadULEB()/_ReadSLEB() are needed for Intel C++ 8.0 compatibility -libunwind_la_SOURCES_os_linux_local = mi/_ReadULEB.c mi/_ReadSLEB.c -endif +libunwind_la_SOURCES_os_linux_local = \ + mi/_ReadULEB.c \ + mi/_ReadSLEB.c +endif SUPPORT_CXX_EXCEPTIONS # List of arch-independent files needed by local-only library (libunwind): -libunwind_la_SOURCES_local_nounwind = \ - $(libunwind_la_SOURCES_os_local) \ - mi/backtrace.c \ - mi/dyn-cancel.c mi/dyn-info-list.c mi/dyn-register.c \ - mi/Ldyn-extract.c mi/Lfind_dynamic_proc_info.c \ - mi/Lget_accessors.c \ - mi/Lget_proc_info_by_ip.c mi/Lget_proc_name.c \ - mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \ - mi/Lget_reg.c mi/Lset_reg.c \ - mi/Lget_fpreg.c mi/Lset_fpreg.c \ - mi/Lset_caching_policy.c \ - mi/Lset_cache_size.c - -libunwind_la_SOURCES_local = \ - $(libunwind_la_SOURCES_local_nounwind) \ +libunwind_la_SOURCES_local_nounwind = \ + $(libunwind_la_SOURCES_os_local) \ + mi/backtrace.c \ + mi/dyn-cancel.c \ + mi/dyn-info-list.c \ + mi/dyn-register.c \ + mi/Laddress_validator.c \ + mi/Ldestroy_addr_space.c \ + mi/Ldyn-extract.c \ + mi/Lfind_dynamic_proc_info.c \ + mi/Lget_accessors.c \ + mi/Lget_fpreg.c mi/Lset_fpreg.c \ + mi/Lget_proc_info_by_ip.c \ + mi/Lget_proc_name.c \ + mi/Lget_reg.c \ + mi/Lput_dynamic_unwind_info.c \ + mi/Lset_cache_size.c \ + mi/Lset_caching_policy.c \ + mi/Lset_iterate_phdr_function.c \ + mi/Lset_reg.c \ + mi/Lget_elf_filename.c + +libunwind_la_SOURCES_local = \ + $(libunwind_la_SOURCES_local_nounwind) \ $(libunwind_la_SOURCES_local_unwind) noinst_HEADERS += os-linux.h -libunwind_la_SOURCES_os_linux = os-linux.c dl-iterate-phdr.c - -libunwind_la_SOURCES_os_hpux = os-hpux.c - -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 = \ - dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c dwarf/Lpe.c \ - dwarf/Lfind_proc_info-lsb.c \ - dwarf/Lfind_unwind_table.c \ - dwarf/Lget_proc_info_in_range.c +libunwind_dwarf_local_la_SOURCES = \ + dwarf/Lexpr.c \ + dwarf/Lfde.c \ + dwarf/Lfind_proc_info-lsb.c \ + dwarf/Lfind_unwind_table.c \ + dwarf/Lget_proc_info_in_range.c \ + dwarf/Lparser.c \ + dwarf/Lpe.c libunwind_dwarf_local_la_LIBADD = libunwind-dwarf-common.la -libunwind_dwarf_generic_la_SOURCES = \ - dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c \ - dwarf/Gfind_proc_info-lsb.c \ - dwarf/Gfind_unwind_table.c \ - dwarf/Gget_proc_info_in_range.c +libunwind_dwarf_generic_la_SOURCES = \ + dwarf/Gexpr.c \ + dwarf/Gfde.c \ + dwarf/Gfind_proc_info-lsb.c \ + dwarf/Gfind_unwind_table.c \ + dwarf/Gget_proc_info_in_range.c \ + dwarf/Gparser.c \ + dwarf/Gpe.c libunwind_dwarf_generic_la_LIBADD = libunwind-dwarf-common.la if USE_DWARF @@ -193,354 +342,878 @@ libunwind_elf32_la_LIBADD = $(LIBLZMA) $(LIBZ) libunwind_elf64_la_LIBADD = $(LIBLZMA) $(LIBZ) libunwind_elfxx_la_LIBADD = $(LIBLZMA) $(LIBZ) -noinst_LTLIBRARIES += $(LIBUNWIND_ELF) -libunwind_la_LIBADD += $(LIBUNWIND_ELF) +noinst_LTLIBRARIES += $(libunwind_elf_libs) +libunwind_la_LIBADD += $(libunwind_elf_libs) -# The list of files that go into libunwind and libunwind-aarch64: -noinst_HEADERS += aarch64/init.h aarch64/offsets.h aarch64/unwind_i.h -libunwind_la_SOURCES_aarch64_common = $(libunwind_la_SOURCES_common) \ - aarch64/is_fpreg.c aarch64/regname.c +if OS_LINUX + libunwind_la_SOURCES_os = os-linux.c dl-iterate-phdr.c + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_linux_local) + libunwind_la_SOURCES_aarch64_os = aarch64/Gos-linux.c + libunwind_la_SOURCES_aarch64_os_local = aarch64/Los-linux.c + libunwind_la_SOURCES_arm_os = arm/Gos-linux.c + libunwind_la_SOURCES_arm_os_local = arm/Los-linux.c + libunwind_la_SOURCES_x86_os = x86/Gos-linux.c + libunwind_la_SOURCES_x86_os_local = x86/Los-linux.c x86/getcontext-linux.S + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-linux.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_linux.c + libunwind_coredump_la_SOURCES += coredump/_UCD_get_threadinfo_prstatus.c + libunwind_coredump_la_SOURCES += coredump/_UCD_get_mapinfo_linux.c +endif -# The list of files that go into libunwind: -libunwind_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ - $(libunwind_la_SOURCES_local) \ - aarch64/Lapply_reg_state.c aarch64/Lreg_states_iterate.c \ - aarch64/Lcreate_addr_space.c aarch64/Lget_proc_info.c \ - aarch64/Lget_save_loc.c aarch64/Lglobal.c aarch64/Linit.c \ - aarch64/Linit_local.c aarch64/Linit_remote.c \ - aarch64/Lis_signal_frame.c aarch64/Lregs.c aarch64/Lresume.c \ - aarch64/Lstash_frame.c aarch64/Lstep.c aarch64/Ltrace.c \ - aarch64/getcontext.S - -libunwind_aarch64_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ - $(libunwind_la_SOURCES_generic) \ - aarch64/Gapply_reg_state.c aarch64/Greg_states_iterate.c \ - aarch64/Gcreate_addr_space.c aarch64/Gget_proc_info.c \ - aarch64/Gget_save_loc.c aarch64/Gglobal.c aarch64/Ginit.c \ - aarch64/Ginit_local.c aarch64/Ginit_remote.c \ - aarch64/Gis_signal_frame.c aarch64/Gregs.c aarch64/Gresume.c \ - aarch64/Gstash_frame.c aarch64/Gstep.c aarch64/Gtrace.c +if OS_HPUX + libunwind_la_SOURCES_os = os-hpux.c + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_hpux_local) +endif -# The list of files that go into libunwind and libunwind-arm: -noinst_HEADERS += arm/init.h arm/offsets.h arm/unwind_i.h -libunwind_la_SOURCES_arm_common = $(libunwind_la_SOURCES_common) \ - arm/is_fpreg.c arm/regname.c +if OS_FREEBSD + libunwind_la_SOURCES_os = os-freebsd.c + libunwind_la_SOURCES_aarch64_os = aarch64/Gos-freebsd.c + libunwind_la_SOURCES_aarch64_os_local = aarch64/Los-freebsd.c aarch64/setcontext.S + libunwind_la_SOURCES_arm_os = arm/Gos-freebsd.c + libunwind_la_SOURCES_arm_os_local = arm/Los-freebsd.c + libunwind_la_SOURCES_x86_os = x86/Gos-freebsd.c + libunwind_la_SOURCES_x86_os_local = x86/Los-freebsd.c x86/getcontext-freebsd.S + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-freebsd.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-freebsd.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c + libunwind_coredump_la_SOURCES += coredump/_UCD_get_threadinfo_prstatus.c + libunwind_coredump_la_SOURCES += coredump/_UCD_get_mapinfo_generic.c +endif -# The list of files that go into libunwind: -libunwind_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ - $(libunwind_la_SOURCES_arm_os_local) \ - $(libunwind_la_SOURCES_local) \ - arm/getcontext.S \ - arm/Lapply_reg_state.c arm/Lreg_states_iterate.c \ - arm/Lcreate_addr_space.c arm/Lget_proc_info.c arm/Lget_save_loc.c \ - arm/Lglobal.c arm/Linit.c arm/Linit_local.c arm/Linit_remote.c \ - arm/Lregs.c arm/Lresume.c arm/Lstep.c \ - arm/Lex_tables.c arm/Lstash_frame.c arm/Ltrace.c +if OS_SOLARIS + libunwind_la_SOURCES_os = os-solaris.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-solaris.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-solaris.c +endif -# The list of files that go into libunwind-arm: -libunwind_arm_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ - $(libunwind_la_SOURCES_arm_os) \ - $(libunwind_la_SOURCES_generic) \ - arm/Gapply_reg_state.c arm/Greg_states_iterate.c \ - arm/Gcreate_addr_space.c arm/Gget_proc_info.c arm/Gget_save_loc.c \ - arm/Gglobal.c arm/Ginit.c arm/Ginit_local.c arm/Ginit_remote.c \ - arm/Gregs.c arm/Gresume.c arm/Gstep.c \ - arm/Gex_tables.c arm/Gstash_frame.c arm/Gtrace.c +if OS_QNX + libunwind_la_SOURCES_os = os-qnx.c + libunwind_la_SOURCES_aarch64_os = aarch64/Gos-qnx.c + libunwind_la_SOURCES_aarch64_os_local = aarch64/Los-qnx.c + libunwind_la_SOURCES_arm_os = arm/Gos-other.c + libunwind_la_SOURCES_arm_os_local = arm/Los-other.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-qnx.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-qnx.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_qnx.c + libunwind_coredump_la_SOURCES += coredump/_UCD_get_threadinfo_prstatus.c + libunwind_coredump_la_SOURCES += coredump/_UCD_get_mapinfo_qnx.c +endif -# The list of files that go both into libunwind and libunwind-ia64: -noinst_HEADERS += ia64/init.h ia64/offsets.h ia64/regs.h \ - ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h -libunwind_la_SOURCES_ia64_common = $(libunwind_la_SOURCES_common) \ - ia64/regname.c -libunwind_la_EXTRAS_ia64 = ia64/mk_cursor_i ia64/mk_Lcursor_i.c \ - ia64/mk_Gcursor_i.c +### target AArch64: +# The list of files that go into libunwind and libunwind-aarch64: +noinst_HEADERS += aarch64/init.h aarch64/ucontext_i.h aarch64/unwind_i.h +libunwind_la_SOURCES_aarch64_common = \ + $(libunwind_la_SOURCES_common) \ + aarch64/is_fpreg.c \ + aarch64/regname.c # The list of files that go into libunwind: -libunwind_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ - $(libunwind_la_SOURCES_local) \ - \ - ia64/dyn_info_list.S ia64/getcontext.S \ - \ - ia64/Lapply_reg_state.c ia64/Lreg_states_iterate.c \ - ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \ - ia64/Lglobal.c ia64/Linit.c ia64/Linit_local.c ia64/Linit_remote.c \ - ia64/Linstall_cursor.S ia64/Lis_signal_frame.c ia64/Lparser.c \ - ia64/Lrbs.c ia64/Lregs.c ia64/Lresume.c ia64/Lscript.c ia64/Lstep.c \ - ia64/Ltables.c ia64/Lfind_unwind_table.c +if ARCH_AARCH64 +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_aarch64_os_local) \ + aarch64/getcontext.S \ + aarch64/Lapply_reg_state.c \ + aarch64/Lcreate_addr_space.c \ + aarch64/Lget_proc_info.c \ + aarch64/Lget_save_loc.c \ + aarch64/Lglobal.c \ + aarch64/Linit.c \ + aarch64/Linit_local.c \ + aarch64/Linit_remote.c \ + aarch64/Lis_signal_frame.c \ + aarch64/Lregs.c \ + aarch64/Lreg_states_iterate.c \ + aarch64/Lresume.c \ + aarch64/Lstash_frame.c \ + aarch64/Lstep.c \ + aarch64/Ltrace.c + +libunwind_setjmp_la_SOURCES += \ + aarch64/longjmp.S \ + aarch64/siglongjmp.S +endif ARCH_AARCH64 + +libunwind_aarch64_la_SOURCES = \ + $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_la_SOURCES_aarch64_os) \ + aarch64/Gapply_reg_state.c \ + aarch64/Gcreate_addr_space.c \ + aarch64/Gget_proc_info.c \ + aarch64/Gget_save_loc.c \ + aarch64/Gglobal.c \ + aarch64/Ginit.c \ + aarch64/Ginit_local.c \ + aarch64/Ginit_remote.c \ + aarch64/Gis_signal_frame.c \ + aarch64/Gregs.c \ + aarch64/Greg_states_iterate.c \ + aarch64/Gresume.c \ + aarch64/Gstash_frame.c \ + aarch64/Gstep.c \ + aarch64/Gtrace.c +libunwind_aarch64_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_aarch64_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf64.la \ + $(libunwind_libadd) + +### target ARMv7: +# The list of files that go into libunwind and libunwind-arm: +noinst_HEADERS += \ + arm/init.h \ + arm/offsets.h \ + arm/unwind_i.h +libunwind_la_SOURCES_arm_common = \ + $(libunwind_la_SOURCES_common) \ + arm/is_fpreg.c arm/regname.c -# The list of files that go into libunwind-ia64: -libunwind_ia64_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ - $(libunwind_la_SOURCES_generic) \ - ia64/Gapply_reg_state.c ia64/Greg_states_iterate.c \ - ia64/Gcreate_addr_space.c ia64/Gget_proc_info.c ia64/Gget_save_loc.c \ - ia64/Gglobal.c ia64/Ginit.c ia64/Ginit_local.c ia64/Ginit_remote.c \ - ia64/Ginstall_cursor.S ia64/Gis_signal_frame.c ia64/Gparser.c \ - ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c ia64/Gstep.c \ - ia64/Gtables.c ia64/Gfind_unwind_table.c +# The list of files that go into libunwind: +if ARCH_ARM +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_arm_os_local) \ + $(libunwind_la_SOURCES_local) \ + arm/getcontext.S \ + arm/Lapply_reg_state.c \ + arm/Lcreate_addr_space.c \ + arm/Lex_tables.c \ + arm/Lget_proc_info.c \ + arm/Lget_save_loc.c \ + arm/Lglobal.c arm/Linit.c \ + arm/Linit_local.c \ + arm/Linit_remote.c \ + arm/Lregs.c \ + arm/Lreg_states_iterate.c \ + arm/Lresume.c \ + arm/Lstash_frame.c \ + arm/Lstep.c \ + arm/Ltrace.c + +libunwind_setjmp_la_SOURCES += arm/siglongjmp.S +endif # ARCH_ARM +# The list of files that go into libunwind-arm: +libunwind_arm_la_SOURCES = \ + $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_arm_os) \ + $(libunwind_la_SOURCES_generic) \ + arm/Gapply_reg_state.c \ + arm/Gcreate_addr_space.c \ + arm/Gex_tables.c \ + arm/Gget_proc_info.c \ + arm/Gget_save_loc.c \ + arm/Gglobal.c \ + arm/Ginit.c \ + arm/Ginit_local.c \ + arm/Ginit_remote.c \ + arm/Gregs.c \ + arm/Greg_states_iterate.c \ + arm/Gresume.c \ + arm/Gstash_frame.c \ + arm/Gstep.c \ + arm/Gtrace.c +libunwind_arm_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_arm_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf32.la \ + $(libunwind_libadd) + +### target HP-PA: # The list of files that go both into libunwind and libunwind-hppa: -noinst_HEADERS += hppa/init.h hppa/offsets.h hppa/unwind_i.h -libunwind_la_SOURCES_hppa_common = $(libunwind_la_SOURCES_common) \ +noinst_HEADERS += \ + hppa/init.h \ + hppa/offsets.h \ + hppa/unwind_i.h +libunwind_la_SOURCES_hppa_common = \ + $(libunwind_la_SOURCES_common) \ hppa/regname.c +if ARCH_HPPA # The list of files that go into libunwind: -libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ - $(libunwind_la_SOURCES_local) \ - hppa/getcontext.S hppa/setcontext.S \ - hppa/Lapply_reg_state.c hppa/Lreg_states_iterate.c \ - hppa/Lcreate_addr_space.c hppa/Lget_save_loc.c hppa/Lglobal.c \ - hppa/Linit.c hppa/Linit_local.c hppa/Linit_remote.c \ - hppa/Lis_signal_frame.c hppa/Lget_proc_info.c hppa/Lregs.c \ - hppa/Lresume.c hppa/Lstep.c +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_local) \ + hppa/getcontext.S \ + hppa/Lapply_reg_state.c \ + hppa/Lcreate_addr_space.c \ + hppa/Lget_proc_info.c \ + hppa/Lget_save_loc.c \ + hppa/Lglobal.c \ + hppa/Linit.c \ + hppa/Linit_local.c \ + hppa/Linit_remote.c \ + hppa/Lis_signal_frame.c \ + hppa/Lregs.c \ + hppa/Lreg_states_iterate.c \ + hppa/Lresume.c \ + hppa/Lstep.c \ + hppa/setcontext.S + +libunwind_setjmp_la_SOURCES += hppa/siglongjmp.S +endif # ARCH_HPPA # The list of files that go into libunwind-hppa: -libunwind_hppa_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ - $(libunwind_la_SOURCES_generic) \ - hppa/Gapply_reg_state.c hppa/Greg_states_iterate.c \ - hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \ - hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \ - hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \ - hppa/Gresume.c hppa/Gstep.c - -# The list of files that go info libunwind and libunwind-mips: -noinst_HEADERS += mips/init.h mips/offsets.h mips/unwind_i.h -libunwind_la_SOURCES_mips_common = $(libunwind_la_SOURCES_common) \ - mips/is_fpreg.c mips/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ - $(libunwind_la_SOURCES_local) \ - mips/getcontext.S \ - mips/Lapply_reg_state.c mips/Lreg_states_iterate.c \ - mips/Lcreate_addr_space.c mips/Lget_proc_info.c mips/Lget_save_loc.c \ - mips/Lglobal.c mips/Linit.c mips/Linit_local.c mips/Linit_remote.c \ - mips/Lis_signal_frame.c mips/Lregs.c mips/Lresume.c mips/Lstep.c - -libunwind_mips_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ - $(libunwind_la_SOURCES_generic) \ - mips/Gapply_reg_state.c mips/Greg_states_iterate.c \ - mips/Gcreate_addr_space.c mips/Gget_proc_info.c mips/Gget_save_loc.c \ - mips/Gglobal.c mips/Ginit.c mips/Ginit_local.c mips/Ginit_remote.c \ - mips/Gis_signal_frame.c mips/Gregs.c mips/Gresume.c mips/Gstep.c - -# The list of files that go info libunwind and libunwind-tilegx: -noinst_HEADERS += tilegx/init.h tilegx/offsets.h tilegx/unwind_i.h -libunwind_la_SOURCES_tilegx_common = $(libunwind_la_SOURCES_common) \ - tilegx/is_fpreg.c tilegx/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ - $(libunwind_la_SOURCES_local) \ - tilegx/getcontext.S \ - tilegx/Lapply_reg_state.c tilegx/Lreg_states_iterate.c \ - tilegx/Lcreate_addr_space.c tilegx/Lget_proc_info.c tilegx/Lget_save_loc.c \ - tilegx/Lglobal.c tilegx/Linit.c tilegx/Linit_local.c tilegx/Linit_remote.c \ - tilegx/Lis_signal_frame.c tilegx/Lregs.c tilegx/Lresume.c tilegx/Lstep.c - -libunwind_tilegx_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ - $(libunwind_la_SOURCES_generic) \ - tilegx/Gapply_reg_state.c tilegx/Greg_states_iterate.c \ - tilegx/Gcreate_addr_space.c tilegx/Gget_proc_info.c tilegx/Gget_save_loc.c \ - tilegx/Gglobal.c tilegx/Ginit.c tilegx/Ginit_local.c tilegx/Ginit_remote.c \ - tilegx/Gis_signal_frame.c tilegx/Gregs.c tilegx/Gresume.c tilegx/Gstep.c +libunwind_hppa_la_SOURCES = \ + $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_generic) \ + hppa/Gapply_reg_state.c \ + hppa/Gcreate_addr_space.c \ + hppa/Gget_proc_info.c \ + hppa/Gget_save_loc.c \ + hppa/Gglobal.c \ + hppa/Ginit.c \ + hppa/Ginit_local.c \ + hppa/Ginit_remote.c \ + hppa/Gis_signal_frame.c \ + hppa/Gregs.c \ + hppa/Greg_states_iterate.c \ + hppa/Gresume.c \ + hppa/Gstep.c +libunwind_hppa_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_hppa_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf32.la \ + $(libunwind_libadd) + +### target IA-64: +# The list of files that go both into libunwind and libunwind-ia64: +noinst_HEADERS += \ + ia64/init.h \ + ia64/offsets.h \ + ia64/regs.h \ + ia64/ucontext_i.h \ + ia64/unwind_decoder.h \ + ia64/unwind_i.h +libunwind_la_SOURCES_ia64_common = \ + $(libunwind_la_SOURCES_common) \ + ia64/regname.c +libunwind_la_EXTRAS_ia64 = \ + ia64/mk_cursor_i \ + ia64/mk_Gcursor_i.c \ + ia64/mk_Lcursor_i.c -# The list of files that go info libunwind and libunwind-riscv: -noinst_HEADERS += riscv/init.h riscv/offsets.h riscv/unwind_i.h riscv/asm.h -libunwind_la_SOURCES_riscv_common = $(libunwind_la_SOURCES_common) \ - riscv/is_fpreg.c riscv/regname.c +if ARCH_IA64 +BUILT_SOURCES = Gcursor_i.h Lcursor_i.h +mk_Gcursor_i.s: $(srcdir)/ia64/mk_Gcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Gcursor_i.c" -o mk_Gcursor_i.s +mk_Lcursor_i.s: $(srcdir)/ia64/mk_Lcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Lcursor_i.c" -o mk_Lcursor_i.s +Gcursor_i.h: mk_Gcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Gcursor_i.s > Gcursor_i.h +Lcursor_i.h: mk_Lcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Lcursor_i.s > Lcursor_i.h # The list of files that go into libunwind: -libunwind_la_SOURCES_riscv = $(libunwind_la_SOURCES_riscv_common) \ - $(libunwind_la_SOURCES_local) \ - riscv/getcontext.S riscv/setcontext.S \ - riscv/Lapply_reg_state.c riscv/Lreg_states_iterate.c \ - riscv/Lcreate_addr_space.c riscv/Lget_proc_info.c riscv/Lget_save_loc.c \ - riscv/Lglobal.c riscv/Linit.c riscv/Linit_local.c riscv/Linit_remote.c \ - riscv/Lis_signal_frame.c riscv/Lregs.c riscv/Lresume.c riscv/Lstep.c - -libunwind_riscv_la_SOURCES_riscv = $(libunwind_la_SOURCES_riscv_common) \ - $(libunwind_la_SOURCES_generic) \ - riscv/Gapply_reg_state.c riscv/Greg_states_iterate.c \ - riscv/Gcreate_addr_space.c riscv/Gget_proc_info.c riscv/Gget_save_loc.c \ - riscv/Gglobal.c riscv/Ginit.c riscv/Ginit_local.c riscv/Ginit_remote.c \ - riscv/Gis_signal_frame.c riscv/Gregs.c riscv/Gresume.c riscv/Gstep.c +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_local) \ + ia64/dyn_info_list.S \ + ia64/getcontext.S \ + ia64/Lapply_reg_state.c \ + ia64/Lcreate_addr_space.c \ + ia64/Lfind_unwind_table.c \ + ia64/Lget_proc_info.c \ + ia64/Lget_save_loc.c \ + ia64/Lglobal.c \ + ia64/Linit.c \ + ia64/Linit_local.c \ + ia64/Linit_remote.c \ + ia64/Linstall_cursor.S \ + ia64/Lis_signal_frame.c \ + ia64/Lparser.c \ + ia64/Lrbs.c \ + ia64/Lregs.c \ + ia64/Lreg_states_iterate.c \ + ia64/Lresume.c \ + ia64/Lscript.c \ + ia64/Lstep.c \ + ia64/Ltables.c + +libunwind_setjmp_la_SOURCES += \ + ia64/longjmp.S \ + ia64/setjmp.S \ + ia64/siglongjmp.S \ + ia64/sigsetjmp.S +endif # ARCH_IA64 +# The list of files that go into libunwind-ia64: +libunwind_ia64_la_SOURCES = \ + $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_generic) \ + ia64/Gapply_reg_state.c \ + ia64/Gcreate_addr_space.c \ + ia64/Gfind_unwind_table.c \ + ia64/Gget_proc_info.c \ + ia64/Gget_save_loc.c \ + ia64/Gglobal.c \ + ia64/Ginit.c \ + ia64/Ginit_local.c \ + ia64/Ginit_remote.c \ + ia64/Ginstall_cursor.S \ + ia64/Gis_signal_frame.c \ + ia64/Gparser.c \ + ia64/Grbs.c \ + ia64/Gregs.c \ + ia64/Greg_states_iterate.c \ + ia64/Gresume.c \ + ia64/Gscript.c \ + ia64/Gstep.c \ + ia64/Gtables.c +libunwind_ia64_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_ia64_la_LIBADD = \ + libunwind-elf64.la \ + $(libunwind_libadd) + +### target LoongArch64: # The list of files that go info libunwind and libunwind-loongarch64: -noinst_HEADERS += loongarch64/init.h loongarch64/offsets.h loongarch64/unwind_i.h -libunwind_la_SOURCES_loongarch64_common = $(libunwind_la_SOURCES_common) \ - loongarch64/is_fpreg.c loongarch64/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_loongarch64 = $(libunwind_la_SOURCES_loongarch64_common) \ - $(libunwind_la_SOURCES_local) \ - loongarch64/getcontext.S \ - loongarch64/Lapply_reg_state.c loongarch64/Lreg_states_iterate.c \ - loongarch64/Lcreate_addr_space.c loongarch64/Lget_proc_info.c \ - loongarch64/Lget_save_loc.c loongarch64/Lglobal.c loongarch64/Linit.c \ - loongarch64/Linit_local.c loongarch64/Linit_remote.c \ - loongarch64/Lis_signal_frame.c loongarch64/Lregs.c \ - loongarch64/Lresume.c loongarch64/Lstep.c - -libunwind_loongarch64_la_SOURCES_loongarch64 = $(libunwind_la_SOURCES_loongarch64_common) \ - $(libunwind_la_SOURCES_generic) \ - loongarch64/Gapply_reg_state.c loongarch64/Greg_states_iterate.c \ - loongarch64/Gcreate_addr_space.c loongarch64/Gget_proc_info.c \ - loongarch64/Gget_save_loc.c loongarch64/Gglobal.c loongarch64/Ginit.c \ - loongarch64/Ginit_local.c loongarch64/Ginit_remote.c \ - loongarch64/Gis_signal_frame.c loongarch64/Gregs.c \ - loongarch64/Gresume.c loongarch64/Gstep.c - -# The list of files that go both into libunwind and libunwind-x86: -noinst_HEADERS += x86/init.h x86/offsets.h x86/unwind_i.h -libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \ - x86/is_fpreg.c x86/regname.c +noinst_HEADERS += \ + loongarch64/init.h \ + loongarch64/offsets.h \ + loongarch64/unwind_i.h +libunwind_la_SOURCES_loongarch64_common = \ + $(libunwind_la_SOURCES_common) \ + loongarch64/is_fpreg.c \ + loongarch64/regname.c +if ARCH_LOONGARCH64 # The list of files that go into libunwind: -libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ - $(libunwind_la_SOURCES_x86_os_local) \ - $(libunwind_la_SOURCES_local) \ - x86/Lapply_reg_state.c x86/Lreg_states_iterate.c \ - x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \ - x86/Linit.c x86/Linit_local.c x86/Linit_remote.c \ - x86/Lget_proc_info.c x86/Lregs.c \ - x86/Lresume.c x86/Lstep.c - -# The list of files that go into libunwind-x86: -libunwind_x86_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ - $(libunwind_la_SOURCES_x86_os) \ - $(libunwind_la_SOURCES_generic) \ - x86/Gapply_reg_state.c x86/Greg_states_iterate.c \ - x86/Gcreate_addr_space.c x86/Gget_save_loc.c x86/Gglobal.c \ - x86/Ginit.c x86/Ginit_local.c x86/Ginit_remote.c \ - x86/Gget_proc_info.c x86/Gregs.c \ - x86/Gresume.c x86/Gstep.c +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_loongarch64_common) \ + $(libunwind_la_SOURCES_local) \ + loongarch64/getcontext.S \ + loongarch64/Lapply_reg_state.c \ + loongarch64/Lcreate_addr_space.c \ + loongarch64/Lget_proc_info.c \ + loongarch64/Lget_save_loc.c \ + loongarch64/Lglobal.c \ + loongarch64/Linit.c \ + loongarch64/Linit_local.c \ + loongarch64/Linit_remote.c \ + loongarch64/Lis_signal_frame.c \ + loongarch64/Lregs.c \ + loongarch64/Lreg_states_iterate.c \ + loongarch64/Lresume.c \ + loongarch64/Lstep.c + +libunwind_setjmp_la_SOURCES += \ + loongarch64/siglongjmp.S +endif # ARCH_LOONGARCH64 -# The list of files that go both into libunwind and libunwind-x86_64: -noinst_HEADERS += x86_64/offsets.h \ - x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h -libunwind_la_SOURCES_x86_64_common = $(libunwind_la_SOURCES_common) \ - x86_64/is_fpreg.c x86_64/regname.c +libunwind_loongarch64_la_SOURCES = \ + $(libunwind_la_SOURCES_loongarch64_common) \ + $(libunwind_la_SOURCES_generic) \ + loongarch64/Gapply_reg_state.c \ + loongarch64/Gcreate_addr_space.c \ + loongarch64/Gget_proc_info.c \ + loongarch64/Gget_save_loc.c \ + loongarch64/Gglobal.c \ + loongarch64/Ginit.c \ + loongarch64/Ginit_local.c \ + loongarch64/Ginit_remote.c \ + loongarch64/Gis_signal_frame.c \ + loongarch64/Gregs.c \ + loongarch64/Greg_states_iterate.c \ + loongarch64/Gresume.c \ + loongarch64/Gstep.c +libunwind_loongarch64_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_loongarch64_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf64.la \ + $(libunwind_libadd) + +### target MIPS: +# The list of files that go info libunwind and libunwind-mips: +noinst_HEADERS += \ + mips/init.h \ + mips/offsets.h \ + mips/unwind_i.h +libunwind_la_SOURCES_mips_common = \ + $(libunwind_la_SOURCES_common) \ + mips/is_fpreg.c \ + mips/regname.c +if ARCH_MIPS # The list of files that go into libunwind: -libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ - $(libunwind_la_SOURCES_x86_64_os_local) \ - $(libunwind_la_SOURCES_local) \ - x86_64/setcontext.S \ - x86_64/Lapply_reg_state.c x86_64/Lreg_states_iterate.c \ - x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \ - x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \ - x86_64/Lget_proc_info.c x86_64/Lregs.c x86_64/Lresume.c \ - x86_64/Lstash_frame.c x86_64/Lstep.c x86_64/Ltrace.c x86_64/getcontext.S - -# The list of files that go into libunwind-x86_64: -libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ - $(libunwind_la_SOURCES_x86_64_os) \ - $(libunwind_la_SOURCES_generic) \ - x86_64/Gapply_reg_state.c x86_64/Greg_states_iterate.c \ - x86_64/Gcreate_addr_space.c x86_64/Gget_save_loc.c x86_64/Gglobal.c \ - x86_64/Ginit.c x86_64/Ginit_local.c x86_64/Ginit_remote.c \ - x86_64/Gget_proc_info.c x86_64/Gregs.c x86_64/Gresume.c \ - x86_64/Gstash_frame.c x86_64/Gstep.c x86_64/Gtrace.c +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_local) \ + mips/getcontext.S \ + mips/Lapply_reg_state.c \ + mips/Lcreate_addr_space.c \ + mips/Lget_proc_info.c \ + mips/Lget_save_loc.c \ + mips/Lglobal.c \ + mips/Linit.c \ + mips/Linit_local.c \ + mips/Linit_remote.c \ + mips/Lis_signal_frame.c \ + mips/Lregs.c \ + mips/Lreg_states_iterate.c \ + mips/Lresume.c \ + mips/Lstep.c + +libunwind_setjmp_la_SOURCES += mips/siglongjmp.S +endif # ARCH_MIPS +libunwind_mips_la_SOURCES = \ + $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_generic) \ + mips/Gapply_reg_state.c \ + mips/Gcreate_addr_space.c \ + mips/Gget_proc_info.c \ + mips/Gget_save_loc.c \ + mips/Gglobal.c \ + mips/Ginit.c \ + mips/Ginit_local.c \ + mips/Ginit_remote.c \ + mips/Gis_signal_frame.c \ + mips/Gregs.c \ + mips/Greg_states_iterate.c \ + mips/Gresume.c \ + mips/Gstep.c +libunwind_mips_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_mips_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elfxx.la \ + $(libunwind_libadd) + +### target PowerPC: # The list of local files that go to Power 64 and 32: -libunwind_la_SOURCES_ppc = \ - ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \ - ppc/Linit_remote.c ppc/Lis_signal_frame.c +libunwind_la_SOURCES_ppc = \ + ppc/Lget_proc_info.c \ + ppc/Lget_save_loc.c \ + ppc/Linit_local.c \ + ppc/Linit_remote.c \ + ppc/Lis_signal_frame.c # The list of generic files that go to Power 64 and 32: -libunwind_ppc_la_SOURCES_ppc_generic = \ - ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \ - ppc/Ginit_remote.c ppc/Gis_signal_frame.c +libunwind_ppc_la_SOURCES_ppc_generic = \ + ppc/Gget_proc_info.c \ + ppc/Gget_save_loc.c \ + ppc/Ginit_local.c \ + ppc/Ginit_remote.c \ + ppc/Gis_signal_frame.c + # The list of files that go both into libunwind and libunwind-ppc32: -noinst_HEADERS += ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h -libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \ - ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c +noinst_HEADERS += \ + ppc32/init.h \ + ppc32/unwind_i.h \ + ppc32/ucontext_i.h +libunwind_la_SOURCES_ppc32_common = \ + $(libunwind_la_SOURCES_common) \ + ppc32/get_func_addr.c \ + ppc32/is_fpreg.c \ + ppc32/regname.c +if ARCH_PPC32 # The list of files that go into libunwind: -libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ - $(libunwind_la_SOURCES_local) \ - $(libunwind_la_SOURCES_ppc) \ - ppc32/Lapply_reg_state.c ppc32/Lreg_states_iterate.c \ - ppc32/Lcreate_addr_space.c \ - ppc32/Lglobal.c ppc32/Linit.c \ - ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc32/Lapply_reg_state.c \ + ppc32/Lcreate_addr_space.c \ + ppc32/Lglobal.c \ + ppc32/Linit.c \ + ppc32/Lregs.c \ + ppc32/Lreg_states_iterate.c \ + ppc32/Lresume.c \ + ppc32/Lstep.c + +libunwind_setjmp_la_SOURCES += \ + ppc/longjmp.S \ + ppc/siglongjmp.S +endif # ARCH_PPC32 # The list of files that go into libunwind-ppc32: -libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ - $(libunwind_la_SOURCES_generic) \ - $(libunwind_ppc_la_SOURCES_ppc_generic) \ - ppc32/Gapply_reg_state.c ppc32/Greg_states_iterate.c \ - ppc32/Gcreate_addr_space.c \ - ppc32/Gglobal.c ppc32/Ginit.c \ - ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c +libunwind_ppc32_la_SOURCES = \ + $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic)\ + ppc32/Gapply_reg_state.c \ + ppc32/Gcreate_addr_space.c \ + ppc32/Gglobal.c \ + ppc32/Ginit.c \ + ppc32/Gregs.c \ + ppc32/Greg_states_iterate.c \ + ppc32/Gresume.c \ + ppc32/Gstep.c +libunwind_ppc32_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_ppc32_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf32.la \ + $(libunwind_libadd) # The list of files that go both into libunwind and libunwind-ppc64: -noinst_HEADERS += ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h -libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ - ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c +noinst_HEADERS += \ + ppc64/init.h \ + ppc64/unwind_i.h \ + ppc64/ucontext_i.h +libunwind_la_SOURCES_ppc64_common = \ + $(libunwind_la_SOURCES_common) \ + ppc64/get_func_addr.c \ + ppc64/is_fpreg.c \ + ppc64/regname.c +if ARCH_PPC64 # The list of files that go into libunwind: -libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ - $(libunwind_la_SOURCES_local) \ - $(libunwind_la_SOURCES_ppc) \ - ppc64/Lapply_reg_state.c ppc64/Lreg_states_iterate.c \ - ppc64/Lcreate_addr_space.c \ - ppc64/Lglobal.c ppc64/Linit.c \ - ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc64/Lapply_reg_state.c \ + ppc64/Lcreate_addr_space.c \ + ppc64/Lglobal.c \ + ppc64/Linit.c \ + ppc64/Lregs.c \ + ppc64/Lreg_states_iterate.c \ + ppc64/Lresume.c \ + ppc64/Lstep.c +libunwind_setjmp_la_SOURCES += \ + ppc/longjmp.S \ + ppc/siglongjmp.S +endif # ARCH_PPC64 # The list of files that go into libunwind-ppc64: -libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ - $(libunwind_la_SOURCES_generic) \ - $(libunwind_ppc_la_SOURCES_ppc_generic) \ - ppc64/Gapply_reg_state.c ppc64/Greg_states_iterate.c \ - ppc64/Gcreate_addr_space.c \ - ppc64/Gglobal.c ppc64/Ginit.c \ - ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c - -# The list of files that go into libunwind and libunwind-sh: -noinst_HEADERS += sh/init.h sh/offsets.h sh/unwind_i.h -libunwind_la_SOURCES_sh_common = $(libunwind_la_SOURCES_common) \ - sh/is_fpreg.c sh/regname.c +libunwind_ppc64_la_SOURCES = \ + $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic)\ + ppc64/Gapply_reg_state.c \ + ppc64/Gcreate_addr_space.c \ + ppc64/Gglobal.c \ + ppc64/Ginit.c \ + ppc64/Gregs.c \ + ppc64/Greg_states_iterate.c \ + ppc64/Gresume.c \ + ppc64/Gstep.c +libunwind_ppc64_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_ppc64_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf64.la \ + $(libunwind_libadd) + +### target RISC-V: +# The list of files that go info libunwind and libunwind-riscv: +noinst_HEADERS += \ + riscv/asm.h \ + riscv/init.h \ + riscv/offsets.h \ + riscv/unwind_i.h +libunwind_la_SOURCES_riscv_common = \ + $(libunwind_la_SOURCES_common) \ + riscv/is_fpreg.c \ + riscv/regname.c +if ARCH_RISCV # The list of files that go into libunwind: -libunwind_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ - $(libunwind_la_SOURCES_local) \ - sh/Lapply_reg_state.c sh/Lreg_states_iterate.c \ - sh/Lcreate_addr_space.c sh/Lget_proc_info.c sh/Lget_save_loc.c \ - sh/Lglobal.c sh/Linit.c sh/Linit_local.c sh/Linit_remote.c \ - sh/Lis_signal_frame.c sh/Lregs.c sh/Lresume.c sh/Lstep.c - -libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ - $(libunwind_la_SOURCES_generic) \ - sh/Gapply_reg_state.c sh/Greg_states_iterate.c \ - sh/Gcreate_addr_space.c sh/Gget_proc_info.c sh/Gget_save_loc.c \ - 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 +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_riscv_common) \ + $(libunwind_la_SOURCES_local) \ + riscv/getcontext.S \ + riscv/Lapply_reg_state.c \ + riscv/Lcreate_addr_space.c \ + riscv/Lget_proc_info.c \ + riscv/Lget_save_loc.c \ + riscv/Lglobal.c \ + riscv/Linit.c \ + riscv/Linit_local.c \ + riscv/Linit_remote.c \ + riscv/Lis_signal_frame.c \ + riscv/Lregs.c \ + riscv/Lreg_states_iterate.c \ + riscv/Lresume.c \ + riscv/Lstep.c \ + riscv/setcontext.S + +libunwind_setjmp_la_SOURCES += \ + riscv/siglongjmp.S +endif # ARCH_RISCV +libunwind_riscv_la_SOURCES = \ + $(libunwind_la_SOURCES_riscv_common) \ + $(libunwind_la_SOURCES_generic) \ + riscv/Gapply_reg_state.c \ + riscv/Gcreate_addr_space.c \ + riscv/Gget_proc_info.c \ + riscv/Gget_save_loc.c \ + riscv/Gglobal.c \ + riscv/Ginit.c \ + riscv/Ginit_local.c \ + riscv/Ginit_remote.c \ + riscv/Gis_signal_frame.c \ + riscv/Gregs.c \ + riscv/Greg_states_iterate.c \ + riscv/Gresume.c \ + riscv/Gstep.c + +libunwind_riscv_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_riscv_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf64.la \ + $(libunwind_libadd) + +### target s390x: # 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 +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 +if ARCH_S390X # 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 +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_s390x_common) \ + $(libunwind_la_SOURCES_local) \ + s390x/getcontext.S \ + s390x/Lapply_reg_state.c \ + s390x/Lcreate_addr_space.c \ + s390x/Lget_proc_info.c \ + s390x/Lget_save_loc.c \ + s390x/Lglobal.c \ + s390x/Linit.c \ + s390x/Linit_local.c \ + s390x/Linit_remote.c \ + s390x/Lis_signal_frame.c \ + s390x/Lregs.c \ + s390x/Lreg_states_iterate.c \ + s390x/Lresume.c \ + s390x/Lstep.c \ + s390x/setcontext.S +endif # ARCH_S390X # 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 +libunwind_s390x_la_SOURCES = \ + $(libunwind_la_SOURCES_s390x_common) \ + $(libunwind_la_SOURCES_generic) \ + s390x/Gapply_reg_state.c \ + s390x/Gcreate_addr_space.c \ + s390x/Gget_proc_info.c \ + s390x/Gget_save_loc.c \ + s390x/Gglobal.c \ + s390x/Ginit.c \ + s390x/Ginit_local.c \ + s390x/Ginit_remote.c \ + s390x/Gis_signal_frame.c \ + s390x/Gregs.c \ + s390x/Greg_states_iterate.c \ + s390x/Gresume.c \ + s390x/Gstep.c +libunwind_s390x_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_s390x_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf64.la \ + $(libunwind_libadd) + +### target Sh: +# The list of files that go into libunwind and libunwind-sh: +noinst_HEADERS += \ + sh/init.h \ + sh/offsets.h \ + sh/unwind_i.h +libunwind_la_SOURCES_sh_common = \ + $(libunwind_la_SOURCES_common) \ + sh/is_fpreg.c \ + sh/regname.c + +if ARCH_SH +# The list of files that go into libunwind: +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_local) \ + sh/Lapply_reg_state.c \ + sh/Lcreate_addr_space.c \ + sh/Lget_proc_info.c \ + sh/Lget_save_loc.c \ + sh/Lglobal.c \ + sh/Linit.c \ + sh/Linit_local.c \ + sh/Linit_remote.c \ + sh/Lis_signal_frame.c \ + sh/Lregs.c \ + sh/Lreg_states_iterate.c \ + sh/Lresume.c \ + sh/Lstep.c +libunwind_setjmp_la_SOURCES += sh/siglongjmp.S +endif # ARCH_SH + +libunwind_sh_la_SOURCES = \ + $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_generic) \ + sh/Gapply_reg_state.c \ + sh/Gcreate_addr_space.c \ + sh/Gget_proc_info.c \ + sh/Gget_save_loc.c \ + sh/Gglobal.c \ + sh/Ginit.c \ + sh/Ginit_local.c \ + sh/Ginit_remote.c \ + sh/Gis_signal_frame.c \ + sh/Gregs.c \ + sh/Greg_states_iterate.c \ + sh/Gresume.c \ + sh/Gstep.c +libunwind_sh_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_sh_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf32.la \ + $(libunwind_libadd) + +### target x86: +# The list of files that go both into libunwind and libunwind-x86: +noinst_HEADERS += \ + x86/init.h \ + x86/offsets.h \ + x86/unwind_i.h +libunwind_la_SOURCES_x86_common = \ + $(libunwind_la_SOURCES_common) \ + x86/is_fpreg.c \ + x86/regname.c + +if ARCH_X86 +# The list of files that go into libunwind: +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os_local) \ + $(libunwind_la_SOURCES_local) \ + x86/Lapply_reg_state.c \ + x86/Lcreate_addr_space.c \ + x86/Lget_proc_info.c \ + x86/Lget_save_loc.c \ + x86/Lglobal.c \ + x86/Linit.c \ + x86/Linit_local.c \ + x86/Linit_remote.c \ + x86/Lregs.c \ + x86/Lreg_states_iterate.c \ + x86/Lresume.c \ + x86/Lstep.c + +libunwind_setjmp_la_SOURCES += \ + x86/longjmp.S \ + x86/siglongjmp.S +endif # ARCH_X86 + +# The list of files that go into libunwind-x86: +libunwind_x86_la_SOURCES = \ + $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os) \ + $(libunwind_la_SOURCES_generic) \ + x86/Gapply_reg_state.c \ + x86/Gcreate_addr_space.c \ + x86/Gget_proc_info.c \ + x86/Gget_save_loc.c \ + x86/Gglobal.c \ + x86/Ginit.c \ + x86/Ginit_local.c \ + x86/Ginit_remote.c \ + x86/Gregs.c \ + x86/Greg_states_iterate.c \ + x86/Gresume.c \ + x86/Gstep.c +libunwind_x86_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_x86_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf32.la \ + $(libunwind_libadd) + +### target x86_64: +# The list of files that go both into libunwind and libunwind-x86_64: +noinst_HEADERS += \ + x86_64/init.h \ + x86_64/ucontext_i.h \ + x86_64/unwind_i.h +libunwind_la_SOURCES_x86_64_common = \ + $(libunwind_la_SOURCES_common) \ + x86_64/is_fpreg.c \ + x86_64/regname.c + +if ARCH_X86_64 +# The list of files that go into libunwind: +libunwind_la_SOURCES = \ + $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os_local)\ + $(libunwind_la_SOURCES_local) \ + x86_64/getcontext.S \ + x86_64/Lapply_reg_state.c \ + x86_64/Lcreate_addr_space.c \ + x86_64/Lget_proc_info.c \ + x86_64/Lget_save_loc.c \ + x86_64/Lglobal.c \ + x86_64/Linit.c \ + x86_64/Linit_local.c \ + x86_64/Linit_remote.c \ + x86_64/Lregs.c \ + x86_64/Lreg_states_iterate.c \ + x86_64/Lresume.c \ + x86_64/Lstash_frame.c \ + x86_64/Lstep.c \ + x86_64/Ltrace.c \ + x86_64/setcontext.S + +libunwind_setjmp_la_SOURCES += \ + x86_64/longjmp.S \ + x86_64/siglongjmp.S +endif # ARCH_X86_64 + +# The list of files that go into libunwind-x86_64: +libunwind_x86_64_la_SOURCES = \ + $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os) \ + $(libunwind_la_SOURCES_generic) \ + x86_64/Gapply_reg_state.c \ + x86_64/Gcreate_addr_space.c \ + x86_64/Gget_proc_info.c \ + x86_64/Gget_save_loc.c \ + x86_64/Gglobal.c \ + x86_64/Ginit.c \ + x86_64/Ginit_local.c \ + x86_64/Ginit_remote.c \ + x86_64/Gregs.c \ + x86_64/Greg_states_iterate.c \ + x86_64/Gresume.c \ + x86_64/Gstash_frame.c \ + x86_64/Gstep.c \ + x86_64/Gtrace.c +libunwind_x86_64_la_LDFLAGS = \ + $(COMMON_SO_LDFLAGS) \ + -version-info $(SOVERSION) +libunwind_x86_64_la_LIBADD = \ + libunwind-dwarf-generic.la \ + libunwind-elf64.la \ + $(libunwind_libadd) if REMOTE_ONLY install-exec-hook: @@ -562,252 +1235,6 @@ install-exec-hook: fi endif -if OS_LINUX - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_linux) - libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_linux_local) - libunwind_la_SOURCES_x86_os = x86/Gos-linux.c - libunwind_x86_la_SOURCES_os = x86/getcontext-linux.S - libunwind_la_SOURCES_x86_os_local = x86/Los-linux.c - libunwind_la_SOURCES_x86_64_os = x86_64/Gos-linux.c - libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c - libunwind_la_SOURCES_arm_os = arm/Gos-linux.c - libunwind_la_SOURCES_arm_os_local = arm/Los-linux.c - libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_linux.c - libunwind_coredump_la_SOURCES += coredump/_UCD_get_threadinfo_prstatus.c - libunwind_coredump_la_SOURCES += coredump/_UCD_get_mapinfo_linux.c -endif - -if OS_HPUX - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_hpux) - libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_hpux_local) -endif - -if OS_FREEBSD - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_freebsd) - libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_freebsd_local) - libunwind_la_SOURCES_x86_os = x86/Gos-freebsd.c - libunwind_x86_la_SOURCES_os = x86/getcontext-freebsd.S - libunwind_la_SOURCES_x86_os_local = x86/Los-freebsd.c - libunwind_la_SOURCES_x86_64_os = x86_64/Gos-freebsd.c - libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-freebsd.c - libunwind_la_SOURCES_arm_os = arm/Gos-freebsd.c - libunwind_la_SOURCES_arm_os_local = arm/Los-freebsd.c - libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c - libunwind_coredump_la_SOURCES += coredump/_UCD_get_threadinfo_prstatus.c - libunwind_coredump_la_SOURCES += coredump/_UCD_get_mapinfo_generic.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) - libunwind_la_SOURCES_arm_os = arm/Gos-other.c - libunwind_la_SOURCES_arm_os_local = arm/Los-other.c -endif - -if ARCH_AARCH64 - lib_LTLIBRARIES += libunwind-aarch64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_aarch64) - libunwind_aarch64_la_SOURCES = $(libunwind_aarch64_la_SOURCES_aarch64) - libunwind_aarch64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_aarch64_la_LIBADD = libunwind-dwarf-generic.la - libunwind_aarch64_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_aarch64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += aarch64/siglongjmp.S -else -if ARCH_ARM - lib_LTLIBRARIES += libunwind-arm.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_arm) - libunwind_arm_la_SOURCES = $(libunwind_arm_la_SOURCES_arm) - libunwind_arm_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_arm_la_LIBADD = libunwind-dwarf-generic.la - libunwind_arm_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_arm_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += arm/siglongjmp.S -else -if ARCH_IA64 - BUILT_SOURCES = Gcursor_i.h Lcursor_i.h -mk_Gcursor_i.s: $(srcdir)/ia64/mk_Gcursor_i.c - $(COMPILE) -S "$(srcdir)/ia64/mk_Gcursor_i.c" -o mk_Gcursor_i.s -mk_Lcursor_i.s: $(srcdir)/ia64/mk_Lcursor_i.c - $(COMPILE) -S "$(srcdir)/ia64/mk_Lcursor_i.c" -o mk_Lcursor_i.s -Gcursor_i.h: mk_Gcursor_i.s - "$(srcdir)/ia64/mk_cursor_i" mk_Gcursor_i.s > Gcursor_i.h -Lcursor_i.h: mk_Lcursor_i.s - "$(srcdir)/ia64/mk_cursor_i" mk_Lcursor_i.s > Lcursor_i.h - - lib_LTLIBRARIES += libunwind-ia64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_ia64) - libunwind_ia64_la_SOURCES = $(libunwind_ia64_la_SOURCES_ia64) - libunwind_ia64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_ia64_la_LIBADD = libunwind-elf64.la -if !REMOTE_ONLY - libunwind_ia64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += ia64/setjmp.S ia64/sigsetjmp.S \ - ia64/longjmp.S ia64/siglongjmp.S -else -if ARCH_HPPA - lib_LTLIBRARIES += libunwind-hppa.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_hppa) - libunwind_hppa_la_SOURCES = $(libunwind_hppa_la_SOURCES_hppa) - libunwind_hppa_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_hppa_la_LIBADD = libunwind-dwarf-generic.la - libunwind_hppa_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_hppa_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += hppa/siglongjmp.S -else -if ARCH_MIPS - lib_LTLIBRARIES += libunwind-mips.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_mips) - libunwind_mips_la_SOURCES = $(libunwind_mips_la_SOURCES_mips) - libunwind_mips_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_mips_la_LIBADD = libunwind-dwarf-generic.la - libunwind_mips_la_LIBADD += libunwind-elfxx.la -if !REMOTE_ONLY - libunwind_mips_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += mips/siglongjmp.S -else -if ARCH_TILEGX - lib_LTLIBRARIES += libunwind-tilegx.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_tilegx) - libunwind_tilegx_la_SOURCES = $(libunwind_tilegx_la_SOURCES_tilegx) - libunwind_tilegx_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_tilegx_la_LIBADD = libunwind-dwarf-generic.la - libunwind_tilegx_la_LIBADD += libunwind-elfxx.la -if !REMOTE_ONLY - libunwind_tilegx_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += tilegx/siglongjmp.S -else -if ARCH_RISCV - lib_LTLIBRARIES += libunwind-riscv.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_riscv) - libunwind_riscv_la_SOURCES = $(libunwind_riscv_la_SOURCES_riscv) - libunwind_riscv_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_riscv_la_LIBADD = libunwind-dwarf-generic.la - libunwind_riscv_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_riscv_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += riscv/siglongjmp.S -else -if ARCH_LOONGARCH64 - lib_LTLIBRARIES += libunwind-loongarch64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_loongarch64) - libunwind_loongarch64_la_SOURCES = $(libunwind_loongarch64_la_SOURCES_loongarch64) - libunwind_loongarch64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_loongarch64_la_LIBADD = libunwind-dwarf-generic.la - libunwind_loongarch64_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_loongarch64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += loongarch64/siglongjmp.S -else -if ARCH_X86 - lib_LTLIBRARIES += libunwind-x86.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86) $(libunwind_x86_la_SOURCES_os) - libunwind_x86_la_SOURCES = $(libunwind_x86_la_SOURCES_x86) - libunwind_x86_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_x86_la_LIBADD = libunwind-dwarf-generic.la - libunwind_x86_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_x86_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += x86/longjmp.S x86/siglongjmp.S -else -if ARCH_X86_64 - lib_LTLIBRARIES += libunwind-x86_64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86_64) - libunwind_x86_64_la_SOURCES = $(libunwind_x86_64_la_SOURCES_x86_64) - libunwind_x86_64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_x86_64_la_LIBADD = libunwind-dwarf-generic.la - libunwind_x86_64_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_x86_64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += x86_64/longjmp.S x86_64/siglongjmp.S -else -if ARCH_PPC32 - lib_LTLIBRARIES += libunwind-ppc32.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32) - libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32) - libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_ppc32_la_LIBADD = libunwind-dwarf-generic.la - libunwind_ppc32_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_ppc32_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S -else -if ARCH_PPC64 - lib_LTLIBRARIES += libunwind-ppc64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64) - libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64) - libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_ppc64_la_LIBADD = libunwind-dwarf-generic.la - libunwind_ppc64_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_ppc64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S -else -if ARCH_SH - lib_LTLIBRARIES += libunwind-sh.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_sh) - libunwind_sh_la_SOURCES = $(libunwind_sh_la_SOURCES_sh) - libunwind_sh_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_sh_la_LIBADD = libunwind-dwarf-generic.la - libunwind_sh_la_LIBADD += libunwind-elf32.la -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 -endif # ARCH_X86_64 -endif # ARCH_X86 -endif # ARCH_LOONGARCH64 -endif # ARCH_RISCV -endif # ARCH_TILEGX -endif # ARCH_MIPS -endif # ARCH_HPPA -endif # ARCH_IA64 -endif # ARCH_ARM -endif # ARCH_AARCH64 - -# libunwind-setjmp depends on libunwind-$(arch). Therefore must be added -# at the end. -if BUILD_SETJMP -lib_LTLIBRARIES += libunwind-setjmp.la -endif - # # Don't link with standard libraries, because those may mention # libunwind already. @@ -821,30 +1248,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. AM_CCASFLAGS = $(AM_CPPFLAGS) noinst_HEADERS += unwind/unwind-internal.h -EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ - $(libunwind_la_SOURCES_arm) \ - $(libunwind_la_SOURCES_hppa) \ - $(libunwind_la_SOURCES_ia64) \ - $(libunwind_la_EXTRAS_ia64) \ - $(libunwind_la_SOURCES_mips) \ - $(libunwind_la_SOURCES_sh) \ - $(libunwind_la_SOURCES_x86) \ - $(libunwind_la_SOURCES_os_freebsd) \ - $(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) \ - $(libunwind_aarch64_la_SOURCES_aarch64) \ - $(libunwind_arm_la_SOURCES_arm) \ - $(libunwind_hppa_la_SOURCES_hppa) \ - $(libunwind_ia64_la_SOURCES_ia64) \ - $(libunwind_mips_la_SOURCES_mips) \ - $(libunwind_sh_la_SOURCES_sh) \ - $(libunwind_x86_la_SOURCES_x86) \ - $(libunwind_x86_64_la_SOURCES_x86_64) +EXTRA_DIST = $(libunwind_la_EXTRAS_ia64) MAINTAINERCLEANFILES = Makefile.in diff --git a/src/native/external/libunwind/src/aarch64/Gglobal.c b/src/native/external/libunwind/src/aarch64/Gglobal.c index 23bececa992cf6..854b54914db8b7 100644 --- a/src/native/external/libunwind/src/aarch64/Gglobal.c +++ b/src/native/external/libunwind/src/aarch64/Gglobal.c @@ -48,8 +48,6 @@ tdep_init (void) dwarf_init (); #ifndef UNW_REMOTE_ONLY - tdep_init_mem_validate (); - aarch64_local_addr_space_init (); #endif atomic_store(&tdep_init_done, 1); /* signal that we're initialized... */ diff --git a/src/native/external/libunwind/src/aarch64/Ginit.c b/src/native/external/libunwind/src/aarch64/Ginit.c index 57f484674f201a..6986dbb61a134a 100644 --- a/src/native/external/libunwind/src/aarch64/Ginit.c +++ b/src/native/external/libunwind/src/aarch64/Ginit.c @@ -2,6 +2,7 @@ Copyright (C) 2008 CodeSourcery Copyright (C) 2012 Tommi Rantala Copyright (C) 2013 Linaro Limited + Copyright 2022 Blackberry Limited This file is part of libunwind. @@ -44,7 +45,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 (unw_context_t *uc, int reg) { if (reg == UNW_AARCH64_VG) { @@ -65,10 +66,21 @@ uc_addr (unw_tdep_context_t *uc, int reg) else if (reg == UNW_AARCH64_PC) return &uc->uc_mcontext.mc_gpregs.gp_elr; else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31) - return &GET_FPCTX(uc)->uc_mcontext.mc_fpregs.fp_q[reg - UNW_AARCH64_V0]; + return &uc->uc_mcontext.mc_fpregs.fp_q[reg - UNW_AARCH64_V0]; else return NULL; -#else /* __FreeBSD__ */ +#elif defined(__QNX__) + if (reg >= UNW_AARCH64_X0 && reg <= UNW_AARCH64_X30) + return &uc->uc_mcontext.cpu.gpr[reg]; + else if (reg == UNW_AARCH64_SP) + return &AARCH64_GET_REGSP(&uc->uc_mcontext.cpu); + else if (reg == UNW_AARCH64_PC) + return &AARCH64_GET_REGIP(&uc->uc_mcontext.cpu); + else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31) + return &uc->uc_mcontext.fpu.reg[reg - UNW_AARCH64_V0]; + else + return NULL; +# else /* !__FreeBSD && ! __QNX__ */ if (reg >= UNW_AARCH64_X0 && reg <= UNW_AARCH64_X30) return &uc->uc_mcontext.regs[reg]; else if (reg == UNW_AARCH64_SP) @@ -85,7 +97,7 @@ 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 (unw_context_t *uc, int reg) { return uc_addr (uc, reg); } @@ -113,234 +125,6 @@ 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]); - - do_pipe2 (mem_validate_pipe); -} - -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 - { - ret = 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 */ - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ - if (mincore (addr, len, (unsigned char *)mvec) != 0) - { - return -1; - } - - return write_validate (addr); -} -#endif - -/* Initialise memory validation method. On linux kernels <2.6.21, - mincore() returns incorrect value for MAP_PRIVATE mappings, - such as stacks. If mincore() was available at compile time, - check if we can actually use it. If not, use msync() instead. */ -HIDDEN void -tdep_init_mem_validate (void) -{ - open_pipe (); - -#ifdef HAVE_MINCORE - unsigned char present = 1; - size_t len = unw_page_size; - unw_word_t addr = uwn_page_start((unw_word_t)&present); - unsigned char mvec[1]; - int ret; - while ((ret = mincore((void *)addr, len, (unsigned char *)mvec)) == -1 && - errno == EAGAIN) - { - } - if (ret == 0) - { - Debug(1, "using mincore to validate memory\n"); - mem_validate_func = mincore_validate; - } - else -#endif - { - Debug(1, "using msync to validate memory\n"); - mem_validate_func = msync_validate; - } -} - -/* Cache of already validated addresses */ -#define NLGA 4 -#if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD -// thread-local variant -static _Thread_local unw_word_t last_good_addr[NLGA]; -static _Thread_local int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (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; -} - -#else -// global, thread safe variant -static _Atomic unw_word_t last_good_addr[NLGA]; -static _Atomic int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == atomic_load(&last_good_addr[i])) - return 1; - } - return 0; -} - -static void -cache_valid_mem(unw_word_t addr) -{ - int i, victim; - victim = atomic_load(&lga_victim); - unw_word_t zero = 0; - for (i = 0; i < NLGA; i++) { - if (atomic_compare_exchange_strong(&last_good_addr[victim], &zero, addr)) { - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - atomic_store(&last_good_addr[victim], addr); - victim = (victim + 1) % NLGA; - atomic_store(&lga_victim, victim); -} -#endif - -static int -validate_mem (unw_word_t addr) -{ - size_t len; - - len = unw_page_size; - addr = uwn_page_start(addr); - - if (addr == 0) - return -1; - - if (is_cached_valid_mem(addr)) - return 0; - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - - cache_valid_mem(addr); - - return 0; -} - static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, void *arg) @@ -348,18 +132,18 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, if (unlikely (write)) { Debug (16, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { /* validate address */ const struct cursor *c = (const struct cursor *)arg; if (likely (c != NULL) && unlikely (c->validate) - && unlikely (validate_mem (addr))) { + && unlikely (!unw_address_is_valid (addr, sizeof(unw_word_t)))) { Debug (16, "mem[%016lx] -> invalid\n", addr); return -1; } - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (16, "mem[%lx] -> %lx\n", addr, *val); } return 0; @@ -370,7 +154,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 = ((struct cursor *)arg)->uc; + unw_context_t *uc = ((struct cursor *)arg)->uc; if (unw_is_fpreg (reg)) goto badreg; @@ -380,12 +164,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- %lx\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %lx\n", unw_regname (reg), *val); } return 0; @@ -399,7 +183,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 = ((struct cursor *)arg)->uc; + unw_context_t *uc = ((struct cursor *)arg)->uc; unw_fpreg_t *addr; if (!unw_is_fpreg (reg)) @@ -441,10 +225,21 @@ static unw_word_t empty_ptrauth_mask(unw_addr_space_t addr_space_unused, void *a return 0; } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + return _Uelf64_get_elf_filename(as, getpid(), ip, buf, buf_len, offp); +} + HIDDEN void aarch64_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; @@ -454,6 +249,7 @@ aarch64_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = aarch64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; local_addr_space.acc.ptrauth_insn_mask = empty_ptrauth_mask; local_addr_space.big_endian = target_is_big_endian(); unw_flush_cache (&local_addr_space, 0, 0); diff --git a/src/native/external/libunwind/src/aarch64/Ginit_local.c b/src/native/external/libunwind/src/aarch64/Ginit_local.c index 4a055fb0938ba5..5bd6c8ae81fe9a 100644 --- a/src/native/external/libunwind/src/aarch64/Ginit_local.c +++ b/src/native/external/libunwind/src/aarch64/Ginit_local.c @@ -61,7 +61,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, unw_context_t *uc, int flag) { if (!flag) { diff --git a/src/native/external/libunwind/src/aarch64/Gis_signal_frame.c b/src/native/external/libunwind/src/aarch64/Gis_signal_frame.c index 67159d83961431..ace0e166145182 100644 --- a/src/native/external/libunwind/src/aarch64/Gis_signal_frame.c +++ b/src/native/external/libunwind/src/aarch64/Gis_signal_frame.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2012 Tommi Rantala Copyright (C) 2013 Linaro Limited + Copyright 2022-2023 Blackberry Limited. This file is part of libunwind. @@ -25,16 +26,41 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "unwind_i.h" -/* The restorer stub will always have the form: - - d2801168 movz x8, #0x8b - d4000001 svc #0x0 -*/ +#if defined(__linux__) +/* + * The restorer stub will always have the form: + * + * d2801168 movz x8, #0x8b + * d4000001 svc #0x0 + */ +# define SIGNAL_RETURN 0xd4000001d2801168 +#elif defined(__FreeBSD__) +/* + * The restorer stub will always have the form: + * + * 910003e0 mov x0, sp + * 91014000 add x0, x0, #SF_UC + * d2803428 mov x8, #SYS_sigreturn + * d4000001 svc 0 + */ +# define SIGNAL_RETURN 0x91014000910003e0 +#elif defined(__QNX__) +/* + * The restorer stub will always have the form: + * + * f9400260 ldr x0, [x19] + * d63f0060 blr x3 + * aa1303e0 mov x0, x19 + * 14xxxxxx b SignalReturn@plt + */ +# define SIGNAL_RETURN 0x14000000aa1303e0 +# define HANDLER_CALL 0xd63f0060f9400260 +#endif int unw_is_signal_frame (unw_cursor_t *cursor) { -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__QNX__) struct cursor *c = (struct cursor *) cursor; unw_word_t w0, ip; unw_addr_space_t as; @@ -52,9 +78,29 @@ unw_is_signal_frame (unw_cursor_t *cursor) if (ret < 0) return ret; - /* FIXME: distinguish 32bit insn vs 64bit registers. */ - if (w0 != 0xd4000001d2801168) + if ((w0 & SIGNAL_RETURN) != SIGNAL_RETURN) + return 0; +#if defined(__FreeBSD__) + ip += 8; + /* + */ + ret = (*a->access_mem) (as, ip, &w0, 0, arg); + if (ret < 0) + return ret; + if (w0 != 0xd4000001d2803428) return 0; +#elif defined(__QNX__) + unw_word_t w1 = 0; + ret = (*a->access_mem) (as, ip-sizeof(w1), &w1, 0, arg); + if (ret < 0) + return ret; + + if ((w1 & HANDLER_CALL) != HANDLER_CALL) + { + return 0; + } + +#endif return 1; diff --git a/src/native/external/libunwind/src/tilegx/Ginit_local.c b/src/native/external/libunwind/src/aarch64/Gos-freebsd.c similarity index 50% rename from src/native/external/libunwind/src/tilegx/Ginit_local.c rename to src/native/external/libunwind/src/aarch64/Gos-freebsd.c index 029558675fd99b..f92fe8ee119de9 100644 --- a/src/native/external/libunwind/src/tilegx/Ginit_local.c +++ b/src/native/external/libunwind/src/aarch64/Gos-freebsd.c @@ -1,6 +1,5 @@ /* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. + Copyright (C) 2023 Dmitry Chagin This file is part of libunwind. @@ -23,58 +22,55 @@ 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; +#include - if (!atomic_load(&tdep_init_done)) - tdep_init (); +#include +#include +#include - memset(c, 0, sizeof(unw_cursor_t)); +#include - Debug (1, "(cursor=%p)\n", c); +#include "unwind_i.h" +#include "ucontext_i.h" - c->dwarf.as = unw_local_addr_space; +#ifndef UNW_REMOTE_ONLY - c->dwarf.as_arg = uc; - return common_init (c, use_prev_instr); -} +#define setcontext UNW_ARCH_OBJ(setcontext) +extern NORETURN void setcontext(ucontext_t *); -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +HIDDEN int +aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) { - return unw_init_local_common(cursor, uc, 1); -} + struct cursor *c = (struct cursor *) cursor; -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) + /* + * XXX. Due to incorrectly handled cfi_signal_frame directive + * (it should mark current function, not a frame above) + * temporarily use unw_is_signal_frame to detect signal trampoline. + */ + if (unw_is_signal_frame (cursor)) { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); + ucontext_t *uc = (ucontext_t *)(c->sigcontext_sp + offsetof(struct sigframe, sf_uc)); + + if (c->dwarf.eh_valid_mask & 0x1) + uc->uc_mcontext.mc_gpregs.gp_x[0] = c->dwarf.eh_args[0]; + if (c->dwarf.eh_valid_mask & 0x2) + uc->uc_mcontext.mc_gpregs.gp_x[1] = c->dwarf.eh_args[1]; + if (c->dwarf.eh_valid_mask & 0x4) + uc->uc_mcontext.mc_gpregs.gp_x[2] = c->dwarf.eh_args[2]; + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->sigcontext_pc, uc); + sigreturn(uc); + abort(); } else { - return -UNW_EINVAL; + setcontext(c->uc); } + + unreachable(); + return -UNW_EINVAL; } #endif /* !UNW_REMOTE_ONLY */ diff --git a/src/native/external/libunwind/src/aarch64/Gos-linux.c b/src/native/external/libunwind/src/aarch64/Gos-linux.c new file mode 100644 index 00000000000000..6614314dea3766 --- /dev/null +++ b/src/native/external/libunwind/src/aarch64/Gos-linux.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-2013 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +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" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->uc; + + if (c->sigcontext_format == AARCH64_SCF_NONE) + { + /* Since there are no signals involved here we restore EH and non scratch + registers only. */ + unsigned long regs[24]; + regs[0] = uc->uc_mcontext.regs[0]; + regs[1] = uc->uc_mcontext.regs[1]; + regs[2] = uc->uc_mcontext.regs[2]; + regs[3] = uc->uc_mcontext.regs[3]; + regs[4] = uc->uc_mcontext.regs[19]; + regs[5] = uc->uc_mcontext.regs[20]; + regs[6] = uc->uc_mcontext.regs[21]; + regs[7] = uc->uc_mcontext.regs[22]; + regs[8] = uc->uc_mcontext.regs[23]; + regs[9] = uc->uc_mcontext.regs[24]; + regs[10] = uc->uc_mcontext.regs[25]; + regs[11] = uc->uc_mcontext.regs[26]; + regs[12] = uc->uc_mcontext.regs[27]; + regs[13] = uc->uc_mcontext.regs[28]; + regs[14] = uc->uc_mcontext.regs[29]; /* FP */ + regs[15] = uc->uc_mcontext.regs[30]; /* LR */ + regs[16] = GET_FPCTX(uc)->vregs[8]; + regs[17] = GET_FPCTX(uc)->vregs[9]; + regs[18] = GET_FPCTX(uc)->vregs[10]; + regs[19] = GET_FPCTX(uc)->vregs[11]; + regs[20] = GET_FPCTX(uc)->vregs[12]; + regs[21] = GET_FPCTX(uc)->vregs[13]; + regs[22] = GET_FPCTX(uc)->vregs[14]; + regs[23] = GET_FPCTX(uc)->vregs[15]; + unsigned long sp = uc->uc_mcontext.sp; + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + __asm__ __volatile__ ( + "mov x4, %0\n" + "mov x5, %1\n" + "ldp x0, x1, [x4]\n" + "ldp x2, x3, [x4,16]\n" + "ldp x19, x20, [x4,32]\n" + "ldp x21, x22, [x4,48]\n" + "ldp x23, x24, [x4,64]\n" + "ldp x25, x26, [x4,80]\n" + "ldp x27, x28, [x4,96]\n" + "ldp x29, x30, [x4,112]\n" + "ldp d8, d9, [x4,128]\n" + "ldp d10, d11, [x4,144]\n" + "ldp d12, d13, [x4,160]\n" + "ldp d14, d15, [x4,176]\n" + "mov sp, x5\n" + "ret \n" + : + : "r" (regs), + "r" (sp), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0]; + if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1]; + if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2]; + if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3]; + + sc->regs[4] = uc->uc_mcontext.regs[4]; + sc->regs[5] = uc->uc_mcontext.regs[5]; + sc->regs[6] = uc->uc_mcontext.regs[6]; + sc->regs[7] = uc->uc_mcontext.regs[7]; + sc->regs[8] = uc->uc_mcontext.regs[8]; + sc->regs[9] = uc->uc_mcontext.regs[9]; + sc->regs[10] = uc->uc_mcontext.regs[10]; + sc->regs[11] = uc->uc_mcontext.regs[11]; + sc->regs[12] = uc->uc_mcontext.regs[12]; + sc->regs[13] = uc->uc_mcontext.regs[13]; + sc->regs[14] = uc->uc_mcontext.regs[14]; + sc->regs[15] = uc->uc_mcontext.regs[15]; + sc->regs[16] = uc->uc_mcontext.regs[16]; + sc->regs[17] = uc->uc_mcontext.regs[17]; + sc->regs[18] = uc->uc_mcontext.regs[18]; + sc->regs[19] = uc->uc_mcontext.regs[19]; + sc->regs[20] = uc->uc_mcontext.regs[20]; + sc->regs[21] = uc->uc_mcontext.regs[21]; + sc->regs[22] = uc->uc_mcontext.regs[22]; + sc->regs[23] = uc->uc_mcontext.regs[23]; + sc->regs[24] = uc->uc_mcontext.regs[24]; + sc->regs[25] = uc->uc_mcontext.regs[25]; + sc->regs[26] = uc->uc_mcontext.regs[26]; + sc->regs[27] = uc->uc_mcontext.regs[27]; + sc->regs[28] = uc->uc_mcontext.regs[28]; + sc->regs[29] = uc->uc_mcontext.regs[29]; + sc->regs[30] = uc->uc_mcontext.regs[30]; + sc->sp = uc->uc_mcontext.sp; + sc->pc = uc->uc_mcontext.pc; + sc->pstate = uc->uc_mcontext.pstate; + + __asm__ __volatile__ ( + "mov sp, %0\n" + "ret %1\n" + : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) + ); + } + unreachable(); + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/native/external/libunwind/src/tilegx/is_fpreg.c b/src/native/external/libunwind/src/aarch64/Gos-qnx.c similarity index 83% rename from src/native/external/libunwind/src/tilegx/is_fpreg.c rename to src/native/external/libunwind/src/aarch64/Gos-qnx.c index d6d58969018882..756d346bed1cc5 100644 --- a/src/native/external/libunwind/src/tilegx/is_fpreg.c +++ b/src/native/external/libunwind/src/aarch64/Gos-qnx.c @@ -1,5 +1,4 @@ /* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery This file is part of libunwind. @@ -22,12 +21,15 @@ 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" +#include "unwind_i.h" -/* TILEGX has no FP. */ +#ifndef UNW_REMOTE_ONLY -int -unw_is_fpreg (int regnum) +HIDDEN int +aarch64_local_resume (unw_addr_space_t as UNUSED, unw_cursor_t *cursor UNUSED, + void *arg UNUSED) { - return 0; + return -UNW_EINVAL; } + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/native/external/libunwind/src/aarch64/Gresume.c b/src/native/external/libunwind/src/aarch64/Gresume.c index 445bac70f0dd4a..bad2f60c7327a3 100644 --- a/src/native/external/libunwind/src/aarch64/Gresume.c +++ b/src/native/external/libunwind/src/aarch64/Gresume.c @@ -25,129 +25,6 @@ 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 "offsets.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_tdep_context_t *uc = c->uc; - - if (c->sigcontext_format == AARCH64_SCF_NONE) - { - /* Since there are no signals involved here we restore EH and non scratch - registers only. */ - unsigned long regs[24]; - regs[0] = uc->uc_mcontext.regs[0]; - regs[1] = uc->uc_mcontext.regs[1]; - regs[2] = uc->uc_mcontext.regs[2]; - regs[3] = uc->uc_mcontext.regs[3]; - regs[4] = uc->uc_mcontext.regs[19]; - regs[5] = uc->uc_mcontext.regs[20]; - regs[6] = uc->uc_mcontext.regs[21]; - regs[7] = uc->uc_mcontext.regs[22]; - regs[8] = uc->uc_mcontext.regs[23]; - regs[9] = uc->uc_mcontext.regs[24]; - regs[10] = uc->uc_mcontext.regs[25]; - regs[11] = uc->uc_mcontext.regs[26]; - regs[12] = uc->uc_mcontext.regs[27]; - regs[13] = uc->uc_mcontext.regs[28]; - regs[14] = uc->uc_mcontext.regs[29]; /* FP */ - regs[15] = uc->uc_mcontext.regs[30]; /* LR */ - regs[16] = GET_FPCTX(uc)->vregs[8]; - regs[17] = GET_FPCTX(uc)->vregs[9]; - regs[18] = GET_FPCTX(uc)->vregs[10]; - regs[19] = GET_FPCTX(uc)->vregs[11]; - regs[20] = GET_FPCTX(uc)->vregs[12]; - regs[21] = GET_FPCTX(uc)->vregs[13]; - regs[22] = GET_FPCTX(uc)->vregs[14]; - regs[23] = GET_FPCTX(uc)->vregs[15]; - unsigned long sp = uc->uc_mcontext.sp; - - struct regs_overlay { - char x[sizeof(regs)]; - }; - - __asm__ __volatile__ ( - "mov x4, %0\n" - "mov x5, %1\n" - "ldp x0, x1, [x4]\n" - "ldp x2, x3, [x4,16]\n" - "ldp x19, x20, [x4,32]\n" - "ldp x21, x22, [x4,48]\n" - "ldp x23, x24, [x4,64]\n" - "ldp x25, x26, [x4,80]\n" - "ldp x27, x28, [x4,96]\n" - "ldp x29, x30, [x4,112]\n" - "ldp d8, d9, [x4,128]\n" - "ldp d10, d11, [x4,144]\n" - "ldp d12, d13, [x4,160]\n" - "ldp d14, d15, [x4,176]\n" - "mov sp, x5\n" - "ret \n" - : - : "r" (regs), - "r" (sp), - "m" (*(struct regs_overlay *)regs) - ); - } - else - { - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - - if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0]; - if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1]; - if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2]; - if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3]; - - sc->regs[4] = uc->uc_mcontext.regs[4]; - sc->regs[5] = uc->uc_mcontext.regs[5]; - sc->regs[6] = uc->uc_mcontext.regs[6]; - sc->regs[7] = uc->uc_mcontext.regs[7]; - sc->regs[8] = uc->uc_mcontext.regs[8]; - sc->regs[9] = uc->uc_mcontext.regs[9]; - sc->regs[10] = uc->uc_mcontext.regs[10]; - sc->regs[11] = uc->uc_mcontext.regs[11]; - sc->regs[12] = uc->uc_mcontext.regs[12]; - sc->regs[13] = uc->uc_mcontext.regs[13]; - sc->regs[14] = uc->uc_mcontext.regs[14]; - sc->regs[15] = uc->uc_mcontext.regs[15]; - sc->regs[16] = uc->uc_mcontext.regs[16]; - sc->regs[17] = uc->uc_mcontext.regs[17]; - sc->regs[18] = uc->uc_mcontext.regs[18]; - sc->regs[19] = uc->uc_mcontext.regs[19]; - sc->regs[20] = uc->uc_mcontext.regs[20]; - sc->regs[21] = uc->uc_mcontext.regs[21]; - sc->regs[22] = uc->uc_mcontext.regs[22]; - sc->regs[23] = uc->uc_mcontext.regs[23]; - sc->regs[24] = uc->uc_mcontext.regs[24]; - sc->regs[25] = uc->uc_mcontext.regs[25]; - sc->regs[26] = uc->uc_mcontext.regs[26]; - sc->regs[27] = uc->uc_mcontext.regs[27]; - sc->regs[28] = uc->uc_mcontext.regs[28]; - sc->regs[29] = uc->uc_mcontext.regs[29]; - sc->regs[30] = uc->uc_mcontext.regs[30]; - sc->sp = uc->uc_mcontext.sp; - sc->pc = uc->uc_mcontext.pc; - sc->pstate = uc->uc_mcontext.pstate; - - __asm__ __volatile__ ( - "mov sp, %0\n" - "ret %1\n" - : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) - ); - } - unreachable(); -#else - printf ("%s: implement me\n", __FUNCTION__); -#endif - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ static inline void establish_machine_state (struct cursor *c) @@ -160,19 +37,17 @@ establish_machine_state (struct cursor *c) Debug (8, "copying out cursor state\n"); - for (reg = 0; reg <= UNW_AARCH64_V31; ++reg) + for (reg = 0; reg <= UNW_AARCH64_RA_SIGN_STATE; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + for (reg = UNW_AARCH64_V0; reg <= UNW_AARCH64_V31; ++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) - as->acc.access_fpreg (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - as->acc.access_reg (as, reg, &val, 1, arg); - } + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); } } @@ -191,8 +66,10 @@ unw_resume (unw_cursor_t *cursor) return -UNW_EINVAL; } +Debug(1, "==smw> before establish_machine_state\n"); establish_machine_state (c); +Debug(1, "==smw> before acc.resume\n"); return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, c->dwarf.as_arg); } diff --git a/src/native/external/libunwind/src/aarch64/Gstep.c b/src/native/external/libunwind/src/aarch64/Gstep.c index f4ef369d3a1096..3602da3d0530c8 100644 --- a/src/native/external/libunwind/src/aarch64/Gstep.c +++ b/src/native/external/libunwind/src/aarch64/Gstep.c @@ -2,6 +2,7 @@ Copyright (C) 2008 CodeSourcery Copyright (C) 2011-2013 Linaro Limited Copyright (C) 2012 Tommi Rantala + Copyright 2022 Blackberry Limited. This file is part of libunwind. @@ -25,38 +26,433 @@ 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 "dwarf_i.h" +#include "ucontext_i.h" #include "unwind_i.h" -#include "offsets.h" + +static const int WSIZE = sizeof (unw_word_t); /* Recognise PLT entries such as: 40ddf0: b0000570 adrp x16, 4ba000 <_GLOBAL_OFFSET_TABLE_+0x2a8> 40ddf4: f9433611 ldr x17, [x16,#1640] 40ddf8: 9119a210 add x16, x16, #0x668 - 40ddfc: d61f0220 br x17 */ + 40ddfc: d61f0220 br x17 + + \note The current implementation only supports little endian modes. +*/ static int is_plt_entry (struct dwarf_cursor *c) { - unw_word_t w0, w1; + unw_word_t w0 = 0, w1 = 0; + unw_accessors_t *a; + + if (c->as->big_endian) + { + return 0; + } + + /* + A PLT (Procedure Linkage Table) is used by the dynamic linker to map the + relative address of a position independent function call onto the real + address of the function. If we attempt to unwind from any instruction + inside the PLT, and the PLT is missing DWARF unwind information, then + conventional unwinding will fail because although the function has been + "called" we have not yet entered the prologue and set-up the stack frame. + + This code looks to see if the instruction is anywhere within a "recognised" + PLT entry (note that the IP could be anywhere within the PLT, so we have to + examine nearby instructions). + */ + + struct instruction_entry + { + uint32_t pattern; + uint32_t mask; + } instructions[4] = + { + // aarch64 + {0x90000010,0x9f00001f}, // adrp + {0xf9400211,0xffc003ff}, // ldr + {0x91000210,0xff8003ff}, // add + {0xd61f0220,0xffffffff}, // br + }; + + a = unw_get_accessors (c->as); + if ((*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg) < 0) + { + return 0; + } + + /* + NB: the following code is endian sensitive! + + The current implementation is for little-endian modes, big-endian modes + will see the first instruction in the high bits of w0, and the second + instruction in the low bits of w0. Some tweaks will be needed to read from + the correct part of the word to support big endian modes. + */ + if ((w0 & instructions[0].mask) == instructions[0].pattern && + ((w0>>32) & instructions[1].mask) == instructions[1].pattern) + { + if ((*a->access_mem) (c->as, c->ip+8, &w1, 0, c->as_arg) >= 0 && + (w1 & instructions[2].mask) == instructions[2].pattern && + ((w1>>32) & instructions[3].mask) == instructions[3].pattern) + { + return 1; + } + else + { + return 0; + } + } + else if ((w0 & instructions[2].mask) == instructions[2].pattern && + ((w0>>32) & instructions[3].mask) == instructions[3].pattern) + { + w1 = w0; + if ((*a->access_mem) (c->as, c->ip-8, &w0, 0, c->as_arg) >= 0 && + (w0 & instructions[0].mask) == instructions[0].pattern && + ((w0>>32) & instructions[1].mask) == instructions[1].pattern) + { + return 1; + } + else + { + return 0; + } + } + else if ((w0 & instructions[1].mask) == instructions[1].pattern && + ((w0>>32) & instructions[2].mask) == instructions[2].pattern) + { + if ((*a->access_mem) (c->as, c->ip-4, &w0, 0, c->as_arg) < 0 || + (*a->access_mem) (c->as, c->ip+4, &w1, 0, c->as_arg) < 0) + { + return 0; + } + } + else if ((w0 & instructions[3].mask) == instructions[3].pattern) + { + if ((*a->access_mem) (c->as, c->ip-12, &w0, 0, c->as_arg) < 0 || + (*a->access_mem) (c->as, c->ip-4, &w1, 0, c->as_arg) < 0) + { + return 0; + } + } + + if ((w0 & instructions[0].mask) == instructions[0].pattern && + ((w0>>32) & instructions[1].mask) == instructions[1].pattern && + (w1 & instructions[2].mask) == instructions[2].pattern && + ((w1>>32) & instructions[3].mask) == instructions[3].pattern) + { + return 1; + } + else + { + return 0; + } +} + +typedef enum frame_record_location + { + NONE, /* frame record creation has not been detected, use LR */ + AT_SP_OFFSET, /* frame record creation has been detected, but FP + update not detected */ + AT_FP, /* frame record creation and FP update detected */ + } frame_record_location_t; + +typedef struct frame_state + { + frame_record_location_t loc; + int32_t offset; + } frame_state_t; + +/* Recognise when a frame record storing FP+LR has been created and whether FP + has been updated to point to the frame record. For example: + 4183d4: a9bd7bfd stp x29, x30, [sp,#-48]! <= FP+LR stored + 4183d8: d2800005 mov x5, #0x0 + 4183dc: d2800004 mov x4, #0x0 + 4183e0: 910003fd mov x29, sp <= FP updated + 4183e4: a90153f3 stp x19, x20, [sp,#16] + ... + 418444: a94153f3 ldp x19, x20, [sp,#16] + 418448: f94013f5 ldr x21, [sp,#32] + 41844c: a8c37bfd ldp x29, x30, [sp],#48 <= FP+LR retrieved + 418450: d65f03c0 ret +*/ +static frame_state_t +get_frame_state (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_accessors_t *a = unw_get_accessors (c->dwarf.as); + unw_word_t w, start_ip, ip, offp; + frame_state_t fs; + fs.loc = NONE; + fs.offset = 0; + + /* PLT entries do not create frame records */ + if (is_plt_entry (&c->dwarf)) + return fs; + + /* Use get_proc_name to find start_ip of procedure */ + char name[128]; + if (((*a->get_proc_name) (c->dwarf.as, c->dwarf.ip, name, sizeof(name), &offp, c->dwarf.as_arg)) != 0) + return fs; + + start_ip = c->dwarf.ip - offp; + + /* Check for frame record instructions since the start of the procedure (start_ip). + * access_mem reads WSIZE bytes, so two instructions are checked in each iteration + */ + for (ip = start_ip; ip < c->dwarf.ip; ip += WSIZE) + { + if ((*a->access_mem) (c->dwarf.as, ip, &w, 0, c->dwarf.as_arg) < 0) + return fs; + + if (fs.loc == NONE) + { + /* Check that a 64-bit store pair (STP) instruction storing FP and LR + has been executed, which would indicate that a frame record has been + created and that the LR value is saved therein. + + From the ARM Architecture Reference Manual (ARMv8), the format of the + 64-bit STP instruction is + + | 10 | 101 | 0 | 0XX | 0 | imm7 | Rt2 | Rn | Rt | + + where X can be 0/1 above to indicate the instruction variant (post- + index, pre-index or signed offset). imm7 is a 7-bit signed immediate + offset. The following should be asserted for this check + + Rt2 == LR (x30) => 0b11110 + Rn == SP (x31) => 0b11111 + Rt == FP (x29) => 0b11101. + + Hence the bitmask should be constructed to assert that the instruction + is + + | 10 | 101 | 0 | 0XX | 0 | XXXXXXX | 11110 | 11111 | 11101 | + + So using a bitmask of 0xfe407fff, the masked instruction would be + 0xa8007bfd */ + if ((((w & 0xfe407fff00000000) == 0xa8007bfd00000000) && (c->dwarf.ip > ip + 4)) + || (((w & 0x00000000fe407fff) == 0x00000000a8007bfd) && (c->dwarf.ip > ip))) + { + fs.loc = AT_SP_OFFSET; + + /* If the signed offset variant of the STP instruction is detected, + the frame record may not be currently pointed to by SP. Extract + the offset from the STP instruction. + + From the ARM Architecture Reference Manual (ARMv8), the format of + the signed offset variant of the 64-bit STP instruction is + + | 10 | 101 | 0 | 010 | 0 | imm7 | Rt2 | Rn | Rt | + + Hence the bitmask should be constructed to assert that the + instruction is + + | 10 | 101 | 0 | 010 | 0 | XXXXXXX | 11110 | 11111 | 11101 | + + So using a bitmask of 0xffc07fff, the masked instruction would + be 0xa9007bdf. The offset value is (imm7 * 8) */ + if (((w & 0xffc07fff00000000) == 0xa9007bfd00000000) && (c->dwarf.ip > ip + 4)) + { + int32_t abs_offset = (w & 0x001f800000000000) >> 47; + fs.offset = ((w & 0x0020000000000000)? -abs_offset : abs_offset) * 8; + } + else if (((w & 0x00000000ffc07fff) == 0x00000000a9007bfd) && (c->dwarf.ip > ip)) + { + int32_t abs_offset = (w & 0x00000000001f8000) >> 15; + fs.offset = ((w & 0x0000000000200000)? -abs_offset : abs_offset) * 8; + } + else + fs.offset = 0; + + Debug (4, "ip=0x%lx => frame record stored at SP+0x%x\n", ip, fs.offset); + } + } + + if (fs.loc == AT_SP_OFFSET) + { + /* If the STP instruction has been executed, but not the instruction + to update FP, then the SP (with offset) should be used to find the + frame record, otherwise the FP should be used as there are no + guarantees that the SP is pointing to the frame record after the FP + has been updated. + + Two methods for updating the FP have been seen in practice. The + first is a MOV instruction. From the ARM Architecture Reference + Manual (ARMv8), the 64-bit MOV (to/from SP) instruction to update + FP (x29) is 0x910003fd. + + The second is an ADD instruction taking SP and FP as the source and + destination registers, respectively. From the ARM Architecture + Reference Manual (ARMv8), the 64-bit ADD (immediate) instruction is + + | 1 | 0 | 0 | 10001 | shift | imm12 | Rn | Rd | + + where the values of shift and imm12 are irrelevant for this check. + The following should be asserted + + Rn == SP (x31) => 0b11111 + Rd == FP (x29) => 0b11101. + + Hence the bitmask should be constructed to assert that the instruction + is + + | 1 | 0 | 0 | 10001 | XX | XXXXXXXXXXXX | 11111 | 11101 | + + So using a bitmask of 0xff0003ff, the masked instruction would be + 0x910003fd. + + Since the MOV instruction is an alias for ADD, it is sufficient to + only check for the latter case. */ + if ((((w & 0xff0003ff00000000) == 0x910003fd00000000) && (c->dwarf.ip > ip + 4)) + || (((w & 0x00000000ff0003ff) == 0x00000000910003fd) && (c->dwarf.ip > ip))) + { + fs.loc = AT_FP; + fs.offset = 0; + + Debug (4, "ip=0x%lx => frame record stored at FP\n", ip); + } + } + else if (fs.loc == AT_FP) + { + /* Check that a 64-bit load pair (LDP) instruction to restore FP and LR has been + executed, which would indicate that a branch or return instruction is about to + be executed and that FP is pointing to the caller's frame record instead. The + LR should be examined for the return address. In this case, the RA must have + already been authenticated. + + From the ARM Architecture Reference Manual (ARMv8), the format of the 64-bit + LDP instruction is + + | 10 | 101 | 0 | 0XX | 1 | imm7 | Rt2 | Rn | Rt | + + where X can be 0/1 above to indicate the instruction variant (post-index, pre- + index or signed offset). imm7 is a 7-bit signed immediate offset, which is + irrelevant for this check. However, the following should be asserted + + Rt2 == LR (x30) => 0b11110 + Rn == SP (x31) => 0b11111 + Rt == FP (x29) => 0b11101. + + Hence the bitmask should be constructed to assert that the instruction is + + | 10 | 101 | 0 | 0XX | 1 | XXXXXXX | 11110 | 11111 | 11101 | + + So using a bitmask of 0xfe407fff, the masked instruction would be 0xa8407bfd */ + if ((((w & 0xfe407fff00000000) == 0xa8407bfd00000000) && (c->dwarf.ip > ip + 4)) + || (((w & 0x00000000fe407fff) == 0x00000000a8407bfd) && (c->dwarf.ip > ip))) + { + fs.loc = NONE; + fs.offset = 0; + + Debug (4, "ip=0x%lx => frame record has been loaded, use LR\n", ip); + } + } + } + + Debug (3, "[start_ip = 0x%lx, ip=0x%lx) => loc = %d, offset = %d\n", + start_ip, c->dwarf.ip, fs.loc, fs.offset); + + return fs; +} + +#if defined __QNX__ +/* + * QNX kernel call have neither CFI nor save frame pointer, + * 00000000000549e8 : + * 549e8: cb0203e2 neg x2, x2 + * 549ec: 52800168 mov w8, #0xb // #11 + * 549f0: d4000a21 svc #0x51 + * 549f4: d65f03c0 ret + * 549f8: cb0003e0 neg x0, x0 + * 549fc: d65f03c0 ret + * + * From disassemble, QNX kernel call have mov followed by svc, and may with some + * neg instructions at beginning. + * 1. find procedure's ip start,end start + * 2. search mov,svc from begin, skip any neg instructions + */ +static bool is_neg_instr(uint32_t instr) +{ + /* 64bit register Xd */ + return ((instr & 0xffe003e0) == 0xcb0003e0); +} + +/* QNX use w8 to pass kernel call number */ +static bool is_mov_w8_instr(uint32_t instr) +{ + /* movz 32bit register Wd */ + return ((instr & 0xffe00008) == 0x52800008); +} + +static bool is_svc_instr(uint32_t instr) +{ + return instr == 0xd4000a21; +} + +static bool +is_qnx_kercall(struct dwarf_cursor *c) +{ + unw_word_t w0; unw_accessors_t *a; int ret; + unw_word_t proc_start_ip; + unw_word_t proc_end_ip; a = unw_get_accessors_int (c->as); - if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 - || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) - return 0; + if (c->as->big_endian || !a->get_proc_ip_range) + { + return false; + } + + ret = (*a->get_proc_ip_range) (c->as, c->ip, &proc_start_ip, &proc_end_ip, c->as_arg); + if (ret < 0) + { + Debug (2, "ip=0x%lx get proc ip range fail, ret = %d\n", c->ip, ret); + return false; + } + + unw_word_t ip = proc_start_ip; + while ((ip < proc_end_ip) && (ip + 8 < proc_end_ip)) + { + if ((*a->access_mem) (c->as, ip, &w0, 0, c->as_arg) < 0) + { + Debug (14, "access_mem ip=0x%lx fail\n", ip); + return false; + } - ret = (((w0 & 0xff0000009f000000) == 0xf900000090000000) - && ((w1 & 0xffffffffff000000) == 0xd61f022091000000)); + uint32_t low32 = w0 & 0xffffffff; + uint32_t high32 = w0 >> 32; + + if (is_mov_w8_instr(low32) && is_svc_instr(high32)) + { + return true; + } + if (is_neg_instr(low32) && is_neg_instr(high32)) + { + ip += 8; + } + else if (is_neg_instr(low32) && is_mov_w8_instr(high32)) + { + ip += 4; + } + else + { + return false; + } + } - Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); - return ret; + return false; } +#endif /* * Save the location of VL (vector length) from the signal frame to the VG (vector * granule) register if it exists, otherwise do nothing. If there is an error, * the location is also not modified. */ +#if defined __linux__ static int get_sve_vl_signal_loc (struct dwarf_cursor* dwarf, unw_word_t sc_addr) { @@ -103,6 +499,13 @@ get_sve_vl_signal_loc (struct dwarf_cursor* dwarf, unw_word_t sc_addr) } return 1; } +#else +static int +get_sve_vl_signal_loc (struct dwarf_cursor* dwarf, unw_word_t sc_addr) +{ + return 1; +} +#endif static int aarch64_handle_signal_frame (unw_cursor_t *cursor) @@ -117,20 +520,19 @@ aarch64_handle_signal_frame (unw_cursor_t *cursor) ret = unw_is_signal_frame (cursor); Debug(1, "unw_is_signal_frame()=%d\n", ret); - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - if (ret > 0) { - c->sigcontext_format = AARCH64_SCF_LINUX_RT_SIGFRAME; - sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + c->sigcontext_format = SCF_FORMAT; + sc_addr = sp_addr + sizeof (siginfo_t) + UC_MCONTEXT_OFF; } else return -UNW_EUNSPEC; + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + c->sigcontext_addr = sc_addr; c->frame_info.frame_type = UNW_AARCH64_FRAME_SIGRETURN; c->frame_info.cfa_reg_offset = sc_addr - sp_addr; @@ -141,40 +543,40 @@ aarch64_handle_signal_frame (unw_cursor_t *cursor) /* Update the dwarf cursor. Set the location of the registers to the corresponding addresses of the uc_mcontext / sigcontext structure contents. */ - c->dwarf.loc[UNW_AARCH64_X0] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X0_OFF); - c->dwarf.loc[UNW_AARCH64_X1] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X1_OFF); - c->dwarf.loc[UNW_AARCH64_X2] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X2_OFF); - c->dwarf.loc[UNW_AARCH64_X3] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X3_OFF); - c->dwarf.loc[UNW_AARCH64_X4] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X4_OFF); - c->dwarf.loc[UNW_AARCH64_X5] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X5_OFF); - c->dwarf.loc[UNW_AARCH64_X6] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X6_OFF); - c->dwarf.loc[UNW_AARCH64_X7] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X7_OFF); - c->dwarf.loc[UNW_AARCH64_X8] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X8_OFF); - c->dwarf.loc[UNW_AARCH64_X9] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X9_OFF); - c->dwarf.loc[UNW_AARCH64_X10] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X10_OFF); - c->dwarf.loc[UNW_AARCH64_X11] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X11_OFF); - c->dwarf.loc[UNW_AARCH64_X12] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X12_OFF); - c->dwarf.loc[UNW_AARCH64_X13] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X13_OFF); - c->dwarf.loc[UNW_AARCH64_X14] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X14_OFF); - c->dwarf.loc[UNW_AARCH64_X15] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X15_OFF); - c->dwarf.loc[UNW_AARCH64_X16] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X16_OFF); - c->dwarf.loc[UNW_AARCH64_X17] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X17_OFF); - c->dwarf.loc[UNW_AARCH64_X18] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X18_OFF); - c->dwarf.loc[UNW_AARCH64_X19] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X19_OFF); - c->dwarf.loc[UNW_AARCH64_X20] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X20_OFF); - c->dwarf.loc[UNW_AARCH64_X21] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X21_OFF); - c->dwarf.loc[UNW_AARCH64_X22] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X22_OFF); - c->dwarf.loc[UNW_AARCH64_X23] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X23_OFF); - c->dwarf.loc[UNW_AARCH64_X24] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X24_OFF); - c->dwarf.loc[UNW_AARCH64_X25] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X25_OFF); - c->dwarf.loc[UNW_AARCH64_X26] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X26_OFF); - c->dwarf.loc[UNW_AARCH64_X27] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X27_OFF); - c->dwarf.loc[UNW_AARCH64_X28] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X28_OFF); - c->dwarf.loc[UNW_AARCH64_X29] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X29_OFF); - c->dwarf.loc[UNW_AARCH64_X30] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_X30_OFF); - c->dwarf.loc[UNW_AARCH64_SP] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_SP_OFF); - c->dwarf.loc[UNW_AARCH64_PC] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_PC_OFF); - c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_MEM_LOC (c->dwarf, sc_addr + LINUX_SC_PSTATE_OFF); + c->dwarf.loc[UNW_AARCH64_X0] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF); + c->dwarf.loc[UNW_AARCH64_X1] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 1); + c->dwarf.loc[UNW_AARCH64_X2] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 2); + c->dwarf.loc[UNW_AARCH64_X3] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 3); + c->dwarf.loc[UNW_AARCH64_X4] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 4); + c->dwarf.loc[UNW_AARCH64_X5] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 5); + c->dwarf.loc[UNW_AARCH64_X6] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 6); + c->dwarf.loc[UNW_AARCH64_X7] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 7); + c->dwarf.loc[UNW_AARCH64_X8] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 8); + c->dwarf.loc[UNW_AARCH64_X9] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 9); + c->dwarf.loc[UNW_AARCH64_X10] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 10); + c->dwarf.loc[UNW_AARCH64_X11] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 11); + c->dwarf.loc[UNW_AARCH64_X12] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 12); + c->dwarf.loc[UNW_AARCH64_X13] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 13); + c->dwarf.loc[UNW_AARCH64_X14] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 14); + c->dwarf.loc[UNW_AARCH64_X15] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 15); + c->dwarf.loc[UNW_AARCH64_X16] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 16); + c->dwarf.loc[UNW_AARCH64_X17] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 17); + c->dwarf.loc[UNW_AARCH64_X18] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 18); + c->dwarf.loc[UNW_AARCH64_X19] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 19); + c->dwarf.loc[UNW_AARCH64_X20] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 20); + c->dwarf.loc[UNW_AARCH64_X21] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 21); + c->dwarf.loc[UNW_AARCH64_X22] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 22); + c->dwarf.loc[UNW_AARCH64_X23] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 23); + c->dwarf.loc[UNW_AARCH64_X24] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 24); + c->dwarf.loc[UNW_AARCH64_X25] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 25); + c->dwarf.loc[UNW_AARCH64_X26] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 26); + c->dwarf.loc[UNW_AARCH64_X27] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 27); + c->dwarf.loc[UNW_AARCH64_X28] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_GPR_OFF + 8 * 28); + c->dwarf.loc[UNW_AARCH64_X29] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_X29_OFF); + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_X30_OFF); + c->dwarf.loc[UNW_AARCH64_SP] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_SP_OFF); + c->dwarf.loc[UNW_AARCH64_PC] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_PC_OFF); + c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_MEM_LOC (c->dwarf, sc_addr + SC_PSTATE_OFF); c->dwarf.loc[UNW_AARCH64_VG] = DWARF_NULL_LOC; /* Set SP/CFA and PC/IP. */ @@ -192,6 +594,7 @@ unw_step (unw_cursor_t *cursor) { struct cursor *c = (struct cursor *) cursor; int validate = c->validate; + unw_word_t fp = 0; int ret; Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n", @@ -213,29 +616,129 @@ unw_step (unw_cursor_t *cursor) dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_X30], &c->dwarf.ip); } - /* Restore default memory validation state */ - c->validate = validate; - + /* Try DWARF-based unwinding... */ + c->sigcontext_format = AARCH64_SCF_NONE; ret = dwarf_step (&c->dwarf); Debug(1, "dwarf_step()=%d\n", ret); + /* Restore default memory validation state */ + c->validate = validate; + if (unlikely (ret == -UNW_ESTOPUNWIND)) return ret; + if (likely (ret > 0)) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_X29], &fp); + if (ret == 0 && fp == 0) + { + /* Procedure Call Standard for the ARM 64-bit Architecture (AArch64) + * specifies that the end of the frame record chain is indicated by + * the address zero in the address for the previous frame. + */ + c->dwarf.ip = 0; + Debug (2, "NULL frame pointer X29 loc, returning 0\n"); + return 0; + } + } + if (unlikely (ret < 0)) { /* DWARF failed. */ + + /* + * We could get here because of missing/bad unwind information. + * Validate all addresses before dereferencing. + */ + if (c->dwarf.as == unw_local_addr_space) + { + c->validate = 1; + } + if (is_plt_entry (&c->dwarf)) { Debug (2, "found plt entry\n"); c->frame_info.frame_type = UNW_AARCH64_FRAME_STANDARD; } +#if defined __QNX__ + else if (is_qnx_kercall(&c->dwarf)) + { + Debug (2, "found qnx kernel call, fallback to use link register\n"); + c->frame_info.frame_type = UNW_AARCH64_FRAME_GUESSED; + } +#endif else { - Debug (2, "fallback\n"); + /* Try use frame record. */ c->frame_info.frame_type = UNW_AARCH64_FRAME_GUESSED; + } + + frame_state_t fs = get_frame_state(cursor); + + /* Prefer using frame record. The LR value is stored at an offset of + 8 into the frame record. */ + if (fs.loc != NONE) + { + if (fs.loc == AT_FP) + { + /* X29 points to frame record. */ + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_X29], &fp); + if (unlikely (ret == 0)) + { + if (fp == 0) + { + /* Procedure Call Standard for the ARM 64-bit Architecture (AArch64) + * specifies that the end of the frame record chain is indicated by + * the address zero in the address for the previous frame. + */ + c->dwarf.ip = 0; + Debug (2, "NULL frame pointer X29 loc, returning 0\n"); + return 0; + } + } + + for (int i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + /* Frame record holds X29 and X30 values. */ + c->dwarf.loc[UNW_AARCH64_X29] = DWARF_MEM_LOC (c->dwarf, fp); + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_MEM_LOC (c->dwarf, fp + 8); + } + else + { + /* Frame record stored but not pointed to by X29, use SP. */ + unw_word_t sp; + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &sp); + if (ret < 0) + return ret; + + for (int i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->frame_info.cfa_reg_offset = fs.offset; + c->frame_info.cfa_reg_sp = 1; + + c->dwarf.loc[UNW_AARCH64_X29] = DWARF_MEM_LOC (c->dwarf, sp + fs.offset); + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_MEM_LOC (c->dwarf, sp + fs.offset + 8); + } + + c->dwarf.loc[UNW_AARCH64_PC] = c->dwarf.loc[UNW_AARCH64_X30]; + + /* Set SP/CFA and PC/IP. */ + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_X29], &c->dwarf.cfa); + if (ret < 0) + return ret; + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); + if (ret == 0) + { + ret = 1; + } + Debug (2, "fallback, CFA = 0x%016lx, IP = 0x%016lx returning %d\n", + c->dwarf.cfa, c->dwarf.ip, ret); + return ret; } - /* Use link register (X30). */ + + /* No frame record, fallback to link register (X30). */ c->frame_info.cfa_reg_offset = 0; c->frame_info.cfa_reg_sp = 0; c->frame_info.fp_cfa_offset = -1; diff --git a/src/native/external/libunwind/src/aarch64/Gtrace.c b/src/native/external/libunwind/src/aarch64/Gtrace.c index bcdf19296b31a1..555b4a50b45c45 100644 --- a/src/native/external/libunwind/src/aarch64/Gtrace.c +++ b/src/native/external/libunwind/src/aarch64/Gtrace.c @@ -25,7 +25,7 @@ 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 "offsets.h" +#include "ucontext_i.h" #include #include @@ -70,7 +70,7 @@ trace_cache_free (void *arg) } tls_cache_destroyed = 1; tls_cache = NULL; - munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mi_munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); mempool_free (&trace_cache_pool, cache); Debug(5, "freed cache %p\n", cache); } @@ -152,7 +152,7 @@ trace_cache_expand (unw_trace_cache_t *cache) } Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); - munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + mi_munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); cache->frames = new_frames; cache->log_size = new_log_size; cache->used = 0; @@ -407,7 +407,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) int depth = 0; int ret; - /* Check input parametres. */ + /* Check input parameters. */ if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) return -UNW_EINVAL; @@ -483,13 +483,20 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) /* Advance standard traceable frame. */ cfa = (f->cfa_reg_sp ? sp : fp) + f->cfa_reg_offset; if (likely(f->lr_cfa_offset != -1)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); + { + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); + } else if (lr != 0) - { - /* Use the saved link register as the new pc. */ - pc = lr; - lr = 0; - } + { + /* Use the saved link register as the new pc. */ + pc = lr; + lr = 0; + } + else + { + /* Cached frame has no LR and neither do we. */ + return -UNW_ESTOPUNWIND; + } if (likely(ret >= 0) && likely(f->fp_cfa_offset != -1)) ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->fp_cfa_offset, fp); @@ -503,15 +510,15 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) case UNW_AARCH64_FRAME_SIGRETURN: cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); + ACCESS_MEM_FAST(ret, c->validate, d, cfa + SC_PC_OFF, pc); if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X29_OFF, fp); + ACCESS_MEM_FAST(ret, c->validate, d, cfa + SC_X29_OFF, fp); if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_SP_OFF, sp); + ACCESS_MEM_FAST(ret, c->validate, d, cfa + SC_SP_OFF, sp); /* Save the link register here in case we end up in a function that doesn't save the link register in the prologue, e.g. kill. */ if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X30_OFF, lr); + ACCESS_MEM_FAST(ret, c->validate, d, cfa + SC_X30_OFF, lr); /* Resume stack at signal restoration point. The stack is not necessarily continuous here, especially with sigaltstack(). */ diff --git a/src/native/external/libunwind/src/tilegx/Linit_local.c b/src/native/external/libunwind/src/aarch64/Los-freebsd.c similarity index 81% rename from src/native/external/libunwind/src/tilegx/Linit_local.c rename to src/native/external/libunwind/src/aarch64/Los-freebsd.c index 68a1687e85444b..a75a205df19c01 100644 --- a/src/native/external/libunwind/src/tilegx/Linit_local.c +++ b/src/native/external/libunwind/src/aarch64/Los-freebsd.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" +#include "Gos-freebsd.c" #endif diff --git a/src/native/external/libunwind/src/tilegx/Lglobal.c b/src/native/external/libunwind/src/aarch64/Los-linux.c similarity index 82% rename from src/native/external/libunwind/src/tilegx/Lglobal.c rename to src/native/external/libunwind/src/aarch64/Los-linux.c index 6d7b489e14bd9f..3cc18aabcc399c 100644 --- a/src/native/external/libunwind/src/tilegx/Lglobal.c +++ b/src/native/external/libunwind/src/aarch64/Los-linux.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" +#include "Gos-linux.c" #endif diff --git a/src/native/external/libunwind/src/tilegx/Linit.c b/src/native/external/libunwind/src/aarch64/Los-qnx.c similarity index 83% rename from src/native/external/libunwind/src/tilegx/Linit.c rename to src/native/external/libunwind/src/aarch64/Los-qnx.c index e9abfdd46a3e0f..d5e4b82b9dd127 100644 --- a/src/native/external/libunwind/src/tilegx/Linit.c +++ b/src/native/external/libunwind/src/aarch64/Los-qnx.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" +#include "Gos-qnx.c" #endif diff --git a/src/native/external/libunwind/src/aarch64/gen-offsets.c b/src/native/external/libunwind/src/aarch64/gen-offsets.c deleted file mode 100644 index eadc2377d8f7a7..00000000000000 --- a/src/native/external/libunwind/src/aarch64/gen-offsets.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -#define UC(N,X) \ - printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) - -#define SC(N,X) \ - printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) - -int -main (void) -{ - printf ( -"/* Linux-specific definitions: */\n\n" - -"/* Define various structure offsets to simplify cross-compilation. */\n\n" - -"/* Offsets for AArch64 Linux \"ucontext_t\": */\n\n"); - - UC ("FLAGS", uc_flags); - UC ("LINK", uc_link); - UC ("STACK", uc_stack); - UC ("MCONTEXT", uc_mcontext); - UC ("SIGMASK", uc_sigmask); - - printf ("\n/* Offsets for AArch64 Linux \"struct sigcontext\": */\n\n"); - - SC ("R0", regs[0]); - SC ("R1", regs[1]); - SC ("R2", regs[2]); - SC ("R3", regs[3]); - SC ("R4", regs[4]); - SC ("R5", regs[5]); - SC ("R6", regs[6]); - SC ("R7", regs[7]); - SC ("R8", regs[8]); - SC ("R9", regs[9]); - SC ("R10", regs[10]); - SC ("R11", regs[11]); - SC ("R12", regs[12]); - SC ("R13", regs[13]); - SC ("R14", regs[14]); - SC ("R15", regs[15]); - SC ("R16", regs[16]); - SC ("R17", regs[17]); - SC ("R18", regs[18]); - SC ("R19", regs[19]); - SC ("R20", regs[20]); - SC ("R21", regs[21]); - SC ("R22", regs[22]); - SC ("R23", regs[23]); - SC ("R24", regs[24]); - SC ("R25", regs[25]); - SC ("R26", regs[26]); - SC ("R27", regs[27]); - SC ("R28", regs[28]); - SC ("R29", regs[29]); - SC ("R30", regs[30]); - SC ("R31", regs[31]); - - SC ("PC", pc); - SC ("SP", sp); - SC ("Fault", fault_address); - SC ("state", pstate); - return 0; -} diff --git a/src/native/external/libunwind/src/aarch64/getcontext.S b/src/native/external/libunwind/src/aarch64/getcontext.S index 25ed5b66be73ea..6fcd17c488bc73 100644 --- a/src/native/external/libunwind/src/aarch64/getcontext.S +++ b/src/native/external/libunwind/src/aarch64/getcontext.S @@ -24,7 +24,7 @@ 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 "offsets.h" +#include "ucontext_i.h" /* int _Uaarch64_getcontext_trace (unw_tdep_context_t *ucp) @@ -39,10 +39,10 @@ _Uaarch64_getcontext_trace: .cfi_startproc /* Save only FP, SP, PC - exclude this call. */ - str x29, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_X29_OFF)] + str x29, [x0, #(UC_MCONTEXT_OFF + SC_X29_OFF)] mov x9, sp - str x9, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_SP_OFF)] - str x30, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_PC_OFF)] + str x9, [x0, #(UC_MCONTEXT_OFF + SC_SP_OFF)] + str x30, [x0, #(UC_MCONTEXT_OFF + SC_PC_OFF)] ret .cfi_endproc diff --git a/src/native/external/libunwind/include/x86/jmpbuf.h b/src/native/external/libunwind/src/aarch64/longjmp.S similarity index 69% rename from src/native/external/libunwind/include/x86/jmpbuf.h rename to src/native/external/libunwind/src/aarch64/longjmp.S index 94d5984f08c496..a1b73f0509b6e7 100644 --- a/src/native/external/libunwind/include/x86/jmpbuf.h +++ b/src/native/external/libunwind/src/aarch64/longjmp.S @@ -1,6 +1,5 @@ /* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2023 Dmitry Chagin This file is part of libunwind. @@ -23,9 +22,25 @@ 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. */ -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + .global _UI_longjmp_cont + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: +#if defined(__linux__) || defined(__QNX__) + ret +#elif defined(__FreeBSD__) + .cfi_startproc + /* + * x0 - return address + * x1 - return value + */ + mov x30, x0 + mov x0, x1 + ret + .cfi_endproc +#else +#error Port me +#endif + .size _UI_longjmp_cont, . - _UI_longjmp_cont -#define JB_SP 4 -#define JB_RP 5 -#define JB_MASK_SAVED 6 -#define JB_MASK 7 + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits diff --git a/src/native/external/libunwind/src/aarch64/offsets.h b/src/native/external/libunwind/src/aarch64/offsets.h deleted file mode 100644 index 52291edb33d9cd..00000000000000 --- a/src/native/external/libunwind/src/aarch64/offsets.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* Offsets for AArch64 Linux "ucontext_t": */ - -#define LINUX_UC_FLAGS_OFF 0x0 -#define LINUX_UC_LINK_OFF 0x8 -#define LINUX_UC_STACK_OFF 0x10 -#define LINUX_UC_SIGMASK_OFF 0x28 -#define LINUX_UC_MCONTEXT_OFF 0xb0 - -/* Offsets for AArch64 Linux "struct sigcontext": */ - -#define LINUX_SC_FAULTADDRESS_OFF 0x00 -#define LINUX_SC_X0_OFF 0x008 -#define LINUX_SC_X1_OFF 0x010 -#define LINUX_SC_X2_OFF 0x018 -#define LINUX_SC_X3_OFF 0x020 -#define LINUX_SC_X4_OFF 0x028 -#define LINUX_SC_X5_OFF 0x030 -#define LINUX_SC_X6_OFF 0x038 -#define LINUX_SC_X7_OFF 0x040 -#define LINUX_SC_X8_OFF 0x048 -#define LINUX_SC_X9_OFF 0x050 -#define LINUX_SC_X10_OFF 0x058 -#define LINUX_SC_X11_OFF 0x060 -#define LINUX_SC_X12_OFF 0x068 -#define LINUX_SC_X13_OFF 0x070 -#define LINUX_SC_X14_OFF 0x078 -#define LINUX_SC_X15_OFF 0x080 -#define LINUX_SC_X16_OFF 0x088 -#define LINUX_SC_X17_OFF 0x090 -#define LINUX_SC_X18_OFF 0x098 -#define LINUX_SC_X19_OFF 0x0a0 -#define LINUX_SC_X20_OFF 0x0a8 -#define LINUX_SC_X21_OFF 0x0b0 -#define LINUX_SC_X22_OFF 0x0b8 -#define LINUX_SC_X23_OFF 0x0c0 -#define LINUX_SC_X24_OFF 0x0c8 -#define LINUX_SC_X25_OFF 0x0d0 -#define LINUX_SC_X26_OFF 0x0d8 -#define LINUX_SC_X27_OFF 0x0e0 -#define LINUX_SC_X28_OFF 0x0e8 -#define LINUX_SC_X29_OFF 0x0f0 -#define LINUX_SC_X30_OFF 0x0f8 -#define LINUX_SC_SP_OFF 0x100 -#define LINUX_SC_PC_OFF 0x108 -#define LINUX_SC_PSTATE_OFF 0x110 -#define LINUX_SC_RESERVED_OFF 0x120 - -// struct _aarch64_ctx { __u32 magic; __u32 size; }; -// struct sve_context { struct _aarch64_ctx head; __u16 vl; __u16 __reserved[3]; }; -#define LINUX_SC_RESERVED_MAGIC_OFF 0x0 -#define LINUX_SC_RESERVED_SIZE_OFF 0x4 -#define LINUX_SC_RESERVED_SVE_VL_OFF 0x8 \ No newline at end of file diff --git a/src/native/external/libunwind/src/aarch64/setcontext.S b/src/native/external/libunwind/src/aarch64/setcontext.S new file mode 100644 index 00000000000000..2ab1165f491888 --- /dev/null +++ b/src/native/external/libunwind/src/aarch64/setcontext.S @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2023 Dmitry Chagin + +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 "ucontext_i.h" + + + .global _Uaarch64_setcontext + .type _Uaarch64_setcontext, @function +_Uaarch64_setcontext: + .cfi_startproc + + /* + * Since there are no signals involved here we restore EH and + * non scratch registers only. + */ + + mov x9, x0 + ldp x0, x1, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF)] + ldp x2, x3, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF + 2 * 8)] + ldp x19, x20, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF + 19 * 8)] + ldp x21, x22, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF + 21 * 8)] + ldp x23, x24, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF + 23 * 8)] + ldp x25, x26, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF + 25 * 8)] + ldp x27, x28, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF + 27 * 8)] + ldp x29, x30, [x9, #(UC_MCONTEXT_OFF + SC_GPR_OFF + 29 * 8)] + + ldp q8, q9, [x9, #(UC_MCONTEXT_OFF + SC_FPSIMD_OFF + 8 * 16)] + ldp q10, q11, [x9, #(UC_MCONTEXT_OFF + SC_FPSIMD_OFF + 10 * 16)] + ldp q12, q13, [x9, #(UC_MCONTEXT_OFF + SC_FPSIMD_OFF + 12 * 16)] + ldp q14, q15, [x9, #(UC_MCONTEXT_OFF + SC_FPSIMD_OFF + 14 * 16)] + + ldr x9, [x9, #(UC_MCONTEXT_OFF + SC_SP_OFF)] + mov sp, x9 + + ret + .cfi_endproc + .size _Uaarch64_setcontext, . - _Uaarch64_setcontext + + .section .note.GNU-stack,"",@progbits diff --git a/src/native/external/libunwind/src/aarch64/siglongjmp.S b/src/native/external/libunwind/src/aarch64/siglongjmp.S index 9985c4b4aab378..92de7b2521a664 100644 --- a/src/native/external/libunwind/src/aarch64/siglongjmp.S +++ b/src/native/external/libunwind/src/aarch64/siglongjmp.S @@ -1,12 +1,59 @@ - /* Dummy implementation for now. */ +/* libunwind - a platform-independent unwind library + Copyright (C) 2023 Dmitry Chagin - .global _UI_siglongjmp_cont - .global _UI_longjmp_cont +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(__FreeBSD__) +#include +#define SIG_SETMASK 3 +#endif + + .global _UI_siglongjmp_cont + .type _UI_siglongjmp_cont, @function _UI_siglongjmp_cont: -_UI_longjmp_cont: +#if defined(__linux__) || defined(__QNX__) + ret +#elif defined(__FreeBSD__) + .cfi_startproc + /* + * x0 - return address + * x1 - return value + * x2 - mask + */ + stp x0, x1, [sp, #-16]! + .cfi_def_cfa_offset 16 + /* Restore the signal mask */ + mov x1, x2 /* set */ + mov x2, #0 /* oset */ + mov x0, #SIG_SETMASK + mov x8, #SYS_sigprocmask + svc 0 + ldp x30, x0, [sp], #16 + .cfi_def_cfa_offset 0 ret -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",%progbits + .cfi_endproc +#else +#error Port me #endif + .size _UI_siglongjmp_cont, . - _UI_siglongjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits diff --git a/src/native/external/libunwind/src/aarch64/ucontext_i.h b/src/native/external/libunwind/src/aarch64/ucontext_i.h new file mode 100644 index 00000000000000..b1f99edba1b9a6 --- /dev/null +++ b/src/native/external/libunwind/src/aarch64/ucontext_i.h @@ -0,0 +1,74 @@ +/* Contributed by Dmitry Chagin . + +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_src_aarch64_ucontext_i_h +#define libunwind_src_aarch64_ucontext_i_h + +#if defined __FreeBSD__ || defined __APPLE__ + +#define UC_MCONTEXT_OFF 0x10 +#define SC_GPR_OFF 0x00 + +#define SC_X29_OFF 0x0e8 +#define SC_X30_OFF 0x0f0 +#define SC_SP_OFF 0x0f8 +#define SC_PC_OFF 0x100 +#define SC_PSTATE_OFF 0x108 +#define SC_FPSIMD_OFF 0x110 + +#define SCF_FORMAT AARCH64_SCF_FREEBSD_RT_SIGFRAME + +#elif defined(__linux__) + +#define UC_MCONTEXT_OFF 0xb0 +#define SC_GPR_OFF 0x08 + +#define SC_X29_OFF 0x0f0 +#define SC_X30_OFF 0x0f8 +#define SC_SP_OFF 0x100 +#define SC_PC_OFF 0x108 +#define SC_PSTATE_OFF 0x110 + +#define SCF_FORMAT AARCH64_SCF_LINUX_RT_SIGFRAME + +#define LINUX_SC_RESERVED_OFF 0x120 + +#define LINUX_SC_RESERVED_MAGIC_OFF 0x0 +#define LINUX_SC_RESERVED_SIZE_OFF 0x4 +#define LINUX_SC_RESERVED_SVE_VL_OFF 0x8 + +#elif defined(__QNX__) + +#define UC_MCONTEXT_OFF 48 +#define SC_GPR_OFF 0 +#define SC_X29_OFF 232 +#define SC_X30_OFF 240 +#define SC_SP_OFF 248 +#define SC_PC_OFF 256 +#define SC_PSTATE_OFF 264 +#define SCF_FORMAT AARCH64_SCF_QNX_RT_SIGFRAME + +#else +# error Port me +#endif + +#endif /* libunwind_src_aarch64_ucontext_i_h */ diff --git a/src/native/external/libunwind/src/aarch64/unwind_i.h b/src/native/external/libunwind/src/aarch64/unwind_i.h index 9305846f879e97..ab2e1d13fa2101 100644 --- a/src/native/external/libunwind/src/aarch64/unwind_i.h +++ b/src/native/external/libunwind/src/aarch64/unwind_i.h @@ -59,9 +59,7 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, } while (0) #endif -#if defined(__FreeBSD__) -#define GET_FPCTX(uc) ((unw_tdep_context_t *)(&uc->uc_mcontext.mc_spare)) -#else +#if defined(__linux__) #define GET_FPCTX(uc) ((unw_fpsimd_context_t *)(&uc->uc_mcontext.__reserved)) #endif diff --git a/src/native/external/libunwind/src/arm/Gex_tables.c b/src/native/external/libunwind/src/arm/Gex_tables.c index 40cd15346f32d5..56bbd0d07666c5 100644 --- a/src/native/external/libunwind/src/arm/Gex_tables.c +++ b/src/native/external/libunwind/src/arm/Gex_tables.c @@ -531,7 +531,7 @@ arm_find_proc_info2 (unw_addr_space_t as, unw_word_t ip, cb_data.di.format = -1; SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (arm_phdr_cb, &cb_data); + ret = as->iterate_phdr_function (arm_phdr_cb, &cb_data); SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); if (cb_data.di.format != -1) diff --git a/src/native/external/libunwind/src/arm/Ginit.c b/src/native/external/libunwind/src/arm/Ginit.c index 680b2d47b54369..20071fd0130839 100644 --- a/src/native/external/libunwind/src/arm/Ginit.c +++ b/src/native/external/libunwind/src/arm/Ginit.c @@ -73,65 +73,28 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, return 0; } -/* 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 = unw_page_size; - addr = uwn_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 (msync ((void *) addr, len, MS_ASYNC) == -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) { - /* validate address */ - const struct cursor *c = (const struct cursor *) arg; - if (c && validate_mem(addr)) - return -1; + const struct cursor *c = (const struct cursor *) arg; if (write) { Debug (16, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { - *val = *(unw_word_t *) addr; - Debug (16, "mem[%x] -> %x\n", addr, *val); + if (likely (c!= NULL) && unlikely (c->validate) + && unlikely (!unw_address_is_valid (addr, sizeof(unw_word_t)))) + { + Debug (16, "mem[%#010lx] -> invalid\n", (long)addr); + return -1; + } + memcpy (val, (void *) addr, sizeof(unw_word_t)); + Debug (16, "mem[%#010lx] -> %#010lx\n", (long)addr, (long)*val); } return 0; } @@ -146,18 +109,17 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, if (unw_is_fpreg (reg)) goto badreg; -Debug (16, "reg = %s\n", unw_regname (reg)); if (!(addr = uc_addr (uc, reg))) goto badreg; if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- %x\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %x\n", unw_regname (reg), *val); } return 0; @@ -208,10 +170,23 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void arm_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = arm_find_proc_info; local_addr_space.acc.put_unwind_info = arm_put_unwind_info; @@ -221,6 +196,7 @@ arm_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = arm_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/arm/Gstep.c b/src/native/external/libunwind/src/arm/Gstep.c index e4ada651bce817..fccbbd5ff36a01 100644 --- a/src/native/external/libunwind/src/arm/Gstep.c +++ b/src/native/external/libunwind/src/arm/Gstep.c @@ -94,6 +94,8 @@ unw_step (unw_cursor_t *cursor) struct cursor *c = (struct cursor *) cursor; int ret = -UNW_EUNSPEC; int has_stopunwind = 0; + int validate = c->validate; + c->validate = 1; Debug (1, "(cursor=%p)\n", c); @@ -107,9 +109,15 @@ unw_step (unw_cursor_t *cursor) ret = arm_exidx_step (c); Debug(1, "arm_exidx_step()=%d\n", ret); if (ret > 0) - return 1; + { + c->validate = validate; + return 1; + } if (ret == 0) - return ret; + { + c->validate = validate; + return ret; + } if (ret == -UNW_ESTOPUNWIND) has_stopunwind = 1; } @@ -125,16 +133,21 @@ unw_step (unw_cursor_t *cursor) Debug(1, "dwarf_step()=%d\n", ret); if (likely (ret > 0)) - return 1; + { + c->validate = validate; + return 1; + } if (ret < 0 && ret != -UNW_ENOINFO) { Debug (2, "returning %d\n", ret); + c->validate = validate; return ret; } } #endif /* CONFIG_DEBUG_FRAME */ + c->validate = validate; // Before trying the fallback, if any unwind info tell us to stop, do that. if (has_stopunwind) return -UNW_ESTOPUNWIND; diff --git a/src/native/external/libunwind/src/arm/Gtrace.c b/src/native/external/libunwind/src/arm/Gtrace.c index 51fc281de352e6..a73f6cf0a946b2 100644 --- a/src/native/external/libunwind/src/arm/Gtrace.c +++ b/src/native/external/libunwind/src/arm/Gtrace.c @@ -70,7 +70,7 @@ trace_cache_free (void *arg) } tls_cache_destroyed = 1; tls_cache = NULL; - munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mi_munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); mempool_free (&trace_cache_pool, cache); Debug(5, "freed cache %p\n", cache); } @@ -153,7 +153,7 @@ trace_cache_expand (unw_trace_cache_t *cache) Debug(5, "expanded cache from 2^%u to 2^%u buckets\n", cache->log_size, new_log_size); - munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + mi_munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); cache->frames = new_frames; cache->log_size = new_log_size; cache->used = 0; @@ -408,7 +408,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) int depth = 0; int ret; - /* Check input parametres. */ + /* Check input parameters. */ if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) return -UNW_EINVAL; @@ -514,7 +514,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) if (likely(ret >= 0)) ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_LR_OFF, lr); #elif defined(__FreeBSD__) - printf("XXX\n"); + #error implement UNW_ARM_FRAME_SIGRETURN on FreeBSD #endif /* Resume stack at signal restoration point. The stack is not @@ -526,7 +526,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) break; case UNW_ARM_FRAME_SYSCALL: - printf("XXX1\n"); + Dprintf ("%s: implement me\n", __FUNCTION__); break; default: diff --git a/src/native/external/libunwind/src/coredump/_UCD_access_mem.c b/src/native/external/libunwind/src/coredump/_UCD_access_mem.c index cdfc6220283529..9328b9b9f98226 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_access_mem.c +++ b/src/native/external/libunwind/src/coredump/_UCD_access_mem.c @@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "ucd_file_table.h" int -_UCD_access_mem (unw_addr_space_t as, +_UCD_access_mem (unw_addr_space_t as UNUSED, unw_word_t addr, unw_word_t *val, int write, diff --git a/src/native/external/libunwind/src/coredump/_UCD_access_reg_linux.c b/src/native/external/libunwind/src/coredump/_UCD_access_reg_linux.c index bb6826168e8847..302f7bdfd20a61 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_access_reg_linux.c +++ b/src/native/external/libunwind/src/coredump/_UCD_access_reg_linux.c @@ -27,9 +27,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UCD_internal.h" int -_UCD_access_reg (unw_addr_space_t as, - unw_regnum_t regnum, unw_word_t *valp, - int write, void *arg) +_UCD_access_reg (unw_addr_space_t as UNUSED, + unw_regnum_t regnum, + unw_word_t *valp, + int write, + void *arg) { struct UCD_info *ui = arg; @@ -51,9 +53,6 @@ _UCD_access_reg (unw_addr_space_t as, #elif defined(UNW_TARGET_SH) if (regnum > UNW_SH_PR) goto badreg; -#elif defined(UNW_TARGET_TILEGX) - if (regnum > UNW_TILEGX_CFA) - goto badreg; #elif defined(UNW_TARGET_IA64) || defined(UNW_TARGET_HPPA) || defined(UNW_TARGET_PPC32) || defined(UNW_TARGET_PPC64) if (regnum >= ARRAY_SIZE(ui->prstatus->pr_reg)) goto badreg; diff --git a/src/native/external/libunwind/src/coredump/_UCD_access_reg_qnx.c b/src/native/external/libunwind/src/coredump/_UCD_access_reg_qnx.c new file mode 100644 index 00000000000000..1ceaf6a14e66b4 --- /dev/null +++ b/src/native/external/libunwind/src/coredump/_UCD_access_reg_qnx.c @@ -0,0 +1,158 @@ +/** + * Extract filemap info from a coredump (QNX) + */ +/* + 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 "_UCD_internal.h" + + +/** + * Access scalar CPU register from core file + * @param[in] as Pointer to unwind address space structure. + * @param[in] regnum Arch-specific index of register to access. + * @param[out] valp Pointer to value to write to to be read to. + * @param[in] write Direction of operation (1 == write, 0 == read register). + * @param[in] arg Arg passed through from back end (pointer to UCD_info). + * + * @returns 0 on success, <0 on error. + * + * Reads a value from an architecture-specific, OS-specific structure retrieved + * from the core file under analysis. + * + * This is the QNX-specific implementation. + */ +int +_UCD_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, + unw_word_t *valp, + int write, + void *arg) +{ + if (write) + { + Debug(0, "write is not supported\n"); + return -UNW_EINVAL; + } + + struct UCD_info *ui = arg; + +#if defined(UNW_TARGET_X86) + switch (regnum) { + case UNW_X86_EAX: + *valp = ui->prstatus->greg.x86.eax; + break; + case UNW_X86_EDX: + *valp = ui->prstatus->greg.x86.edx; + break; + case UNW_X86_ECX: + *valp = ui->prstatus->greg.x86.ecx; + break; + case UNW_X86_EBX: + *valp = ui->prstatus->greg.x86.ebx; + break; + case UNW_X86_ESI: + *valp = ui->prstatus->greg.x86.esi; + break; + case UNW_X86_EDI: + *valp = ui->prstatus->greg.x86.edi; + break; + case UNW_X86_EBP: + *valp = ui->prstatus->greg.x86.ebp; + break; + case UNW_X86_ESP: + *valp = ui->prstatus->greg.x86.esp; + break; + case UNW_X86_EIP: + *valp = ui->prstatus->greg.x86.eip; + break; + case UNW_X86_EFLAGS: + *valp = ui->prstatus->greg.x86.efl; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } +#elif defined(UNW_TARGET_X86_64) + switch (regnum) { + case UNW_X86_64_RAX: + *valp = ui->prstatus->greg.x86_64.rax; + break; + case UNW_X86_64_RDX: + *valp = ui->prstatus->greg.x86_64.rdx; + break; + case UNW_X86_64_RCX: + *valp = ui->prstatus->greg.x86_64.rcx; + break; + case UNW_X86_64_RBX: + *valp = ui->prstatus->greg.x86_64.rbx; + break; + case UNW_X86_64_RSI: + *valp = ui->prstatus->greg.x86_64.rsi; + break; + case UNW_X86_64_RDI: + *valp = ui->prstatus->greg.x86_64.rdi; + break; + case UNW_X86_64_RBP: + *valp = ui->prstatus->greg.x86_64.rbp; + break; + case UNW_X86_64_RSP: + *valp = ui->prstatus->greg.x86_64.rsp; + break; + case UNW_X86_64_RIP: + *valp = ui->prstatus->greg.x86_64.rip; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } +#elif defined(UNW_TARGET_ARM) + if (regnum >= UNW_ARM_R0 && regnum <= UNW_ARM_R16) { + *valp = ui->prstatus->greg.arm.gpr[regnum]; + } else { + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } +#elif defined(UNW_TARGET_AARCH64) + if (regnum >= UNW_AARCH64_X0 && regnum <= UNW_AARCH64_X30) { + *valp = ui->prstatus->greg.aarch64.gpr[regnum]; + } else { + switch (regnum) { + case UNW_AARCH64_SP: + *valp = ui->prstatus->greg.aarch64.gpr[AARCH64_REG_SP]; + break; + case UNW_AARCH64_PC: + *valp = ui->prstatus->greg.aarch64.elr; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } + } + +#else +#error Port me +#endif + + return 0; +} + diff --git a/src/native/external/libunwind/src/coredump/_UCD_accessors.c b/src/native/external/libunwind/src/coredump/_UCD_accessors.c index ae5c23d21940b9..6d4a0b5c20564c 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_accessors.c +++ b/src/native/external/libunwind/src/coredump/_UCD_accessors.c @@ -32,5 +32,6 @@ unw_accessors_t _UCD_accessors = .access_reg = _UCD_access_reg, .access_fpreg = _UCD_access_fpreg, .resume = _UCD_resume, - .get_proc_name = _UCD_get_proc_name + .get_proc_name = _UCD_get_proc_name, + .get_elf_filename = _UCD_get_elf_filename }; diff --git a/src/native/external/libunwind/src/coredump/_UCD_create.c b/src/native/external/libunwind/src/coredump/_UCD_create.c index 784d0462513905..0faf8f1e9615bc 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_create.c +++ b/src/native/external/libunwind/src/coredump/_UCD_create.c @@ -54,6 +54,8 @@ _UCD_create(const char *filename) #define elf_header64 elf_header.h64 bool _64bits; + mi_init (); + struct UCD_info *ui = memset(malloc(sizeof(*ui)), 0, sizeof(*ui)); ui->edi.di_cache.format = -1; ui->edi.di_debug.format = -1; @@ -242,7 +244,7 @@ void _UCD_select_thread(struct UCD_info *ui, int n) pid_t _UCD_get_pid(struct UCD_info *ui) { #if defined(HAVE_PROCFS_STATUS) - return ui->prstatus->pid; + return ui->prstatus->thread.pid; #else return ui->prstatus->pr_pid; #endif @@ -251,7 +253,7 @@ pid_t _UCD_get_pid(struct UCD_info *ui) int _UCD_get_cursig(struct UCD_info *ui) { #if defined(HAVE_PROCFS_STATUS) - return 0; + return ui->prstatus->thread.info.si_signo; #else return ui->prstatus->pr_cursig; #endif diff --git a/src/native/external/libunwind/src/coredump/_UCD_elf_map_image.c b/src/native/external/libunwind/src/coredump/_UCD_elf_map_image.c index ea36745a6a026a..4f2ff7d1a7c68f 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_elf_map_image.c +++ b/src/native/external/libunwind/src/coredump/_UCD_elf_map_image.c @@ -43,10 +43,10 @@ CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr) * these pages are allocated, but non-accessible. */ /* addr, length, prot, flags, fd, fd_offset */ - ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset); + ei->image = mi_mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset); if (ei->image == MAP_FAILED) { - Debug(0, "error %d in mmap(): %s\n", errno, strerror(errno)); + Debug(0, "error in mmap()\n"); ei->image = NULL; return NULL; } @@ -55,7 +55,7 @@ CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr) if (remainder_len > 0) { void *remainder_base = (char*) ei->image + phdr->p_filesz; - munmap(remainder_base, remainder_len); + mi_munmap(remainder_base, remainder_len); } } else { ucd_file_t *ucd_file = ucd_file_table_at(&ui->ucd_file_table, phdr->p_backing_file_index); @@ -76,7 +76,7 @@ CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr) /* Check ELF header for sanity */ if (!elf_w(valid_object)(ei)) { - munmap(ei->image, ei->size); + mi_munmap(ei->image, ei->size); ei->image = NULL; ei->size = 0; return NULL; diff --git a/src/native/external/libunwind/src/coredump/_UCD_get_elf_filename.c b/src/native/external/libunwind/src/coredump/_UCD_get_elf_filename.c new file mode 100644 index 00000000000000..31146c55a4091c --- /dev/null +++ b/src/native/external/libunwind/src/coredump/_UCD_get_elf_filename.c @@ -0,0 +1,122 @@ +/* + 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 "_UCD_lib.h" +#include "_UCD_internal.h" + +#if defined(HAVE_ELF_H) +# include +#elif defined(HAVE_SYS_ELF_H) +# include +#endif + +static off_t +_get_text_offset (uint8_t *image) +{ + off_t offset = 0; + typedef union + { + Elf32_Ehdr h32; + Elf64_Ehdr h64; + } elf_header_t; + + elf_header_t *elf_header = (elf_header_t *)image; + bool _64bits = (elf_header->h32.e_ident[EI_CLASS] == ELFCLASS64); + off_t e_phofs = _64bits ? elf_header->h64.e_phoff : elf_header->h32.e_phoff; + unsigned e_phnum = _64bits ? elf_header->h64.e_phnum : elf_header->h32.e_phnum; + + for (unsigned i = 0; i < e_phnum; ++i) + { + if (_64bits) + { + Elf64_Phdr *phdr = (Elf64_Phdr *) (image + e_phofs); + + if (phdr[i].p_type == PT_LOAD && (phdr[i].p_flags & PF_X) == PF_X) + { + offset = phdr[i].p_offset; + break; + } + } + else + { + Elf32_Phdr *phdr = (Elf32_Phdr *) (image + e_phofs); + + if ((phdr[i].p_flags & PF_X) == PF_X) + { + offset = phdr[i].p_offset; + break; + } + } + } + + Debug (4, "returning offset %ld\n", (long)offset); + return offset; +} + +static int +elf_w (CD_get_elf_filename) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + int ret = UNW_ESUCCESS; + + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ + coredump_phdr_t *cphdr = _UCD_get_elf_image (ui, ip); + if (!cphdr) + { + Debug (1, "returns error: _UCD_get_elf_image failed\n"); + return -UNW_ENOINFO; + } + + const ucd_file_t *ucd_file = ucd_file_table_at(&ui->ucd_file_table, cphdr->p_backing_file_index); + if (!ucd_file) + { + Debug (1, "backing_fie_index:%d ucd_file_table_at failed\n", cphdr->p_backing_file_index); + return -UNW_ENOINFO; + } + + if (buf) + { + strncpy(buf, ucd_file->filename, buf_len); + buf[buf_len - 1] = '\0'; + if (strlen(ucd_file->filename) >= buf_len) + ret = -UNW_ENOMEM; + } + + /* Adjust IP to be relative to start of the .text section of the ELF file */ + if (offp) + *offp = ip - cphdr->p_vaddr + _get_text_offset (ui->edi.ei.image); + + return ret; +} + +int +_UCD_get_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + struct UCD_info *ui = arg; +#if UNW_ELF_CLASS == UNW_ELFCLASS64 + return _Uelf64_CD_get_elf_filename (ui, as, ip, buf, buf_len, offp); +#elif UNW_ELF_CLASS == UNW_ELFCLASS32 + return _Uelf32_CD_get_elf_filename (ui, as, ip, buf, buf_len, offp); +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/native/external/libunwind/src/coredump/_UCD_get_mapinfo_linux.c b/src/native/external/libunwind/src/coredump/_UCD_get_mapinfo_linux.c index 0d04f01a86840a..1157ac14b9b495 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_get_mapinfo_linux.c +++ b/src/native/external/libunwind/src/coredump/_UCD_get_mapinfo_linux.c @@ -74,7 +74,7 @@ static const size_t mapinfo_offset = sizeof (core_nt_file_hdr_t); * various segments loaded into memory from ELF files with the ELF file from * which those segments were loaded. * - * This function links the file namess mapped in the CORE/NT_FILE note with + * This function links the file names mapped in the CORE/NT_FILE note with * the program headers in the core file through the UCD_info file table. * * Any file names that end in the string "(deleted)" are ignored. @@ -130,12 +130,12 @@ _handle_nt_file_note (uint8_t *desc, void *arg) * Note interpretation requires both name and type. */ static int -_handle_pt_note_segment (uint32_t n_namesz, - uint32_t n_descsz, - uint32_t n_type, - char *name, - uint8_t *desc, - void *arg) +_handle_pt_note_segment (uint32_t n_namesz UNUSED, + uint32_t n_descsz UNUSED, + uint32_t n_type, + char *name, + uint8_t *desc, + void *arg) { #ifdef NT_FILE if (n_type == NT_FILE && strcmp (name, "CORE") == 0) diff --git a/src/native/external/libunwind/src/coredump/_UCD_get_mapinfo_qnx.c b/src/native/external/libunwind/src/coredump/_UCD_get_mapinfo_qnx.c new file mode 100644 index 00000000000000..fce9ceced0d78c --- /dev/null +++ b/src/native/external/libunwind/src/coredump/_UCD_get_mapinfo_qnx.c @@ -0,0 +1,159 @@ +/** + * Extract filemap info from a coredump (QNX) + */ +/* + 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 "_UCD_internal.h" + +#include + + +#define MAP_PATH_MAX 512 + + +/** Number of bytes for rounding up addresses. */ +static inline const size_t _roundup(size_t size) +{ +#if UNW_ELF_CLASS == UNW_ELFCLASS32 + static const size_t _roundup_sz = 4; +#else + static const size_t _roundup_sz = 8; +#endif + return (((size) + ((_roundup_sz)-1)) & ~((_roundup_sz)-1)); +} + + +/** + * Handle the QNX/QNT_LINK_MAP note type. + * @param[in] desc The note-specific data + * @param[in] arg The user-supplied callback argument + * + * The QNX/QNT_LINK_MAP note type contains a list of start/end virtual addresses + * within the core file and an associated filename. The purpose is to map + * various segments loaded into memory from ELF files with the ELF file from + * which those segments were loaded. + * + * This function links the file names mapped in the QNX/QNT_LINK_MAP note with + * the program headers in the core file through the UCD_info file table. + */ +static int +_handle_nt_file_note (uint8_t *desc, void *arg) +{ + struct UCD_info *ui = (struct UCD_info *)arg; + struct qnx_linkmap_note* linkmap_note = (struct qnx_linkmap_note*)desc; + uintptr_t data = (uintptr_t)&linkmap_note->data[0]; + + const size_t r_debug_size = _roundup(sizeof(struct qnx_r_debug)); + const struct qnx_link_map* linkmap = (struct qnx_link_map*)(data + r_debug_size); + const size_t link_count = (linkmap_note->header.linkmapsz - r_debug_size) / sizeof(struct qnx_link_map); + const char *const strtab = (const char *const)(data + _roundup(linkmap_note->header.linkmapsz)); + + for (size_t i = 0; i < link_count; ++i) + { + const struct qnx_link_map *map = &linkmap[i]; + for (size_t p = 0; p < ui->phdrs_count; ++p) + { + coredump_phdr_t *phdr = &ui->phdrs[p]; + if (phdr->p_type == PT_LOAD + && linkmap[i].l_addr >= phdr->p_vaddr + && linkmap[i].l_addr < phdr->p_vaddr + phdr->p_memsz) + { + char libpath[MAP_PATH_MAX]; + if ((0 == strncmp(strtab + linkmap[i].l_name, "PIE", 3)) + || (0 == strncmp(strtab + linkmap[i].l_name, "EXE", 3))) + { + snprintf (libpath, MAP_PATH_MAX, "%s", strtab + map->l_path); + } + else + { + snprintf (libpath, MAP_PATH_MAX, "%s%s", strtab + map->l_path, strtab + map->l_name); + } + phdr->p_backing_file_index = ucd_file_table_insert (&ui->ucd_file_table, libpath); + Debug(2, "added '%s' at index %d for phdr %zu\n", libpath, phdr->p_backing_file_index, p); + break; + } + } + } + + return UNW_ESUCCESS; +} + + +/** + * Callback to handle notes. + * @param[in] n_namesz size of name data + * @param[in] n_descsz size of desc data + * @param[in] n_type type of note + * @param[in] name zero-terminated string, n_namesz bytes plus alignment padding + * @param[in] desc note-specific data, n_descsz bytes plus alignment padding + * @param[in] arg user-supplied callback argument + */ +static int +_handle_pt_note_segment (uint32_t n_namesz UNUSED, + uint32_t n_descsz UNUSED, + uint32_t n_type, + char *name, + uint8_t *desc, + void *arg) +{ + if ((strcmp(name, QNX_NOTE_NAME) == 0) && n_type == QNT_LINK_MAP) + { + return _handle_nt_file_note (desc, arg); + } + return UNW_ESUCCESS; +} + + +/** + * Get filemap info from core file (QNX) + * @param[in] ui + * @param[in] phdrs + * @param[in] phdr_size + * + * If there is a mapinfo note in the core file, map its contents to the phdrs. + * + * Since there may or may not be any mapinfo notes it's OK for this function to + * fail. + */ +int +_UCD_get_mapinfo (struct UCD_info *ui, coredump_phdr_t *phdrs, unsigned phdr_size) +{ + int ret = UNW_ESUCCESS; /* it's OK if there are no file mappings */ + + for (unsigned i = 0; i < phdr_size; ++i) + { + if (phdrs[i].p_type == PT_NOTE) + { + uint8_t *segment; + size_t segment_size; + ret = _UCD_elf_read_segment (ui, &phdrs[i], &segment, &segment_size); + + if (ret == UNW_ESUCCESS) + { + _UCD_elf_visit_notes (segment, segment_size, _handle_pt_note_segment, ui); + free (segment); + } + } + } + + return ret; +} diff --git a/src/native/external/libunwind/src/coredump/_UCD_get_proc_name.c b/src/native/external/libunwind/src/coredump/_UCD_get_proc_name.c index cff587b0d1a331..f5d544e5620288 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_get_proc_name.c +++ b/src/native/external/libunwind/src/coredump/_UCD_get_proc_name.c @@ -84,8 +84,9 @@ static int elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp) { - unsigned long segbase, mapoff; + unsigned long segbase; int ret; + /* We're about to map an elf image. The call will unmap memory it doesn't own, so just null it out and avoid that. */ @@ -104,6 +105,26 @@ elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t i /* Adjust IP to be relative to start of the .text section of the ELF file */ ip = ip - cphdr->p_vaddr + _get_text_offset (ui->edi.ei.image); ret = elf_w (get_proc_name_in_image) (as, &ui->edi.ei, segbase, ip, buf, buf_len, offp); + if (ret == -UNW_ENOINFO) + { + /* maybe symtab is stripped, try debuglink */ + ucd_file_t *ucd_file = ucd_file_table_at(&ui->ucd_file_table, cphdr->p_backing_file_index); + if (ucd_file) + { + struct elf_image ei = {NULL, 0}; + ret = elf_w (load_debuginfo) (ucd_file->filename, &ei, 1); + if (ret == 0) + { + ret = elf_w (get_proc_name_in_image) (as, &ei, segbase, ip, buf, buf_len, offp); + mi_munmap(ei.image, ei.size); + ei.image = NULL; + } + else + { + ret = -UNW_ENOINFO; + } + } + } return ret; } diff --git a/src/native/external/libunwind/src/coredump/_UCD_get_threadinfo_prstatus.c b/src/native/external/libunwind/src/coredump/_UCD_get_threadinfo_prstatus.c index 4644d1b1b6f8dc..c5927d9cf4026f 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_get_threadinfo_prstatus.c +++ b/src/native/external/libunwind/src/coredump/_UCD_get_threadinfo_prstatus.c @@ -1,19 +1,19 @@ /** - * Extract threadinfo from a coredump (targets with NT_PRSTATUS) + * Extract threadinfo from a coredump (supported targets) */ /* 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 @@ -35,13 +35,22 @@ * Accumulate a count of the number of thread notes * * This _UCD_elf_visit_notes() callback just increments a count for each - * NT_PRSTATUS note seen. + * thread status note seen. */ static int -_count_thread_notes(uint32_t n_namesz, uint32_t n_descsz, uint32_t n_type, char *name, uint8_t *desc, void *arg) +_count_thread_notes(uint32_t n_namesz UNUSED, + uint32_t n_descsz UNUSED, + uint32_t n_type, + char *name UNUSED, + uint8_t *desc UNUSED, + void *arg) { size_t *thread_count = (size_t *)arg; +#if defined(HAVE_PROCFS_STATUS) + if (0 == strcmp(name, QNX_NOTE_NAME) && n_type == QNT_CORE_STATUS) +#else if (n_type == NT_PRSTATUS) +#endif /* defined(HAVE_PROCFS_STATUS) */ { ++*thread_count; } @@ -52,25 +61,55 @@ _count_thread_notes(uint32_t n_namesz, uint32_t n_descsz, uint32_t n_type, char /** * Save a thread note to the unwind-coredump context * - * This _UCD_elf_visit_notes() callback just copies the actual data structure - * from any NT_PRSTATUS note seen into an array of such structures and - * increments the count. + * This _UCD_elf_visit_notes() callback just copies the actual data structure(s) + * from any notes seen into an array of such structures and increments the count. + * + * Some targets have multiple notes for each thread that MUST always come in the + * right order (eg. NT_PRSTATUS followed by NT_FPREGSET for Linux and the BSDs). + * The count only gets incremented on the first note for the thread so the + * remaining notes need to have their zero-based index adjusted. */ static int -_save_thread_notes(uint32_t n_namesz, uint32_t n_descsz, uint32_t n_type, char *name, uint8_t *desc, void *arg) +_save_thread_notes(uint32_t n_namesz UNUSED, + uint32_t n_descsz UNUSED, + uint32_t n_type, + char *name UNUSED, + uint8_t *desc, + void *arg) { struct UCD_info *ui = (struct UCD_info *)arg; +#if defined(HAVE_PROCFS_STATUS) + if (0 == strcmp(name, QNX_NOTE_NAME)) + { + switch (n_type) + { + case QNT_CORE_STATUS: + ++ui->n_threads; + memcpy(&ui->threads[ui->n_threads-1].prstatus.thread, desc, (size_t)n_descsz); + break; + case QNT_CORE_GREG: + memcpy(&ui->threads[ui->n_threads-1].prstatus.greg, desc, (size_t)n_descsz); + break; + case QNT_CORE_FPREG: + memcpy(&ui->threads[ui->n_threads-1].prstatus.fpreg, desc, (size_t)n_descsz); + break; + default: + break; + } + } +#else if (n_type == NT_PRSTATUS) - { - memcpy(&ui->threads[ui->n_threads].prstatus, desc, sizeof(UCD_proc_status_t)); - ++ui->n_threads; - } - if (n_type == NT_FPREGSET) - { + { + memcpy(&ui->threads[ui->n_threads].prstatus, desc, sizeof(UCD_proc_status_t)); + ++ui->n_threads; + } +#endif #ifdef HAVE_ELF_FPREGSET_T - memcpy(&ui->threads[ui->n_threads-1].fpregset, desc, sizeof(elf_fpregset_t)); + if (n_type == NT_FPREGSET) + { + memcpy(&ui->threads[ui->n_threads-1].fpregset, desc, sizeof(elf_fpregset_t)); + } #endif - } return UNW_ESUCCESS; } @@ -82,7 +121,7 @@ _save_thread_notes(uint32_t n_namesz, uint32_t n_descsz, uint32_t n_type, char * * and the process information is described by a note in the core file of type * NT_PRSTATUS. In fact, on Linux, the state of a thread is described by a * CPU-dependent group of notes but right now we're only going to care about the - * one process-status note. This statement is also true for FreeBSD. + * one process-status note. This statement is also true for the BSDs. * * Depending on how the core file is created, there may be one PT_NOTE segment * with multiple NT_PRSTATUS notes in it, or multiple PT_NOTE segments. Just to diff --git a/src/native/external/libunwind/src/coredump/_UCD_internal.h b/src/native/external/libunwind/src/coredump/_UCD_internal.h index 3a9434ab0244ba..e5dc89edf118df 100644 --- a/src/native/external/libunwind/src/coredump/_UCD_internal.h +++ b/src/native/external/libunwind/src/coredump/_UCD_internal.h @@ -80,7 +80,11 @@ typedef struct elf_prstatus UCD_proc_status_t; #elif defined(HAVE_STRUCT_PRSTATUS) typedef struct prstatus UCD_proc_status_t; #elif defined(HAVE_PROCFS_STATUS) -typedef procfs_status UCD_proc_status_t; +typedef struct { + procfs_status thread; + procfs_greg greg; + procfs_fpreg fpreg; +} UCD_proc_status_t; #else # error UCD_proc_status_t undefined #endif diff --git a/src/native/external/libunwind/src/coredump/_UPT_access_fpreg.c b/src/native/external/libunwind/src/coredump/_UPT_access_fpreg.c index a6d0bcea437694..be8dcffa13a0e3 100644 --- a/src/native/external/libunwind/src/coredump/_UPT_access_fpreg.c +++ b/src/native/external/libunwind/src/coredump/_UPT_access_fpreg.c @@ -25,8 +25,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UCD_internal.h" int -_UCD_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) +_UCD_access_fpreg (unw_addr_space_t as UNUSED, + unw_regnum_t reg UNUSED, + unw_fpreg_t *val UNUSED, + int write, + void *arg) { struct UCD_info *ui UNUSED = arg; diff --git a/src/native/external/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/native/external/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c index 7548d63320f337..fd5c776983aaa8 100644 --- a/src/native/external/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c +++ b/src/native/external/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c @@ -79,8 +79,10 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, DWARF2 unwind info. */ static inline int -get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, - int *countp) +get_list_addr (unw_addr_space_t as UNUSED, + unw_word_t *dil_addr UNUSED, + void *arg UNUSED, + int *countp) { # warning Implement get_list_addr(), please. *countp = 0; diff --git a/src/native/external/libunwind/src/coredump/_UPT_put_unwind_info.c b/src/native/external/libunwind/src/coredump/_UPT_put_unwind_info.c index 462e1d048c3906..06d3bf44cf5268 100644 --- a/src/native/external/libunwind/src/coredump/_UPT_put_unwind_info.c +++ b/src/native/external/libunwind/src/coredump/_UPT_put_unwind_info.c @@ -27,7 +27,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UCD_internal.h" void -_UCD_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +_UCD_put_unwind_info (unw_addr_space_t as UNUSED, + unw_proc_info_t *pi, + void *arg UNUSED) { if (!pi->unwind_info) return; diff --git a/src/native/external/libunwind/src/coredump/_UPT_resume.c b/src/native/external/libunwind/src/coredump/_UPT_resume.c index a729c908cb123e..78cd6151eb2edb 100644 --- a/src/native/external/libunwind/src/coredump/_UPT_resume.c +++ b/src/native/external/libunwind/src/coredump/_UPT_resume.c @@ -27,7 +27,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UCD_internal.h" int -_UCD_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) +_UCD_resume (unw_addr_space_t as UNUSED, + unw_cursor_t *c UNUSED, + void *arg UNUSED) { print_error (__func__); print_error (" not implemented\n"); diff --git a/src/native/external/libunwind/src/coredump/ucd_file_table.c b/src/native/external/libunwind/src/coredump/ucd_file_table.c index cde693db58aa76..2a7294f219110d 100644 --- a/src/native/external/libunwind/src/coredump/ucd_file_table.c +++ b/src/native/external/libunwind/src/coredump/ucd_file_table.c @@ -93,6 +93,7 @@ _ucd_file_open (ucd_file_t *ucd_file) if (ucd_file->fd == -1) { Debug(0, "error %d in open(%s): %s\n", errno, ucd_file->filename, strerror(errno)); + return; } struct stat sbuf; @@ -115,7 +116,6 @@ ucd_file_map (ucd_file_t *ucd_file) { if (ucd_file->image != NULL) { - Debug(0, "warning, file \"%s\" already loaded\n", ucd_file->filename); return ucd_file->image; } @@ -124,10 +124,10 @@ ucd_file_map (ucd_file_t *ucd_file) _ucd_file_open (ucd_file); } - ucd_file->image = mmap(NULL, ucd_file->size, PROT_READ, MAP_PRIVATE, ucd_file->fd, 0); + ucd_file->image = mi_mmap(NULL, ucd_file->size, PROT_READ, MAP_PRIVATE, ucd_file->fd, 0); if (ucd_file->image == MAP_FAILED) { - Debug(0, "error %d in mmap(%s): %s\n", errno, ucd_file->filename, strerror(errno)); + Debug(0, "error in mmap(%s)\n", ucd_file->filename); ucd_file->image = NULL; return NULL; } diff --git a/src/native/external/libunwind/src/dl-iterate-phdr.c b/src/native/external/libunwind/src/dl-iterate-phdr.c index b14b765d9bf4e5..5c738a9ebc1c57 100644 --- a/src/native/external/libunwind/src/dl-iterate-phdr.c +++ b/src/native/external/libunwind/src/dl-iterate-phdr.c @@ -39,17 +39,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ (ehdr).e_ident[EI_MAG3] == ELFMAG3) #endif -typedef int (*unw_iterate_phdr_impl) (int (*callback) ( - struct dl_phdr_info *info, - size_t size, void *data), - void *data); - HIDDEN int -dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), +dl_iterate_phdr (unw_iterate_phdr_callback_t callback, void *data) { static int initialized = 0; - static unw_iterate_phdr_impl libc_impl; + static unw_iterate_phdr_func_t libc_impl; int rc = 0; struct map_iterator mi; unsigned long start, end, offset, flags; diff --git a/src/native/external/libunwind/src/dwarf/Gexpr.c b/src/native/external/libunwind/src/dwarf/Gexpr.c index 882f4dac9642b2..4a8da2ce1bb3d2 100644 --- a/src/native/external/libunwind/src/dwarf/Gexpr.c +++ b/src/native/external/libunwind/src/dwarf/Gexpr.c @@ -110,7 +110,7 @@ static const uint8_t operands[256] = }; static inline unw_sword_t -sword (unw_addr_space_t as, unw_word_t val) +sword (unw_addr_space_t as UNUSED, unw_word_t val) { switch (dwarf_addr_size (as)) { diff --git a/src/native/external/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/src/native/external/libunwind/src/dwarf/Gfind_proc_info-lsb.c index 8ead48f096fdd6..c11345e88383f2 100644 --- a/src/native/external/libunwind/src/dwarf/Gfind_proc_info-lsb.c +++ b/src/native/external/libunwind/src/dwarf/Gfind_proc_info-lsb.c @@ -120,7 +120,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, ei.image = NULL; *load_offset = 0; - ret = elf_w (load_debuglink) (file, &ei, is_local); + ret = elf_w (load_debuginfo) (file, &ei, is_local); if (ret != 0) return ret; @@ -128,7 +128,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, if (!shdr || (shdr->sh_offset + shdr->sh_size > ei.size)) { - munmap(ei.image, ei.size); + mi_munmap(ei.image, ei.size); return 1; } @@ -146,7 +146,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, if (!*buf) { Debug (2, "failed to allocate zlib .debug_frame buffer, skipping\n"); - munmap(ei.image, ei.size); + mi_munmap(ei.image, ei.size); return 1; } @@ -156,8 +156,8 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, if (ret != Z_OK) { Debug (2, "failed to decompress zlib .debug_frame, skipping\n"); - munmap(*buf, *bufsize); - munmap(ei.image, ei.size); + mi_munmap(*buf, *bufsize); + mi_munmap(ei.image, ei.size); return 1; } @@ -169,7 +169,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, { Debug (2, "unknown compression type %d, skipping\n", chdr->ch_type); - munmap(ei.image, ei.size); + mi_munmap(ei.image, ei.size); return 1; } } @@ -182,7 +182,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, if (!*buf) { Debug (2, "failed to allocate .debug_frame buffer, skipping\n"); - munmap(ei.image, ei.size); + mi_munmap(ei.image, ei.size); return 1; } @@ -207,7 +207,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, break; } - munmap(ei.image, ei.size); + mi_munmap(ei.image, ei.size); return 0; } @@ -549,7 +549,7 @@ dwarf_find_eh_frame_section(struct dl_phdr_info *info) eh_frame); out: - munmap (ei.image, ei.size); + mi_munmap (ei.image, ei.size); return eh_frame; } @@ -804,7 +804,7 @@ dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, cb_data.di_debug.format = -1; SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (dwarf_callback, &cb_data); + ret = as->iterate_phdr_function (dwarf_callback, &cb_data); SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); if (ret > 0) @@ -966,7 +966,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, if (as == unw_local_addr_space) { e = lookup (table, table_len, ip - ip_base - di->load_offset); - if (e && &e[1] < &table[table_len / sizeof (unw_word_t)]) + if (e && &e[1] < &table[table_len / sizeof (struct table_entry)]) last_ip = e[1].start_ip_offset + ip_base + di->load_offset; else last_ip = di->end_ip; @@ -1037,7 +1037,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, } HIDDEN void -dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +dwarf_put_unwind_info (unw_addr_space_t as UNUSED, unw_proc_info_t *pi UNUSED, void *arg UNUSED) { return; /* always a nop */ } diff --git a/src/native/external/libunwind/src/dwarf/Gfind_unwind_table.c b/src/native/external/libunwind/src/dwarf/Gfind_unwind_table.c index fb20fea0da449c..a7c4dfd3725887 100644 --- a/src/native/external/libunwind/src/dwarf/Gfind_unwind_table.c +++ b/src/native/external/libunwind/src/dwarf/Gfind_unwind_table.c @@ -36,12 +36,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define to_unw_word(p) ((unw_word_t) (uintptr_t) (p)) int -dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - const char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip) +dwarf_find_unwind_table (struct elf_dyn_info *edi, + unw_addr_space_t as UNUSED, + const char *path UNUSED, + unw_word_t segbase, + unw_word_t mapoff, + unw_word_t ip UNUSED) { Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; - unw_word_t addr, eh_frame_start, fde_count, load_base; + unw_word_t addr, eh_frame_start, fde_count, loadoff, load_base; unw_word_t max_load_addr = 0; unw_word_t start_ip = to_unw_word (-1); unw_word_t end_ip = 0; @@ -104,7 +107,8 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, if (!ptxt) return 0; - load_base = segbase - ptxt->p_vaddr; + loadoff = mapoff + (ptxt->p_vaddr - ptxt->p_offset); + load_base = segbase - loadoff; start_ip += load_base; end_ip += load_base; diff --git a/src/native/external/libunwind/src/dwarf/Gget_proc_info_in_range.c b/src/native/external/libunwind/src/dwarf/Gget_proc_info_in_range.c index b9a369ba0626a2..5701c5d2d4ddf4 100644 --- a/src/native/external/libunwind/src/dwarf/Gget_proc_info_in_range.c +++ b/src/native/external/libunwind/src/dwarf/Gget_proc_info_in_range.c @@ -24,12 +24,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf_i.h" int -unw_get_proc_info_in_range (unw_word_t start_ip, unw_word_t end_ip, - unw_word_t eh_frame_table, unw_word_t eh_frame_table_len, - unw_word_t exidx_frame_table, unw_word_t exidx_frame_table_len, - unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, - void *arg) +unw_get_proc_info_in_range (unw_word_t start_ip, + unw_word_t end_ip, + unw_word_t eh_frame_table, + unw_word_t eh_frame_table_len UNUSED, + unw_word_t exidx_frame_table UNUSED, + unw_word_t exidx_frame_table_len UNUSED, + unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, + void *arg) { int ret = 0; @@ -53,11 +58,10 @@ unw_get_proc_info_in_range (unw_word_t start_ip, unw_word_t end_ip, if (eh_frame_table != 0) { unw_accessors_t *a = unw_get_accessors_int (as); - unw_word_t hdr; - if ((*a->access_mem)(as, eh_frame_table, &hdr, 0, arg) < 0) { + struct dwarf_eh_frame_hdr* exhdr = NULL; + if ((*a->access_mem)(as, eh_frame_table, (unw_word_t*)&exhdr, 0, arg) < 0) { return -UNW_EINVAL; } - struct dwarf_eh_frame_hdr* exhdr = (struct dwarf_eh_frame_hdr*)&hdr; if (exhdr->version != DW_EH_VERSION) { Debug (1, "Unexpected version %d\n", exhdr->version); diff --git a/src/native/external/libunwind/src/dwarf/Gparser.c b/src/native/external/libunwind/src/dwarf/Gparser.c index b7f83ca2dad597..7a5d7e1f0ff344 100644 --- a/src/native/external/libunwind/src/dwarf/Gparser.c +++ b/src/native/external/libunwind/src/dwarf/Gparser.c @@ -490,7 +490,9 @@ fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip) } static int -parse_dynamic (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) +parse_dynamic (struct dwarf_cursor *c UNUSED, + unw_word_t ip UNUSED, + dwarf_state_record_t *sr UNUSED) { Debug (1, "Not yet implemented\n"); return -UNW_ENOINFO; @@ -520,8 +522,10 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) set_reg (sr, i, DWARF_WHERE_SAME, 0); +#if !defined(UNW_TARGET_ARM) && !(defined(UNW_TARGET_MIPS) && _MIPS_SIM == _ABI64) // SP defaults to CFA (but is overridable) set_reg (sr, TDEP_DWARF_SP, DWARF_WHERE_CFA, 0); +#endif struct dwarf_cie_info *dci = c->pi.unwind_info; sr->rs_current.ret_addr_column = dci->ret_addr_column; @@ -571,14 +575,14 @@ dwarf_flush_rs_cache (struct dwarf_rs_cache *cache) cache->log_size = DWARF_DEFAULT_LOG_UNW_CACHE_SIZE; } else { if (cache->hash && cache->hash != cache->default_hash) - munmap(cache->hash, DWARF_UNW_HASH_SIZE(cache->prev_log_size) - * sizeof (cache->hash[0])); + mi_munmap(cache->hash, DWARF_UNW_HASH_SIZE(cache->prev_log_size) + * sizeof (cache->hash[0])); if (cache->buckets && cache->buckets != cache->default_buckets) - munmap(cache->buckets, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) - * sizeof (cache->buckets[0])); + mi_munmap(cache->buckets, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) + * sizeof (cache->buckets[0])); if (cache->links && cache->links != cache->default_links) - munmap(cache->links, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) - * sizeof (cache->links[0])); + mi_munmap(cache->links, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) + * sizeof (cache->links[0])); GET_MEMORY(cache->hash, DWARF_UNW_HASH_SIZE(cache->log_size) * sizeof (cache->hash[0])); GET_MEMORY(cache->buckets, DWARF_UNW_CACHE_SIZE(cache->log_size) @@ -961,7 +965,6 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) if (DWARF_IS_NULL_LOC (c->loc[rs->ret_addr_column])) { c->ip = 0; - ret = 0; } else { @@ -982,8 +985,8 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) } #endif c->ip = ip; - ret = 1; } + ret = (c->ip != 0) ? 1 : 0; /* XXX: check for ip to be code_aligned */ if (c->ip == prev_ip && c->cfa == prev_cfa) @@ -1095,9 +1098,9 @@ dwarf_make_proc_info (struct dwarf_cursor *c) } static int -dwarf_reg_states_dynamic_iterate(struct dwarf_cursor *c, - unw_reg_states_callback cb, - void *token) +dwarf_reg_states_dynamic_iterate(struct dwarf_cursor *c UNUSED, + unw_reg_states_callback cb UNUSED, + void *token UNUSED) { Debug (1, "Not yet implemented\n"); return -UNW_ENOINFO; diff --git a/src/native/external/libunwind/src/elfxx.c b/src/native/external/libunwind/src/elfxx.c index 92bcde32cdb31d..e7b2d561f49f98 100644 --- a/src/native/external/libunwind/src/elfxx.c +++ b/src/native/external/libunwind/src/elfxx.c @@ -30,12 +30,40 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#ifdef HAVE_LZMA +#if HAVE_LZMA #include #endif /* HAVE_LZMA */ +struct symbol_info +{ + const char *strtab; + const Elf_W (Sym) *sym; + Elf_W (Addr) start_ip; +}; + +struct symbol_lookup_context +{ + unw_addr_space_t as; + unw_word_t ip; + struct elf_image *ei; + Elf_W (Addr) load_offset; + Elf_W (Addr) *min_dist; +}; + +struct symbol_callback_data +{ + char *buf; + size_t buf_len; +}; + +struct ip_range_callback_data +{ + Elf_W (Addr) *start_ip; + Elf_W (Addr) *end_ip; +}; + static Elf_W (Shdr)* -elf_w (section_table) (struct elf_image *ei) +elf_w (section_table) (const struct elf_image *ei) { Elf_W (Ehdr) *ehdr = ei->image; Elf_W (Off) soff; @@ -53,7 +81,7 @@ elf_w (section_table) (struct elf_image *ei) } static char* -elf_w (string_table) (struct elf_image *ei, int section) +elf_w (string_table) (const struct elf_image *ei, int section) { Elf_W (Ehdr) *ehdr = ei->image; Elf_W (Off) soff, str_soff; @@ -85,11 +113,127 @@ elf_w (string_table) (struct elf_image *ei, int section) } static int -elf_w (lookup_symbol) (unw_addr_space_t as, - unw_word_t ip, struct elf_image *ei, - Elf_W (Addr) load_offset, - char *buf, size_t buf_len, Elf_W (Addr) *min_dist) +elf_w (lookup_symbol_from_dynamic) (unw_addr_space_t as UNUSED, + const struct symbol_lookup_context *context, + int (*callback)(const struct symbol_lookup_context *context, + const struct symbol_info *syminfo, void *data), + void *data) + +{ + struct elf_image *ei = context->ei; + Elf_W (Addr) load_offset = context->load_offset; + Elf_W (Addr) file_offset = 0; + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Sym) *sym = NULL, *symtab = NULL; + Elf_W (Phdr) *phdr; + Elf_W (Word) sym_num; + Elf_W (Word) *hash = NULL, *gnu_hash = NULL; + Elf_W (Addr) val; + const char *strtab = NULL; + int ret = -UNW_ENOINFO; + size_t i; + Elf_W(Dyn) *dyn = NULL; + + phdr = (Elf_W (Phdr) *) ((char *) ei->image + ehdr->e_phoff); + for (i = 0; i < ehdr->e_phnum; ++i) + if (phdr[i].p_type == PT_PHDR) + { + file_offset = phdr[i].p_vaddr - phdr[i].p_offset; + } + else if (phdr[i].p_type == PT_DYNAMIC) + { + dyn = (Elf_W (Dyn) *) ((char *)ei->image + phdr[i].p_offset); + break; + } + + if (!dyn) + return -UNW_ENOINFO; + + for (; dyn->d_tag != DT_NULL; ++dyn) + { + switch (dyn->d_tag) + { + case DT_SYMTAB: + symtab = (Elf_W (Sym) *) ((char *) ei->image + dyn->d_un.d_ptr - file_offset); + break; + case DT_STRTAB: + strtab = (const char *) ((char *) ei->image + dyn->d_un.d_ptr - file_offset); + break; + case DT_HASH: + hash = (Elf_W (Word) *) ((char *) ei->image + dyn->d_un.d_ptr - file_offset); + break; + case DT_GNU_HASH: + gnu_hash = (Elf_W (Word) *) ((char *) ei->image + dyn->d_un.d_ptr - file_offset); + break; + default: + break; + } + } + + if (!symtab || !strtab || (!hash && !gnu_hash)) + return -UNW_ENOINFO; + + if (gnu_hash) + { + uint32_t *buckets = gnu_hash + 4 + (gnu_hash[2] * sizeof(size_t)/4); + uint32_t *hashval; + for (i = sym_num = 0; i < gnu_hash[0]; i++) + if (buckets[i] > sym_num) + sym_num = buckets[i]; + + if (sym_num) + { + hashval = buckets + gnu_hash[0] + (sym_num - gnu_hash[1]); + do sym_num++; + while (!(*hashval++ & 1)); + } + } + else + { + sym_num = hash[1]; + } + + for (i = 0; i < sym_num; ++i) + { + sym = &symtab[i]; + if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC + && sym->st_shndx != SHN_UNDEF) + { + val = sym->st_value; + if (sym->st_shndx != SHN_ABS) + val += load_offset; + if (tdep_get_func_addr (as, val, &val) < 0) + continue; + Debug (16, "0x%016lx info=0x%02x %s\n", + (long) val, sym->st_info, strtab + sym->st_name); + + /* as long as found one, the return will be success*/ + struct symbol_info syminfo = + { + .strtab = strtab, + .sym = sym, + .start_ip = val + }; + if ((*callback) (context, &syminfo, data) == UNW_ESUCCESS) + { + if (ret != UNW_ESUCCESS) + ret = UNW_ESUCCESS; + } + } + } + + return ret; +} + +static int +elf_w (lookup_symbol_closeness) (unw_addr_space_t as UNUSED, + const struct symbol_lookup_context *context, + int (*callback)(const struct symbol_lookup_context *context, + const struct symbol_info *syminfo, void *data), + void *data) { + struct elf_image *ei = context->ei; + Elf_W (Addr) load_offset = context->load_offset; size_t syment_size; Elf_W (Ehdr) *ehdr = ei->image; Elf_W (Sym) *sym, *symtab, *symtab_end; @@ -137,13 +281,17 @@ elf_w (lookup_symbol) (unw_addr_space_t as, Debug (16, "0x%016lx info=0x%02x %s\n", (long) val, sym->st_info, strtab + sym->st_name); - if ((Elf_W (Addr)) (ip - val) < *min_dist) + /* as long as found one, the return will be success*/ + struct symbol_info syminfo = { - *min_dist = (Elf_W (Addr)) (ip - val); - strncpy (buf, strtab + sym->st_name, buf_len); - buf[buf_len - 1] = '\0'; - ret = (strlen (strtab + sym->st_name) >= buf_len - ? -UNW_ENOMEM : 0); + .strtab = strtab, + .sym = sym, + .start_ip = val + }; + if ((*callback) (context, &syminfo, data) == UNW_ESUCCESS) + { + if (ret != UNW_ESUCCESS) + ret = UNW_ESUCCESS; } } } @@ -154,9 +302,110 @@ elf_w (lookup_symbol) (unw_addr_space_t as, } shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); } + + if (ret != UNW_ESUCCESS) + ret = elf_w (lookup_symbol_from_dynamic) (as, context, callback, data); + + return ret; +} + +static int +elf_w (lookup_symbol_callback)(const struct symbol_lookup_context *context, + const struct symbol_info *syminfo, void *data) +{ + int ret = -UNW_ENOINFO; + struct symbol_callback_data *d = data; + + if (context->ip < syminfo->start_ip || + context->ip >= (syminfo->start_ip + syminfo->sym->st_size)) + return -UNW_ENOINFO; + + if ((Elf_W (Addr)) (context->ip - syminfo->start_ip) < *(context->min_dist)) + { + *(context->min_dist) = (Elf_W (Addr)) (context->ip - syminfo->start_ip); + Debug (1, "candidate sym: %s@0x%lx\n", syminfo->strtab + syminfo->sym->st_name, syminfo->start_ip); + strncpy (d->buf, syminfo->strtab + syminfo->sym->st_name, d->buf_len); + d->buf[d->buf_len - 1] = '\0'; + ret = (strlen (syminfo->strtab + syminfo->sym->st_name) >= d->buf_len + ? -UNW_ENOMEM : UNW_ESUCCESS); + } + + return ret; +} + +static int +elf_w (lookup_symbol) (unw_addr_space_t as, + unw_word_t ip, struct elf_image *ei, + Elf_W (Addr) load_offset, + char *buf, size_t buf_len, Elf_W (Addr) *min_dist) +{ + struct symbol_lookup_context context = + { + .as = as, + .ip = ip, + .ei = ei, + .load_offset = load_offset, + .min_dist = min_dist, + }; + struct symbol_callback_data data = + { + .buf = buf, + .buf_len = buf_len, + }; + return elf_w (lookup_symbol_closeness) (as, + &context, + elf_w (lookup_symbol_callback), + &data); +} + +static int +elf_w (lookup_ip_range_callback)(const struct symbol_lookup_context *context, + const struct symbol_info *syminfo, void *data) +{ + int ret = -UNW_ENOINFO; + struct ip_range_callback_data *d = data; + + if (context->ip < syminfo->start_ip || + context->ip >= (syminfo->start_ip + syminfo->sym->st_size)) + return -UNW_ENOINFO; + + if ((Elf_W (Addr)) (context->ip - syminfo->start_ip) < *(context->min_dist)) + { + *(context->min_dist) = (Elf_W (Addr)) (context->ip - syminfo->start_ip); + *(d->start_ip) = syminfo->start_ip; + *(d->end_ip) = syminfo->start_ip + syminfo->sym->st_size; + + ret = UNW_ESUCCESS; + } + return ret; } +static int +elf_w (lookup_ip_range)(unw_addr_space_t as, + unw_word_t ip, struct elf_image *ei, + Elf_W (Addr) load_offset, Elf_W (Addr) *start_ip, + Elf_W (Addr) *end_ip, Elf_W (Addr) *min_dist) +{ + struct symbol_lookup_context context = + { + .as = as, + .ip = ip, + .ei = ei, + .load_offset = load_offset, + .min_dist = min_dist + }; + struct ip_range_callback_data data = + { + .start_ip = start_ip, + .end_ip = end_ip + }; + return elf_w (lookup_symbol_closeness) (as, + &context, + elf_w (lookup_ip_range_callback), + &data); +} + static Elf_W (Addr) elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase) { @@ -168,7 +417,7 @@ elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase) // PT_LOAD program headers p_offset however is not guaranteed to be aligned on a // page size, ld.lld generate libraries where this is not the case. So we must // make sure we compare both values with the same alignment. - unsigned long pagesize_alignment_mask = ~(((unsigned long)getpagesize()) - 1UL); + unsigned long pagesize_alignment_mask = ~(unw_page_size - 1UL); ehdr = ei->image; phdr = (Elf_W (Phdr) *) ((char *) ei->image + ehdr->e_phoff); @@ -184,8 +433,62 @@ elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase) } #if HAVE_LZMA + +#define XZ_MAX_ALLOCS 16 +struct xz_allocator_data { + struct { + void *ptr; + size_t size; + } allocations[XZ_MAX_ALLOCS]; + uint8_t n_allocs; +}; + +static void* +xz_alloc (void *opaque, size_t nmemb, size_t size) +{ + struct xz_allocator_data *data = opaque; + if (XZ_MAX_ALLOCS == data->n_allocs) + return NULL; + size = UNW_ALIGN(size * nmemb, unw_page_size); + void *ptr; + GET_MEMORY (ptr, size); + if (!ptr) return ptr; + data->allocations[data->n_allocs].ptr = ptr; + data->allocations[data->n_allocs].size = size; + ++data->n_allocs; + return ptr; +} + +static void +xz_free (void *opaque, void *ptr) +{ + struct xz_allocator_data *data = opaque; + for (uint8_t i = data->n_allocs; i-- > 0;) + { + if (data->allocations[i].ptr == ptr) + { + mi_munmap (ptr, data->allocations[i].size); + --data->n_allocs; + if (i != data->n_allocs) + { + data->allocations[i] = data->allocations[data->n_allocs]; + } + return; + } + } +} + +static void +xz_free_all (struct xz_allocator_data *data) +{ + while (data->n_allocs-- > 0) + { + mi_munmap (data->allocations[data->n_allocs].ptr, data->allocations[data->n_allocs].size); + } +} + static size_t -xz_uncompressed_size (uint8_t *compressed, size_t length) +xz_uncompressed_size (lzma_allocator *xz_allocator, uint8_t *compressed, size_t length) { uint64_t memlimit = UINT64_MAX; size_t ret = 0, pos = 0; @@ -203,7 +506,7 @@ xz_uncompressed_size (uint8_t *compressed, size_t length) return 0; uint8_t *indexdata = footer - options.backward_size; - if (lzma_index_buffer_decode (&index, &memlimit, NULL, indexdata, + if (lzma_index_buffer_decode (&index, &memlimit, xz_allocator, indexdata, &pos, options.backward_size) != LZMA_OK) return 0; @@ -212,7 +515,7 @@ xz_uncompressed_size (uint8_t *compressed, size_t length) ret = lzma_index_uncompressed_size (index); } - lzma_index_end (index, NULL); + lzma_index_end (index, xz_allocator); return ret; } @@ -224,6 +527,14 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) uint64_t memlimit = UINT64_MAX; /* no memory limit */ size_t compressed_len, uncompressed_len; + struct xz_allocator_data allocator_data; + lzma_allocator xz_allocator = + { + .alloc = xz_alloc, + .free = xz_free, + .opaque = &allocator_data + }; + shdr = elf_w (find_section) (ei, ".gnu_debugdata"); if (!shdr) return 0; @@ -231,29 +542,34 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) compressed = ((uint8_t *) ei->image) + shdr->sh_offset; compressed_len = shdr->sh_size; - uncompressed_len = xz_uncompressed_size (compressed, compressed_len); + uncompressed_len = xz_uncompressed_size (&xz_allocator, compressed, compressed_len); if (uncompressed_len == 0) { + xz_free_all (&allocator_data); Debug (1, "invalid .gnu_debugdata contents\n"); return 0; } mdi->size = uncompressed_len; - mdi->image = mmap (NULL, uncompressed_len, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + GET_MEMORY (mdi->image, uncompressed_len); - if (mdi->image == MAP_FAILED) - return 0; + if (!mdi->image) + { + xz_free_all (&allocator_data); + return 0; + } size_t in_pos = 0, out_pos = 0; lzma_ret lret; - lret = lzma_stream_buffer_decode (&memlimit, 0, NULL, + lret = lzma_stream_buffer_decode (&memlimit, 0, &xz_allocator, compressed, &in_pos, compressed_len, mdi->image, &out_pos, mdi->size); + xz_free_all (&allocator_data); + if (lret != LZMA_OK) { Debug (1, "LZMA decompression failed: %d\n", lret); - munmap (mdi->image, mdi->size); + mi_munmap (mdi->image, mdi->size); return 0; } @@ -261,7 +577,7 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) } #else static int -elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) +elf_w (extract_minidebuginfo) (struct elf_image *ei UNUSED, struct elf_image *mdi UNUSED) { return 0; } @@ -299,7 +615,7 @@ elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei, ret = ret_mdi; } - munmap (mdi.image, mdi.size); + mi_munmap (mdi.image, mdi.size); } if (min_dist >= ei->size) @@ -322,20 +638,97 @@ elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, if (ret < 0) return ret; - ret = elf_w (load_debuglink) (file, &ei, 1); + ret = elf_w (load_debuginfo) (file, &ei, 1); if (ret < 0) return ret; ret = elf_w (get_proc_name_in_image) (as, &ei, segbase, ip, buf, buf_len, offp); - munmap (ei.image, ei.size); + mi_munmap (ei.image, ei.size); + ei.image = NULL; + + return ret; +} + +HIDDEN int +elf_w (get_proc_ip_range_in_image) (unw_addr_space_t as, struct elf_image *ei, + unsigned long segbase, + unw_word_t ip, + unw_word_t *start, unw_word_t *end) +{ + Elf_W (Addr) load_offset; + Elf_W (Addr) min_dist = ~(Elf_W (Addr))0; + int ret; + + load_offset = elf_w (get_load_offset) (ei, segbase); + ret = elf_w (lookup_ip_range) (as, ip, ei, load_offset, start, end, &min_dist); + + /* If the ELF image has MiniDebugInfo embedded in it, look up the symbol in + there as well and replace the previously found if it is closer. */ + struct elf_image mdi; + if (elf_w (extract_minidebuginfo) (ei, &mdi)) + { + int ret_mdi = elf_w (lookup_ip_range) (as, ip, &mdi, load_offset, start, + end, &min_dist); + + /* Closer symbol was found (possibly truncated). */ + if (ret_mdi == 0 || ret_mdi == -UNW_ENOMEM) + { + ret = ret_mdi; + } + + mi_munmap (mdi.image, mdi.size); + } + + if (min_dist >= ei->size) + return -UNW_ENOINFO; /* not found */ + return ret; +} + +HIDDEN int +elf_w (get_proc_ip_range) (unw_addr_space_t as, pid_t pid, unw_word_t ip, + unw_word_t *start, unw_word_t *end) +{ + unsigned long segbase, mapoff; + struct elf_image ei; + int ret; + char file[PATH_MAX]; + + ret = tdep_get_elf_image (&ei, pid, ip, &segbase, &mapoff, file, PATH_MAX); + if (ret < 0) + return ret; + + ret = elf_w (load_debuginfo) (file, &ei, 1); + if (ret < 0) + return ret; + + ret = elf_w (get_proc_ip_range_in_image) (as, &ei, segbase, ip, start, end); + + mi_munmap (ei.image, ei.size); ei.image = NULL; return ret; } +HIDDEN int +elf_w (get_elf_filename) (unw_addr_space_t as, pid_t pid, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + unsigned long segbase, mapoff; + int ret = UNW_ESUCCESS; + + // use NULL to no map elf image + ret = tdep_get_elf_image (NULL, pid, ip, &segbase, &mapoff, buf, buf_len); + if (ret < 0) + return ret; + + if (offp) + *offp = ip - segbase + mapoff; + return ret; +} + HIDDEN Elf_W (Shdr)* -elf_w (find_section) (struct elf_image *ei, const char* secname) +elf_w (find_section) (const struct elf_image *ei, const char* secname) { Elf_W (Ehdr) *ehdr = ei->image; Elf_W (Shdr) *shdr; @@ -378,6 +771,95 @@ elf_w (find_section) (struct elf_image *ei, const char* secname) return 0; } + +static char * +elf_w (add_hex_byte) (char *str, uint8_t byte) +{ + const char hex[] = "0123456789abcdef"; + + *str++ = hex[byte >> 4]; + *str++ = hex[byte & 0xf]; + *str = 0; + + return str; +} + + +static int +elf_w (find_build_id_path) (const struct elf_image *ei, char *path, unsigned path_len) +{ +/* + * build-id is only available on GNU plaforms. So on non-GNU platforms this + * function just returns fail (-1). + */ +#if defined(ELF_NOTE_GNU) && defined(NT_GNU_BUILD_ID) + const Elf_W (Ehdr) *ehdr = ei->image; + const Elf_W (Phdr) *phdr; + unsigned i; + + if (!elf_w (valid_object) (ei)) + return -1; + + phdr = (Elf_W (Phdr) *) ((uint8_t *) ehdr + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i, phdr = (const Elf_W (Phdr) *) (((const uint8_t *) phdr) + ehdr->e_phentsize)) + { + const uint8_t *notes; + const uint8_t *notes_end; + + /* The build-id is in a note section */ + if (phdr->p_type != PT_NOTE) + continue; + + notes = ((const uint8_t *) ehdr) + phdr->p_offset; + notes_end = notes + phdr->p_memsz; + + while(notes < notes_end) + { + const char prefix[] = "/usr/lib/debug/.build-id/"; + + /* See "man 5 elf" for notes about alignment in Nhdr */ + const Elf_W(Nhdr) *nhdr = (const ElfW(Nhdr) *) notes; + const ElfW(Word) namesz = nhdr->n_namesz; + const ElfW(Word) descsz = nhdr->n_descsz; + const ElfW(Word) nameasz = UNW_ALIGN(namesz, 4); /* Aligned size */ + const char *name = (const char *) (nhdr + 1); + const uint8_t *desc = (const uint8_t *) name + nameasz; + unsigned j; + + notes += sizeof(*nhdr) + nameasz + UNW_ALIGN(descsz, 4); + + if ((namesz != sizeof(ELF_NOTE_GNU)) || /* Spec says must be "GNU" with a NULL */ + (nhdr->n_type != NT_GNU_BUILD_ID) || /* Spec says must be NT_GNU_BUILD_ID */ + (strcmp(name, ELF_NOTE_GNU) != 0)) /* Must be "GNU" with NULL termination */ + continue; + + /* Validate that we have enough space */ + if (path_len < (sizeof(prefix) + /* Path prefix inc NULL */ + 2 + /* Subdirectory */ + 1 + /* Directory separator */ + (2 * (descsz - 1)) + /* Leaf filename */ + 6)) /* .debug extension */ + return -1; + + memcpy(path, prefix, sizeof(prefix)); + + path = elf_w (add_hex_byte) (path + sizeof(prefix) - 1, *desc); + *path++ = '/'; + + for(j = 1, ++desc; j < descsz; ++j, ++desc) + path = elf_w (add_hex_byte) (path, *desc); + + strcat(path, ".debug"); + + return 0; + } + } +#endif /* defined(ELF_NOTE_GNU) */ + + return -1; +} + /* Load a debug section, following .gnu_debuglink if appropriate * Loads ei from file if not already mapped. * If is_local, will also search sys directories /usr/local/dbg @@ -386,18 +868,19 @@ elf_w (find_section) (struct elf_image *ei, const char* secname) * ei will be mapped to file or the located .gnu_debuglink from file */ HIDDEN int -elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) +elf_w (load_debuginfo) (const char* file, struct elf_image *ei, int is_local) { int ret; Elf_W (Shdr) *shdr; Elf_W (Ehdr) *prev_image; off_t prev_size; + char path[PATH_MAX]; if (!ei->image) { ret = elf_map_image(ei, file); if (ret) - return ret; + return ret; } prev_image = ei->image; @@ -408,13 +891,27 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) return 0; } + ret = elf_w (find_build_id_path) (ei, path, sizeof(path)); + if (ret == 0) + { + ei->image = NULL; + + ret = elf_w (load_debuginfo) (path, ei, -1); + if (ret == 0) + { + mi_munmap (prev_image, prev_size); + return 0; + } + + ei->image = prev_image; + ei->size = prev_size; + } + shdr = elf_w (find_section) (ei, ".gnu_debuglink"); if (shdr) { if (shdr->sh_size >= PATH_MAX || (shdr->sh_offset + shdr->sh_size > ei->size)) - { - return 0; - } + return 0; { char linkbuf[shdr->sh_size]; @@ -445,14 +942,14 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) strcpy (newname, basedir); strcat (newname, "/"); strcat (newname, linkbuf); - ret = elf_w (load_debuglink) (newname, ei, -1); + ret = elf_w (load_debuginfo) (newname, ei, -1); if (ret == -1) { strcpy (newname, basedir); strcat (newname, "/.debug/"); strcat (newname, linkbuf); - ret = elf_w (load_debuglink) (newname, ei, -1); + ret = elf_w (load_debuginfo) (newname, ei, -1); } if (ret == -1 && is_local == 1) @@ -461,7 +958,7 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) strcat (newname, basedir); strcat (newname, "/"); strcat (newname, linkbuf); - ret = elf_w (load_debuglink) (newname, ei, -1); + ret = elf_w (load_debuginfo) (newname, ei, -1); } if (ret == -1) @@ -474,7 +971,7 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) } else { - munmap (prev_image, prev_size); + mi_munmap (prev_image, prev_size); } return ret; diff --git a/src/native/external/libunwind/src/elfxx.h b/src/native/external/libunwind/src/elfxx.h index cd36eb42451b2a..ad82d9be867caf 100644 --- a/src/native/external/libunwind/src/elfxx.h +++ b/src/native/external/libunwind/src/elfxx.h @@ -53,11 +53,22 @@ extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as, unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp); -extern Elf_W (Shdr)* elf_w (find_section) (struct elf_image *ei, const char* secname); -extern int elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local); +extern int elf_w (get_proc_ip_range) (unw_addr_space_t as, + pid_t pid, unw_word_t ip, + unw_word_t *start, unw_word_t *end); + +extern int elf_w (get_proc_ip_range_in_image) (unw_addr_space_t as, struct elf_image *ei, + unsigned long segbase, unw_word_t ip, + unw_word_t *start, unw_word_t *end); + +extern int elf_w (get_elf_filename) (unw_addr_space_t as, pid_t pid, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp); + +extern Elf_W (Shdr)* elf_w (find_section) (const struct elf_image *ei, const char* secname); +extern int elf_w (load_debuginfo) (const char* file, struct elf_image *ei, int is_local); static inline int -elf_w (valid_object) (struct elf_image *ei) +elf_w (valid_object) (const struct elf_image *ei) { if (ei->size <= EI_VERSION) return 0; @@ -85,14 +96,14 @@ elf_map_image (struct elf_image *ei, const char *path) } ei->size = stat.st_size; - ei->image = mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); + ei->image = mi_mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); close (fd); if (ei->image == MAP_FAILED) return -1; if (!elf_w (valid_object) (ei)) { - munmap(ei->image, ei->size); + mi_munmap(ei->image, ei->size); return -1; } diff --git a/src/native/external/libunwind/src/hppa/Ginit.c b/src/native/external/libunwind/src/hppa/Ginit.c index 265455a68c82a1..5f06b17f71b6da 100644 --- a/src/native/external/libunwind/src/hppa/Ginit.c +++ b/src/native/external/libunwind/src/hppa/Ginit.c @@ -91,11 +91,11 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, if (write) { Debug (12, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "mem[%x] -> %x\n", addr, *val); } return 0; @@ -117,12 +117,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- %x\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %x\n", unw_regname (reg), *val); } return 0; @@ -174,10 +174,23 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void hppa_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; @@ -187,6 +200,7 @@ hppa_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = hppa_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/ia64/Ginit.c b/src/native/external/libunwind/src/ia64/Ginit.c index 4c70a33ccd8d13..91750bee0ed5f3 100644 --- a/src/native/external/libunwind/src/ia64/Ginit.c +++ b/src/native/external/libunwind/src/ia64/Ginit.c @@ -80,11 +80,11 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, if (write) { Debug (12, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "mem[%lx] -> %lx\n", addr, *val); } return 0; @@ -293,7 +293,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %lx\n", unw_regname (reg), *val); } return 0; @@ -352,6 +352,14 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void ia64_local_addr_space_init (void) { @@ -361,6 +369,11 @@ ia64_local_addr_space_init (void) local_addr_space.abi = ABI_LINUX; #elif defined(__hpux) local_addr_space.abi = ABI_HPUX; +#endif +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif #endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = tdep_find_proc_info; @@ -371,6 +384,7 @@ ia64_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = ia64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/ia64/Gtables.c b/src/native/external/libunwind/src/ia64/Gtables.c index e6ac519780d583..3eed66cba5a836 100644 --- a/src/native/external/libunwind/src/ia64/Gtables.c +++ b/src/native/external/libunwind/src/ia64/Gtables.c @@ -624,7 +624,7 @@ validate_cache (unw_addr_space_t as) int ret; SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (check_callback, as); + ret = as->iterate_phdr_function (check_callback, as); SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); return ret; } @@ -655,7 +655,7 @@ tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, di.u.ti.segbase = ip; /* this is cheap... */ SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (callback, &di); + ret = as->iterate_phdr_function (callback, &di); SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); if (ret <= 0) diff --git a/src/native/external/libunwind/src/loongarch64/Gglobal.c b/src/native/external/libunwind/src/loongarch64/Gglobal.c index e770e09d32604b..cc5a5abbdffeba 100644 --- a/src/native/external/libunwind/src/loongarch64/Gglobal.c +++ b/src/native/external/libunwind/src/loongarch64/Gglobal.c @@ -47,8 +47,6 @@ tdep_init (void) dwarf_init (); #ifndef UNW_REMOTE_ONLY - tdep_init_mem_validate (); - loongarch64_local_addr_space_init (); #endif tdep_init_done = 1; /* signal that we're initialized... */ diff --git a/src/native/external/libunwind/src/loongarch64/Ginit.c b/src/native/external/libunwind/src/loongarch64/Ginit.c index 8994e2eea090d2..75fbe4c997ce3d 100644 --- a/src/native/external/libunwind/src/loongarch64/Ginit.c +++ b/src/native/external/libunwind/src/loongarch64/Ginit.c @@ -84,232 +84,6 @@ 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]); - - do_pipe2 (mem_validate_pipe); -} - -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 - { - ret = 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 */ - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ - if (mincore (addr, len, (unsigned char *)mvec) != 0) - { - return -1; - } - - return write_validate (addr); -} -#endif - -/* Initialise memory validation method. On linux kernels <2.6.21, - mincore() returns incorrect value for MAP_PRIVATE mappings, - such as stacks. If mincore() was available at compile time, - check if we can actually use it. If not, use msync() instead. */ -HIDDEN void -tdep_init_mem_validate (void) -{ - open_pipe (); - -#ifdef HAVE_MINCORE - unsigned char present = 1; - size_t len = unw_page_size; - unw_word_t addr = uwn_page_start((unw_word_t)&present); - unsigned char mvec[1]; - int ret; - while ((ret = mincore ((void*)addr, len, (unsigned char *)mvec)) == -1 && - errno == EAGAIN) - { - } - if (ret == 0) - { - Debug(1, "using mincore to validate memory\n"); - mem_validate_func = mincore_validate; - } - else -#endif - { - Debug(1, "using msync to validate memory\n"); - mem_validate_func = msync_validate; - } -} - -/* Cache of already validated addresses */ -#define NLGA 4 -#if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD -// thread-local variant -static _Thread_local unw_word_t last_good_addr[NLGA]; -static _Thread_local int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (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; -} - -#else -// global, thread safe variant -static _Atomic unw_word_t last_good_addr[NLGA]; -static _Atomic int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == atomic_load(&last_good_addr[i])) - return 1; - } - return 0; -} - -static void -cache_valid_mem(unw_word_t addr) -{ - int i, victim; - victim = atomic_load(&lga_victim); - unw_word_t zero = 0; - for (i = 0; i < NLGA; i++) { - if (atomic_compare_exchange_strong(&last_good_addr[victim], &zero, addr)) { - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - atomic_store(&last_good_addr[victim], addr); - victim = (victim + 1) % NLGA; - atomic_store(&lga_victim, victim); -} -#endif - -static int -validate_mem (unw_word_t addr) -{ - size_t len = unw_page_size; - addr = uwn_page_start(addr); - - if (addr == 0) - return -1; - - if (is_cached_valid_mem(addr)) - return 0; - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - - cache_valid_mem(addr); - - return 0; -} - static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, void *arg) @@ -324,7 +98,7 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, /* validate address */ const struct cursor *c = (const struct cursor *)arg; if (likely (c != NULL) && unlikely (c->validate) - && unlikely (validate_mem (addr))) { + && unlikely (!unw_address_is_valid (addr, sizeof(unw_word_t)))) { Debug (16, "mem[%016lx] -> invalid\n", addr); return -1; } @@ -380,11 +154,24 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return elf_w (get_elf_filename) (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void loongarch64_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif 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; @@ -394,6 +181,7 @@ loongarch64_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = loongarch64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/mi/Gaddress_validator.c b/src/native/external/libunwind/src/mi/Gaddress_validator.c new file mode 100644 index 00000000000000..aaf5a0941214fa --- /dev/null +++ b/src/native/external/libunwind/src/mi/Gaddress_validator.c @@ -0,0 +1,302 @@ +/* + * Contributed by Stephen M. Webb + * + * This file is part of libunwind, a platform-independent unwind library. + * + * 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" + + +#ifdef UNW_REMOTE_ONLY +bool +unw_address_is_valid(UNUSED unw_word_t addr, UNUSED size_t len) +{ + Debug(1, "remote-only invoked\n"); + return false; +} + +#else /* !UNW_REMOTE_ONLY */ + +#include + + +static atomic_flag _unw_address_validator_initialized = ATOMIC_FLAG_INIT; +static int _mem_validate_pipe[2] = {-1, -1}; + +#ifdef HAVE_PIPE2 +static int +_do_pipe2 (int pipefd[2]) +{ + return pipe2 (pipefd, O_CLOEXEC | O_NONBLOCK); +} +#else +static 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 int +_do_pipe2 (int pipefd[2]) +{ + if (pipe (pipefd) < 0) + { + return -1; + } + _set_pipe_flags(pipefd[0]); + _set_pipe_flags(pipefd[1]); +} +#endif + + +static int +_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]); + + return _do_pipe2 (_mem_validate_pipe); +} + + +/** + * Test is a memory address is valid by trying to write from it + * @param[in] addr The address to validate + * + * @returns true if the memory address is valid (readable), false otherwise. + * + * This check works by using the address as a (one-byte) buffer in a + * write-to-pipe operation. The write will fail if the memory is not in the + * process's address space and marked as readable. The read will force the page + * to be swapped in if it's not already there. + */ +static bool +_write_validate (unw_word_t addr) +{ + int ret = -1; + ssize_t bytes = 0; + + if (unlikely (!atomic_flag_test_and_set(&_unw_address_validator_initialized))) + { + if (_open_pipe () != 0) + { + return false; + } + } + + do + { + char buf; + bytes = read (_mem_validate_pipe[0], &buf, 1); + } + while ( errno == EINTR ); + + if (!(bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK)) + { + // re-open closed pipe + if (_open_pipe () != 0) + { + return false; + } + } + + do + { +#ifdef HAVE_SYS_SYSCALL_H + /* use syscall insteadof write() so that ASAN does not complain */ + ret = syscall (SYS_write, _mem_validate_pipe[1], addr, 1); +#else + ret = write (_mem_validate_pipe[1], (void *)addr, 1); +#endif + } + while ( errno == EINTR ); + + return ret > 0; +} + + +/* Cache of already validated addresses */ +enum { NLGA = 4 }; + +#if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD +// thread-local variant +static _Thread_local unw_word_t last_good_addr[NLGA]; +static _Thread_local int lga_victim; + + +static bool +_is_cached_valid_mem(unw_word_t page_addr) +{ + int i; + for (i = 0; i < NLGA; i++) + { + if (page_addr == last_good_addr[i]) + return true; + } + return false; +} + + +static void +_cache_valid_mem(unw_word_t page_addr) +{ + int i, victim; + victim = lga_victim; + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[victim] == 0) + { + last_good_addr[victim] = page_addr; + return; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = page_addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; +} + +#else +// global, thread safe variant +static _Atomic unw_word_t last_good_addr[NLGA]; +static _Atomic int lga_victim; + + +static bool +_is_cached_valid_mem(unw_word_t page_addr) +{ + int i; + for (i = 0; i < NLGA; i++) + { + if (page_addr == atomic_load(&last_good_addr[i])) + return true; + } + return false; +} + + +/** + * Adds a known-valid page address to the cache. + * + * This implementation is racy as all get-out but the worst case is that cached + * address get lost, forcing extra unnecessary validation checks. All of the + * atomic operations don't matter because of TOCTOU races. + */ +static void +_cache_valid_mem(unw_word_t page_addr) +{ + unw_word_t zero = 0; + int victim = atomic_load(&lga_victim); + for (int i = 0; i < NLGA; i++) + { + if (atomic_compare_exchange_strong(&last_good_addr[victim], &zero, page_addr)) + { + return; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + atomic_store(&last_good_addr[victim], page_addr); + victim = (victim + 1) % NLGA; + atomic_store(&lga_victim, victim); +} +#endif + + +/** + * Validate an address is readable + * @param[in] addr The (starting) address of the memory range to validate + * @param[in] len The size of the memory range to validate in bytes + * + * Validates the memory range from @p addr to (@p addr + @p len - 1) is + * readable. Since the granularity of memory readability is the page, only one + * byte needs to be validated per page for each page starting at @p addr and + * encompassing @p len bytes. Only the first address of each page is checked. + * + * @returns true if the memory is readable, false otherwise. + */ +bool +unw_address_is_valid(unw_word_t addr, size_t len) +{ + if (len == 0) + return true; + + /* + * Find the starting address of the page containing the start of the range. + */ + unw_word_t start_page_addr = unw_page_start (addr); + + /* + * Bounds check on bottom of memory: first page is always deemed inaccessible. + * This is potentially incorrect on an embedded system, especially one running + * on bare metal with no VMM, but the check has always been here and no one + * has complained. + */ + if (start_page_addr == 0) + return false; + + /* + * Bounds check on top of memory. Unsigned wraparound could be hazardous. + */ + if (addr > (UNW_WORD_MAX - len - unw_page_size)) + return false; + + /* + * Find the starting address of the page containing the end of the range. + */ + unw_word_t end_page_addr = unw_page_start (addr + (len - 1)) + unw_page_size; + + /* + * Step through each page and check if the first address in each is readable. + * The first non-readable page encountered means none of them in the given + * range can be considered readable. + */ + for (unw_word_t page_addr = start_page_addr; + page_addr < end_page_addr; + page_addr += unw_page_size) + { + if (!_is_cached_valid_mem(page_addr)) + { + if (!_write_validate (page_addr)) + { + Debug(1, "returning false\n"); + return false; + } + _cache_valid_mem(page_addr); + } + } + + return true; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/native/external/libunwind/src/mi/Gdestroy_addr_space.c b/src/native/external/libunwind/src/mi/Gdestroy_addr_space.c index 504558e1a7880c..fa29ac9555a807 100644 --- a/src/native/external/libunwind/src/mi/Gdestroy_addr_space.c +++ b/src/native/external/libunwind/src/mi/Gdestroy_addr_space.c @@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "libunwind_i.h" void -unw_destroy_addr_space (unw_addr_space_t as) +unw_destroy_addr_space (unw_addr_space_t as UNUSED) { #ifndef UNW_LOCAL_ONLY # if UNW_DEBUG diff --git a/src/native/external/libunwind/src/mi/Gdyn-remote.c b/src/native/external/libunwind/src/mi/Gdyn-remote.c index 40a5ad8b5aba41..6d4ec1ecf869b3 100644 --- a/src/native/external/libunwind/src/mi/Gdyn-remote.c +++ b/src/native/external/libunwind/src/mi/Gdyn-remote.c @@ -286,8 +286,9 @@ unwi_dyn_remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, } HIDDEN void -unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, - void *arg) +unwi_dyn_remote_put_unwind_info (unw_addr_space_t as UNUSED, + unw_proc_info_t *pi, + void *arg UNUSED) { if (!pi->unwind_info) return; diff --git a/src/native/external/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/native/external/libunwind/src/mi/Gfind_dynamic_proc_info.c index 2e7c62e5e8623e..dcd7f9de0dc572 100644 --- a/src/native/external/libunwind/src/mi/Gfind_dynamic_proc_info.c +++ b/src/native/external/libunwind/src/mi/Gfind_dynamic_proc_info.c @@ -63,8 +63,11 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, #ifdef UNW_LOCAL_ONLY static inline int -remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, - int need_unwind_info, void *arg) +remote_find_proc_info (unw_addr_space_t as UNUSED, + unw_word_t ip UNUSED, + unw_proc_info_t *pi UNUSED, + int need_unwind_info UNUSED, + void *arg UNUSED) { return -UNW_ENOINFO; } diff --git a/src/native/external/libunwind/src/mi/Gget_elf_filename.c b/src/native/external/libunwind/src/mi/Gget_elf_filename.c new file mode 100644 index 00000000000000..97d0645164fe4f --- /dev/null +++ b/src/native/external/libunwind/src/mi/Gget_elf_filename.c @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library +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" +#include "remote.h" + +int +unw_get_elf_filename_by_ip (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + unw_accessors_t *a = unw_get_accessors_int (as); + unw_proc_info_t pi; + int ret; + + buf[0] = '\0'; /* always return a valid string, even if it's empty */ + + ret = unwi_find_dynamic_proc_info (as, ip, &pi, 1, arg); + if (ret == 0) + { + unwi_put_dynamic_unwind_info (as, &pi, arg); + return -UNW_ENOINFO; + } + + if (a->get_elf_filename) + return (*a->get_elf_filename) (as, ip, buf, buf_len, offp, arg); + + return -UNW_ENOINFO; +} + +int +unw_get_elf_filename (unw_cursor_t *cursor, char *buf, size_t buf_len, + unw_word_t *offp) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ip; + int error; + + 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; + } + +#endif + error = unw_get_elf_filename_by_ip (tdep_get_as (c), ip, buf, buf_len, offp, + tdep_get_as_arg (c)); +#if !defined(__ia64__) + if (c->dwarf.use_prev_instr && offp != NULL && error == 0) + *offp += 1; +#endif + return error; +} diff --git a/src/native/external/libunwind/src/mi/Gset_iterate_phdr_function.c b/src/native/external/libunwind/src/mi/Gset_iterate_phdr_function.c new file mode 100644 index 00000000000000..d56f1fb69ed5d3 --- /dev/null +++ b/src/native/external/libunwind/src/mi/Gset_iterate_phdr_function.c @@ -0,0 +1,23 @@ +#include "libunwind_i.h" + +//! Set an alternative function to use in place of dl_iterate_phdr. +/*! Suggested use is to specify an async-signal safe implementation. + * If not set (or set to NULL) the system dl_iterate_phdr will + * be used. */ +void +unw_set_iterate_phdr_function (unw_addr_space_t as, unw_iterate_phdr_func_t function) +{ + if (!tdep_init_done) + tdep_init (); + +#ifndef UNW_REMOTE_ONLY + if (function) + as->iterate_phdr_function = function; + else +# if defined(HAVE_DL_ITERATE_PHDR) + as->iterate_phdr_function = dl_iterate_phdr; +# else + as->iterate_phdr_function = NULL; +# endif +#endif +} diff --git a/src/native/external/libunwind/src/tilegx/Lcreate_addr_space.c b/src/native/external/libunwind/src/mi/Laddress_validator.c similarity index 77% rename from src/native/external/libunwind/src/tilegx/Lcreate_addr_space.c rename to src/native/external/libunwind/src/mi/Laddress_validator.c index 0f2dc6be901453..b810a3fea02d8c 100644 --- a/src/native/external/libunwind/src/tilegx/Lcreate_addr_space.c +++ b/src/native/external/libunwind/src/mi/Laddress_validator.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" +#include "Gaddress_validator.c" #endif diff --git a/src/native/external/libunwind/src/tilegx/Lapply_reg_state.c b/src/native/external/libunwind/src/mi/Lget_elf_filename.c similarity index 78% rename from src/native/external/libunwind/src/tilegx/Lapply_reg_state.c rename to src/native/external/libunwind/src/mi/Lget_elf_filename.c index 7ebada480e5640..6f24fdbdf24759 100644 --- a/src/native/external/libunwind/src/tilegx/Lapply_reg_state.c +++ b/src/native/external/libunwind/src/mi/Lget_elf_filename.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" +#include "Gget_elf_filename.c" #endif diff --git a/src/native/external/libunwind/src/tilegx/Lget_proc_info.c b/src/native/external/libunwind/src/mi/Lset_iterate_phdr_function.c similarity index 73% rename from src/native/external/libunwind/src/tilegx/Lget_proc_info.c rename to src/native/external/libunwind/src/mi/Lset_iterate_phdr_function.c index 69028b019fcd51..67cef9519c8375 100644 --- a/src/native/external/libunwind/src/tilegx/Lget_proc_info.c +++ b/src/native/external/libunwind/src/mi/Lset_iterate_phdr_function.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" +#include "Gset_iterate_phdr_function.c" #endif diff --git a/src/native/external/libunwind/src/mi/flush_cache.c b/src/native/external/libunwind/src/mi/flush_cache.c index 55ee8a3305edc7..0ea78be89237e5 100644 --- a/src/native/external/libunwind/src/mi/flush_cache.c +++ b/src/native/external/libunwind/src/mi/flush_cache.c @@ -27,7 +27,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include void -unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) +unw_flush_cache (unw_addr_space_t as, unw_word_t lo UNUSED, unw_word_t hi UNUSED) { #if !UNW_TARGET_IA64 struct unw_debug_frame_list *w = as->debug_frames; @@ -37,10 +37,10 @@ unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) struct unw_debug_frame_list *n = w->next; if (w->index) - munmap (w->index, w->index_size); + mi_munmap (w->index, w->index_size); - munmap (w->debug_frame, w->debug_frame_size); - munmap (w, sizeof (*w)); + mi_munmap (w->debug_frame, w->debug_frame_size); + mi_munmap (w, sizeof (*w)); w = n; } as->debug_frames = NULL; diff --git a/src/native/external/libunwind/src/mi/mempool.c b/src/native/external/libunwind/src/mi/mempool.c index 7c5d27d0c2c309..a45f19e8c25dfc 100644 --- a/src/native/external/libunwind/src/mi/mempool.c +++ b/src/native/external/libunwind/src/mi/mempool.c @@ -43,7 +43,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ static alignas(MAX_ALIGN) char sos_memory[SOS_MEMORY_SIZE]; static _Atomic size_t sos_memory_freepos = 0; -static size_t pg_size; HIDDEN void * sos_alloc (size_t size) @@ -94,7 +93,7 @@ expand (struct mempool *pool) GET_MEMORY (mem, size); if (!mem) { - size = UNW_ALIGN(pool->obj_size, pg_size); + size = UNW_ALIGN(pool->obj_size, unw_page_size); GET_MEMORY (mem, size); if (!mem) { @@ -109,9 +108,6 @@ expand (struct mempool *pool) HIDDEN void mempool_init (struct mempool *pool, size_t obj_size, size_t reserve) { - if (pg_size == 0) - pg_size = getpagesize (); - memset (pool, 0, sizeof (*pool)); lock_init (&pool->lock); @@ -121,14 +117,14 @@ mempool_init (struct mempool *pool, size_t obj_size, size_t reserve) if (!reserve) { - reserve = pg_size / obj_size / 4; + reserve = unw_page_size / obj_size / 4; if (!reserve) reserve = 16; } pool->obj_size = obj_size; pool->reserve = reserve; - pool->chunk_size = UNW_ALIGN(2*reserve*obj_size, pg_size); + pool->chunk_size = UNW_ALIGN(2*reserve*obj_size, unw_page_size); expand (pool); } diff --git a/src/native/external/libunwind/src/mips/Ginit.c b/src/native/external/libunwind/src/mips/Ginit.c index 84a34352016b8b..748419d20fa4be 100644 --- a/src/native/external/libunwind/src/mips/Ginit.c +++ b/src/native/external/libunwind/src/mips/Ginit.c @@ -179,6 +179,15 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + + return elf_w (get_elf_filename) (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void mips_local_addr_space_init (void) { @@ -194,6 +203,11 @@ mips_local_addr_space_init (void) # error Unsupported ABI #endif local_addr_space.addr_size = sizeof (void *); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; @@ -203,6 +217,7 @@ mips_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = NULL; /* mips_local_resume? FIXME! */ local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/nto/unw_nto_access_fpreg.c b/src/native/external/libunwind/src/nto/unw_nto_access_fpreg.c new file mode 100644 index 00000000000000..c1d89c4b7dd338 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_access_fpreg.c @@ -0,0 +1,43 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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-nto.h" +#include "unw_nto_internal.h" + +#include + + +int unw_nto_access_fpreg (unw_addr_space_t as, + unw_regnum_t regnum, + unw_fpreg_t *valp, int write, + void *arg) +{ + if (!write) + { + memset (valp, 0, sizeof (*valp)); + } + + return 0; +} + diff --git a/src/native/external/libunwind/src/nto/unw_nto_access_mem.c b/src/native/external/libunwind/src/nto/unw_nto_access_mem.c new file mode 100644 index 00000000000000..670c17b26f4019 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_access_mem.c @@ -0,0 +1,79 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 "unw_nto_internal.h" +#include "os-qnx.h" + +#include +#include +#include +#include + + +/** + * Read/write data from/to the target address space + * + * @todo save opened fd in unw_nto_internal_t + */ +int unw_nto_access_mem (unw_addr_space_t as, + unw_word_t addr, + unw_word_t *valp, + int write, + void *arg) +{ + int ret = -UNW_ENOINFO; + unw_nto_internal_t *uni = (unw_nto_internal_t *)arg; + int as_fd = unw_nto_procfs_open_as (uni->pid); + + if (as_fd < 0) + { + Debug (0, "error %d opening as file: %s\n", errno, strerror (errno)); + return ret; + } + + if (lseek (as_fd, (off_t)addr, SEEK_SET) == -1) + { + Debug (0, "error %d in lseek(%" PRIxPTR "): %s\n", errno, addr, strerror (errno)); + close (as_fd); + return ret; + } + + if (!write) + { + ssize_t count = read (as_fd, valp, sizeof (*valp)); + + if (count != sizeof (*valp)) + { + Debug (0, "error %d in read(%zu): %s\n", errno, sizeof (*valp), strerror (errno)); + close (as_fd); + return ret; + } + + ret = 0; + } + + close (as_fd); + return ret; +} + diff --git a/src/native/external/libunwind/src/nto/unw_nto_access_reg.c b/src/native/external/libunwind/src/nto/unw_nto_access_reg.c new file mode 100644 index 00000000000000..18a317eb94c938 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_access_reg.c @@ -0,0 +1,202 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 "unw_nto_internal.h" +#include "os-qnx.h" + +#include +#include +#include +#include +#include +#include + + +int unw_nto_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, + unw_word_t *valp, + int write, + void *arg) +{ + unw_nto_internal_t *uni = (unw_nto_internal_t *)arg; + int ret = -UNW_EUNSPEC; + procfs_greg greg; + int ctl_fd = unw_nto_procfs_open_ctl (uni->pid); + + if (ctl_fd < 0) + { + Debug (0, "error %d opening ctl file: %s", errno, strerror (errno)); + return ret; + } + + int err = devctl (ctl_fd, DCMD_PROC_CURTHREAD, & (uni->tid), sizeof (uni->tid), 0); + + if (err != EOK) + { + Debug (0, "error %d in devctl(DCMD_PROC_CURTHREAD): %s", err, strerror (err)); + close (ctl_fd); + return ret; + } + + if (write) + { + Debug (0, "write not supported\n"); + } + + else + { + err = devctl (ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg), NULL); + + if (err != EOK) + { + Debug (0, "error %d in devctl(DCMD_PROC_GETGREG): %s", err, strerror (err)); + close (ctl_fd); + return ret; + } + + switch (regnum) + { + case UNW_REG_IP: +#if defined(__X86_64__) + *valp = GET_REGIP (&greg.x86_64); +#elif defined(__ARM__) + *valp = GET_REGIP (&greg.arm); +#elif defined(__aarch64__) + *valp = greg.aarch64.gpr[AARCH64_REG_X30]; +#else +# error Unsupported architecture +#endif + break; + + case UNW_REG_SP: +#if defined(__X86_64__) + *valp = GET_REGSP (&greg.x86_64); +#elif defined(__ARM__) + *valp = GET_REGSP (&greg.arm); +#elif defined(__aarch64__) + *valp = GET_REGSP (&greg.aarch64); +#else +# error Unsupported architecture +#endif + break; +#if defined(__aarch64__) + + case UNW_AARCH64_PC: + *valp = GET_REGIP (&greg.aarch64); + break; + + case UNW_AARCH64_X29: + *valp = greg.aarch64.gpr[AARCH64_REG_X29]; + break; +#endif +#if defined(__X86_64__) + + case UNW_X86_64_RAX: + Debug (15, "request for UNW_X86_64_RAX (%d)\n", UNW_X86_64_RAX); + *valp = greg.x86_64.rax; + break; + + case UNW_X86_64_RDX: + Debug (15, "request for UNW_X86_64_RDX (%d)\n", UNW_X86_64_RDX); + *valp = greg.x86_64.rdx; + break; + + case UNW_X86_64_RCX: + Debug (15, "request for UNW_X86_64_RCX (%d)\n", UNW_X86_64_RCX); + *valp = greg.x86_64.rcx; + break; + + case UNW_X86_64_RBX: + Debug (15, "request for UNW_X86_64_RBX (%d)\n", UNW_X86_64_RBX); + *valp = greg.x86_64.rbx; + break; + + case UNW_X86_64_RSI: + Debug (15, "request for UNW_X86_64_RSI (%d)\n", UNW_X86_64_RSI); + *valp = greg.x86_64.rsi; + break; + + case UNW_X86_64_RDI: + Debug (15, "request for UNW_X86_64_RDI (%d)\n", UNW_X86_64_RDI); + *valp = greg.x86_64.rdi; + break; + + case UNW_X86_64_RBP: + Debug (15, "request for UNW_X86_64_RBP (%d)\n", UNW_X86_64_RBP); + *valp = greg.x86_64.rbp; + break; + + case UNW_X86_64_R8: + Debug (15, "request for UNW_X86_64_R8 (%d)\n", UNW_X86_64_R8); + *valp = greg.x86_64.r8; + break; + + case UNW_X86_64_R9: + Debug (15, "request for UNW_X86_64_R9 (%d)\n", UNW_X86_64_R9); + *valp = greg.x86_64.r9; + break; + + case UNW_X86_64_R10: + Debug (15, "request for UNW_X86_64_R10 (%d)\n", UNW_X86_64_R10); + *valp = greg.x86_64.r10; + break; + + case UNW_X86_64_R11: + Debug (15, "request for UNW_X86_64_R11 (%d)\n", UNW_X86_64_R11); + *valp = greg.x86_64.r11; + break; + + case UNW_X86_64_R12: + Debug (15, "request for UNW_X86_64_R12 (%d)\n", UNW_X86_64_R12); + *valp = greg.x86_64.r12; + break; + + case UNW_X86_64_R13: + Debug (15, "request for UNW_X86_64_R13 (%d)\n", UNW_X86_64_R13); + *valp = greg.x86_64.r13; + break; + + case UNW_X86_64_R14: + Debug (15, "request for UNW_X86_64_R14 (%d)\n", UNW_X86_64_R14); + *valp = greg.x86_64.r14; + break; + + case UNW_X86_64_R15: + Debug (15, "request for UNW_X86_64_R15 (%d)\n", UNW_X86_64_R15); + *valp = greg.x86_64.r15; + break; +#endif + + default: + Debug (0, "as=%p, regnum=%d, valp=%p, write=%d uni=%p\n", as, regnum, valp, write, uni); + break; + } + + ret = 0; + } + + close (ctl_fd); + return ret; +} + diff --git a/src/native/external/libunwind/src/nto/unw_nto_accessors.c b/src/native/external/libunwind/src/nto/unw_nto_accessors.c new file mode 100644 index 00000000000000..1ccc8215c593ef --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_accessors.c @@ -0,0 +1,44 @@ +/* + * Copyright 2020, 2022-2023 QNX Blackberry Limited. + * + * 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-nto.h" + + +/** + * Instance of the NTO accessor struct. + */ +unw_accessors_t unw_nto_accessors = +{ + .find_proc_info = unw_nto_find_proc_info, + .put_unwind_info = unw_nto_put_unwind_info, + .get_dyn_info_list_addr = unw_nto_get_dyn_info_list_addr, + .access_mem = unw_nto_access_mem, + .access_reg = unw_nto_access_reg, + .access_fpreg = unw_nto_access_fpreg, + .resume = unw_nto_resume, + .get_proc_name = unw_nto_get_proc_name, + .get_proc_ip_range = unw_nto_get_proc_ip_range, + .get_elf_filename = unw_nto_get_elf_filename, +}; + diff --git a/src/native/external/libunwind/src/nto/unw_nto_create.c b/src/native/external/libunwind/src/nto/unw_nto_create.c new file mode 100644 index 00000000000000..08b6a0469b8efe --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_create.c @@ -0,0 +1,102 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 "os-qnx.h" +#include "unw_nto_internal.h" + +#include +#include +#include +#include +#include +#include +#include + + +/** + * Hold the target thread to avoid race conditions. + * @param[in] ctl_fd File descriptor for /proc process ctl file + * @param[in] tid Identifies thread to hold + * + * @returns 0 on error, otherwise on success. + */ +static int _hold_thread (int ctl_fd, pthread_t tid) +{ + procfs_threadctl tctl = + { + .cmd = _NTO_TCTL_ONE_THREAD_HOLD, + .tid = tid + }; + memcpy (tctl.data, & (tid), sizeof (tid)); + int err = devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL); + + if (err != EOK) + { + Debug (0, "error %d in devctl(DCMD_PROC_THREADCTL): %s\n", err, strerror (err)); + } + + return err == EOK; +} + + +void *unw_nto_create (pid_t pid, pthread_t tid) +{ + unw_nto_internal_t *uni = calloc (1, sizeof (unw_nto_internal_t)); + if (uni == NULL) + { + return NULL; + } + + mi_init (); + + uni->pid = pid; + uni->tid = tid; + uni->edi.di_cache.format = -1; + uni->edi.di_debug.format = -1; + int ctl_fd = unw_nto_procfs_open_ctl (pid); + + if (ctl_fd < 0) + { + Debug (0, "error %d opening procfs ctl file for pid %d: %s\n", + errno, pid, strerror (errno)); + unw_nto_destroy (uni); + uni = NULL; + return uni; + } + + if (!_hold_thread (ctl_fd, tid)) + { + close (ctl_fd); + unw_nto_destroy (uni); + uni = NULL; + } + + else + { + close (ctl_fd); + } + + return uni; +} + diff --git a/src/native/external/libunwind/src/nto/unw_nto_destroy.c b/src/native/external/libunwind/src/nto/unw_nto_destroy.c new file mode 100644 index 00000000000000..407469b6faf9ce --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_destroy.c @@ -0,0 +1,81 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 "unw_nto_internal.h" +#include "os-qnx.h" + +#include +#include +#include +#include +#include +#include + + +/** + * Continues a (held) thread. + * @param[in] ctl_fd File descriptor for /proc process ctl file + * @param[in] tid Identifies thread to continue + * + * @returns 0 on error, otherwise on success. + */ +static void _cont_thread (int ctl_fd, pthread_t tid) +{ + procfs_threadctl tctl = + { + .cmd = _NTO_TCTL_ONE_THREAD_CONT, + .tid = tid + }; + memcpy (tctl.data, & (tid), sizeof (tid)); + int ret = devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL); + + if (ret != EOK) + { + Debug (0, "error %d continuing thread %d: %s\n", + ret, tid, strerror (ret)); + } +} + + +/** + * Tears down an NTO unwind context. + */ +void unw_nto_destroy (void *arg) +{ + unw_nto_internal_t *uni = (unw_nto_internal_t *)arg; + int ctl_fd = unw_nto_procfs_open_ctl (uni->pid); + + if (ctl_fd < 0) + { + Debug (0, "error %d opening procfs ctl file for pid %d: %s\n", + errno, uni->pid, strerror (errno)); + free (uni); + return; + } + + _cont_thread (ctl_fd, uni->tid); + close (ctl_fd); + free (uni); +} + diff --git a/src/native/external/libunwind/src/nto/unw_nto_elf.c b/src/native/external/libunwind/src/nto/unw_nto_elf.c new file mode 100644 index 00000000000000..b12641d776ef05 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_elf.c @@ -0,0 +1,33 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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. + */ + +/* + * We need to get a separate copy of the ELF-code into libunwind-nto since it + * cannot (and must not) have any ELF dependencies on libunwind. + */ + +#include "libunwind_i.h" /* get ELFCLASS defined */ +#include "../elfxx.c" + diff --git a/src/native/external/libunwind/src/nto/unw_nto_find_proc_info.c b/src/native/external/libunwind/src/nto/unw_nto_find_proc_info.c new file mode 100644 index 00000000000000..a3fd115feda414 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_find_proc_info.c @@ -0,0 +1,100 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 "unw_nto_internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/** + * Locate info needed to unwind a particular procedure. + * @param[in] as The address space object + * @param[in] ip Address of an instruction inside the procedure. + * @param[out] pi Pointer to where the information should be written. + * @param[in] need_unwind_info Flags is certain fields are mandatory i *pi: + * - format + * - unwind_info_size + * - unwind_info + * @param[in] arg The NTO unwind context. + * + * @returns 0 on normal, successful completion and @c -UNW_ESTOPUNWIND to signal + * the end of the frame-chain. Returns @c -UNW_ENOINFO otherwise indicating an + * error. + * + * This function is part of the public API of the libunwind API library and is a + * callback passed to @c unw_create_addr_space() through the @c unw_accessors_t + * object. + */ +int unw_nto_find_proc_info (unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, + void *arg) +{ + unw_nto_internal_t *uni = (unw_nto_internal_t *)arg; + int ret = -UNW_ENOINFO; + unsigned long segbase = 0; + unsigned long mapoff = 0; + char path[PATH_MAX]; + invalidate_edi (&uni->edi); + ret = tdep_get_elf_image (&uni->edi.ei, + uni->pid, + ip, + &segbase, + &mapoff, + path, + sizeof (path)); + + if (ret >= 0) + { + if (tdep_find_unwind_table (&uni->edi, as, path, segbase, mapoff, ip) >= 0) + { + if (uni->edi.di_cache.format != -1) + { + ret = tdep_search_unwind_table (as, ip, &uni->edi.di_cache, + pi, need_unwind_info, uni); + } + + if (ret == -UNW_ENOINFO && uni->edi.di_debug.format != -1) + { + ret = tdep_search_unwind_table (as, ip, &uni->edi.di_debug, pi, + need_unwind_info, uni); + } + } + } + + return ret; +} + diff --git a/src/native/external/libunwind/src/nto/unw_nto_get_dyn_info_list_addr.c b/src/native/external/libunwind/src/nto/unw_nto_get_dyn_info_list_addr.c new file mode 100644 index 00000000000000..b515441e34d197 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_get_dyn_info_list_addr.c @@ -0,0 +1,38 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 "unw_nto_internal.h" + + +/** + * Get the dynamic unwind info registration list. This implementation isn't + * supporting dynamically-generated code so this function does nothing. + */ +int unw_nto_get_dyn_info_list_addr (unw_addr_space_t as, + unw_word_t *dilap, + void *arg) +{ + return -UNW_ENOINFO; +} + diff --git a/src/native/external/libunwind/src/nto/unw_nto_get_elf_filename.c b/src/native/external/libunwind/src/nto/unw_nto_get_elf_filename.c new file mode 100644 index 00000000000000..1654099f6c356d --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_get_elf_filename.c @@ -0,0 +1,51 @@ +/* + * 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 "unw_nto_internal.h" + +#include +#include + +int unw_nto_get_elf_filename (unw_addr_space_t as, + unw_word_t ip, + char *buf, + size_t buf_len, + unw_word_t *offp, + void *arg) +{ + unw_nto_internal_t *uni = (unw_nto_internal_t *)arg; + char path[PATH_MAX] = {0}; + size_t path_len = sizeof (path); + int ret = -UNW_ENOINFO; +#if UNW_ELF_CLASS == UNW_ELFCLASS64 + ret = _Uelf64_get_elf_filename (as, uni->pid, ip, path, path_len, offp); +#elif UNW_ELF_CLASS == UNW_ELFCLASS32 + ret = _Uelf32_get_elf_filename (as, uni->pid, ip, path, path_len, offp); +#else +# error no valid ELF class defined +#endif + + if (ret >= 0) + snprintf (buf, buf_len, "%s", path); + + return ret; +} diff --git a/src/native/external/libunwind/src/nto/unw_nto_get_proc_name.c b/src/native/external/libunwind/src/nto/unw_nto_get_proc_name.c new file mode 100644 index 00000000000000..87a2af07fb42b4 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_get_proc_name.c @@ -0,0 +1,88 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 "unw_nto_internal.h" + +#include +#include + + +/** + * Callback to obtain the name of the procedure in the current frame and the + * relative offset of the IP within that procedure. + */ +int unw_nto_get_proc_name (unw_addr_space_t as, + unw_word_t ip, + char *buf, + size_t buf_len, + unw_word_t *offp, + void *arg) +{ + unw_nto_internal_t *uni = (unw_nto_internal_t *)arg; + char symbol[PATH_MAX] = {0}; + size_t symbol_len = sizeof (symbol); + char path[PATH_MAX] = {0}; + size_t path_len = sizeof (path); + int ret = -UNW_ENOINFO; +#if UNW_ELF_CLASS == UNW_ELFCLASS64 + ret = _Uelf64_get_proc_name (as, uni->pid, ip, symbol, symbol_len, offp); +#elif UNW_ELF_CLASS == UNW_ELFCLASS32 + ret = _Uelf32_get_proc_name (as, uni->pid, ip, symbol, symbol_len, offp); +#else +# error no valid ELF class defined +#endif + + if (ret >= 0) + { + /* snprintf(buf, buf_len, "%s:%s", path, symbol); */ + snprintf (buf, buf_len, "%s", symbol); + } + + else if (path[0] != '\0') + { + snprintf (buf, buf_len, "%s:?????", path); + } + + return ret; +} + +int unw_nto_get_proc_ip_range (unw_addr_space_t as, + unw_word_t ip, + unw_word_t *start, + unw_word_t *end, + void *arg) +{ + unw_nto_internal_t *uni = (unw_nto_internal_t *)arg; + int ret = -UNW_ENOINFO; + +#if UNW_ELF_CLASS == UNW_ELFCLASS64 + ret = _Uelf64_get_proc_ip_range (as, uni->pid, ip, start, end); +#elif UNW_ELF_CLASS == UNW_ELFCLASS32 + ret = _Uelf32_get_proc_ip_range (as, uni->pid, ip, start, end); +#else +# error no valid ELF class defined +#endif + + return ret; +} diff --git a/src/native/external/libunwind/src/nto/unw_nto_internal.h b/src/native/external/libunwind/src/nto/unw_nto_internal.h new file mode 100644 index 00000000000000..ed79ab25200754 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_internal.h @@ -0,0 +1,44 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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 UNW_NTO_INTERNAL_H +#define UNW_NTO_INTERNAL_H + +#include "libunwind-nto.h" +#include "libunwind_i.h" + + +/** + * Internal unw-nto context. + */ +typedef struct unw_nto_internal +{ + pid_t pid; /* process ID of the thread being unwound */ + pthread_t tid; /* thread ID of the thread being unwound */ + struct elf_dyn_info edi; /* ELF info for current frame */ +} unw_nto_internal_t; + + +#endif /* UNW_NTO_INTERNAL_H */ + diff --git a/src/native/external/libunwind/src/nto/unw_nto_put_unwind_info.c b/src/native/external/libunwind/src/nto/unw_nto_put_unwind_info.c new file mode 100644 index 00000000000000..2c6ec1dfb0d4d8 --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_put_unwind_info.c @@ -0,0 +1,37 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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-nto.h" +#include "unw_nto_internal.h" + + +/** + * @todo unsupported + */ +void unw_nto_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, + void *arg) +{ + Debug (2, "as=%p, pi=%p, arg=%p\n", as, pi, arg); +} diff --git a/src/native/external/libunwind/src/nto/unw_nto_resume.c b/src/native/external/libunwind/src/nto/unw_nto_resume.c new file mode 100644 index 00000000000000..b250c3ed565d1f --- /dev/null +++ b/src/native/external/libunwind/src/nto/unw_nto_resume.c @@ -0,0 +1,39 @@ +/* + * Copyright 2020, 2022 Blackberry Limited. + * + * 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-nto.h" +#include "unw_nto_internal.h" + + +/** + * @todo unsupported + */ +int unw_nto_resume (unw_addr_space_t as, + unw_cursor_t *reg, + void *arg) +{ + Debug (2, "as=%p, reg=%p, arg=%p\n", as, reg, arg); + return 0; +} + diff --git a/src/native/external/libunwind/src/os-freebsd.c b/src/native/external/libunwind/src/os-freebsd.c index 753e819dfe4f6f..2d7c6bea920eb8 100644 --- a/src/native/external/libunwind/src/os-freebsd.c +++ b/src/native/external/libunwind/src/os-freebsd.c @@ -37,7 +37,7 @@ get_mem(size_t sz) { void *res; - res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + res = mi_mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (res == MAP_FAILED) return (NULL); return (res); @@ -46,7 +46,7 @@ get_mem(size_t sz) static void free_mem(void *ptr, size_t sz) { - munmap(ptr, sz); + mi_munmap(ptr, sz); } static int @@ -136,8 +136,12 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, if (path) { strncpy(path, kv->kve_path, pathlen); + path[pathlen - 1] = '\0'; } - ret = elf_map_image (ei, kv->kve_path); + if (ei) + ret = elf_map_image (ei, kv->kve_path); + else + ret = strlen (kv->kve_path) >= pathlen ? -UNW_ENOMEM : UNW_ESUCCESS; break; } free_mem(buf, len1); diff --git a/src/native/external/libunwind/src/os-hpux.c b/src/native/external/libunwind/src/os-hpux.c index 48bfb05cf54a00..7b8a2313cf829a 100644 --- a/src/native/external/libunwind/src/os-hpux.c +++ b/src/native/external/libunwind/src/os-hpux.c @@ -38,6 +38,7 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, { struct load_module_desc lmd; const char *path2; + int ret; if (pid != getpid ()) { @@ -63,7 +64,11 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, } Debug(1, "segbase=%lx, mapoff=%lx, path=%s\n", *segbase, *mapoff, path); - return elf_map_image (ei, path); + if (ei) + ret = elf_map_image (ei, path); + else + ret = strlen (path2) >= path ? -UNW_ENOMEM : UNW_ESUCCESS; + return ret; } #ifndef UNW_REMOTE_ONLY diff --git a/src/native/external/libunwind/src/os-linux.c b/src/native/external/libunwind/src/os-linux.c index f61050c82c2a3e..b47abc394b8623 100644 --- a/src/native/external/libunwind/src/os-linux.c +++ b/src/native/external/libunwind/src/os-linux.c @@ -33,20 +33,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "libunwind_i.h" #include "os-linux.h" -#define FULL_PATH_BUFF_SZ 1024 - 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; + int found = 0, rc = UNW_ESUCCESS; unsigned long hi; char root[sizeof ("/proc/0123456789/root")], *cp; char *full_path; struct stat st; - char full_path_buff[FULL_PATH_BUFF_SZ]; if (maps_init (&mi, pid) < 0) return -1; @@ -64,6 +61,18 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, return -1; } + // get path only, no need to map elf image + if (!ei && path) + { + strncpy(path, mi.path, pathlen); + path[pathlen - 1] = '\0'; + if (strlen(mi.path) >= pathlen) + rc = -UNW_ENOMEM; + + maps_close (&mi); + return rc; + } + full_path = mi.path; /* Get process root */ @@ -72,34 +81,30 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, assert (cp + 6 < root + sizeof (root)); memcpy (cp, "/root", 6); + size_t _len = strlen (mi.path) + 1; if (!stat(root, &st) && S_ISDIR(st.st_mode)) + _len += strlen (root); + else + root[0] = '\0'; + + full_path = path; + if(!path) + full_path = (char*) malloc (_len); + else if(_len >= pathlen) // passed buffer is too small, fail { - size_t _len = strlen(root) + strlen(mi.path) + 1; - if(_len >= FULL_PATH_BUFF_SZ) - { - full_path = (char*) malloc(_len); - } - else - { - snprintf(full_path_buff, FULL_PATH_BUFF_SZ, "%s%s", root, mi.path); - full_path = &full_path_buff[0]; - } - if (!full_path) - full_path = mi.path; - else - { - strcpy (full_path, root); - strcat (full_path, mi.path); - } + maps_close (&mi); + return -1; } - if (path) - { - strncpy(path, full_path, pathlen); - } + strcpy (full_path, root); + strcat (full_path, mi.path); + + if (stat(full_path, &st) || !S_ISREG(st.st_mode)) + strcpy(full_path, mi.path); + rc = elf_map_image (ei, full_path); - if (full_path && full_path != mi.path && full_path != &full_path_buff[0]) + if (!path) free (full_path); maps_close (&mi); diff --git a/src/native/external/libunwind/src/os-linux.h b/src/native/external/libunwind/src/os-linux.h index 29aab5cf40ae47..fb1d4f50fd2faa 100644 --- a/src/native/external/libunwind/src/os-linux.h +++ b/src/native/external/libunwind/src/os-linux.h @@ -77,9 +77,8 @@ maps_init (struct map_iterator *mi, pid_t pid) { /* Try to allocate a page-sized buffer. */ mi->buf_size = getpagesize (); - cp = mmap (NULL, mi->buf_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (cp == MAP_FAILED) + GET_MEMORY (cp, mi->buf_size); + if (!cp) { close(mi->fd); mi->fd = -1; @@ -120,10 +119,10 @@ scan_hex (char *cp, unsigned long *valp) digit = *cp; if ((digit - '0') <= 9) digit -= '0'; - else if ((digit - 'a') < 6) - digit -= 'a' - 10; else if ((digit - 'A') < 6) digit -= 'A' - 10; + else if ((digit - 'a') < 6) + digit -= 'a' - 10; else break; val = (val << 4) | digit; @@ -306,7 +305,7 @@ maps_close (struct map_iterator *mi) mi->fd = -1; if (mi->buf) { - munmap (mi->buf_end - mi->buf_size, mi->buf_size); + mi_munmap (mi->buf_end - mi->buf_size, mi->buf_size); mi->buf = mi->buf_end = NULL; } } diff --git a/src/native/external/libunwind/src/os-qnx.c b/src/native/external/libunwind/src/os-qnx.c index 4a76c7cda41a5f..f306929e677a27 100644 --- a/src/native/external/libunwind/src/os-qnx.c +++ b/src/native/external/libunwind/src/os-qnx.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2013 Garmin International Contributed by Matt Fischer + Copyright (c) 2022-2023 BlackBerry Limited. All rights reserved. This file is part of libunwind. @@ -23,85 +24,308 @@ 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" +#include "os-qnx.h" + +#include +#include #include +#include +#include +#include -#include "libunwind_i.h" + +#if __PTR_BITS__ == 32 +typedef Elf32_Ehdr elf_ehdr_t; +typedef Elf32_Phdr elf_phdr_t; +#else +typedef Elf64_Ehdr elf_ehdr_t; +typedef Elf64_Phdr elf_phdr_t; +#endif struct cb_info { - unw_word_t ip; - unsigned long segbase; - unsigned long offset; - const char *path; + unw_word_t ip; + unsigned long segbase; + unsigned long offset; + const char *path; }; -static int callback(const struct dl_phdr_info *info, size_t size, void *data) +static int +phdr_callback(const struct dl_phdr_info *info, size_t size, void *data) { int i; struct cb_info *cbi = (struct cb_info*)data; - for(i=0; idlpi_phnum; i++) { - int segbase = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; - if(cbi->ip >= segbase && cbi->ip < segbase + info->dlpi_phdr[i].p_memsz) + for(i=0; idlpi_phnum; i++) { - cbi->path = info->dlpi_name; - cbi->offset = info->dlpi_phdr[i].p_offset; - cbi->segbase = segbase; - return 1; + unw_word_t segbase = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; + if(cbi->ip >= segbase && cbi->ip < segbase + info->dlpi_phdr[i].p_memsz) + { + cbi->path = info->dlpi_name; + cbi->offset = info->dlpi_phdr[i].p_offset; + cbi->segbase = segbase; + return 1; + } } - } return 0; } -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) + +/** + * Gets the number of mapped segments loaded in the target process image. + * + * @param[in] ctl_fd file descriptor for the process control file + * + * @returns the number of mapped segments loaded in the process image. + */ +static int +_get_map_count(int ctl_fd) { - struct cb_info cbi; - int ret = -1; - cbi.ip = ip; - cbi.segbase = 0; - cbi.offset = 0; - cbi.path = NULL; - - /* QNX's support for accessing symbol maps is severely broken. There is - a devctl() call that can be made on a proc node (DCMD_PROC_MAPDEBUG) - which returns information similar to Linux's /proc//maps - node, however the filename that is returned by this call is not an - absolute path, and there is no foolproof way to map the filename - back to the file that it came from. - - Therefore, the normal approach for implementing this function, - which works equally well for both local and remote unwinding, - will not work here. The only type of image lookup which works - reliably is locally, using dl_iterate_phdr(). However, the only - time that this function is required to look up a remote image is for - ptrace support, which doesn't work on QNX anyway. Local unwinding, - which is the main case that makes use of this function, will work - fine with dl_iterate_phdr(). Therefore, in lieu of any better - platform support for remote image lookup, this function has just - been implemented in terms of dl_iterate_phdr(). - */ + int count = 0; + int err = devctl(ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &count); + if (err != EOK) + { + fprintf(stderr, "error %d in devctl(DCMD_PROC_MAPINFO): %s\n", err, strerror(err)); + return 0; + } - if (pid != getpid()) - { - /* Return an error if an attempt is made to perform remote image lookup */ - return -1; - } + return count; +} - if (dl_iterate_phdr (callback, &cbi) != 0) + +/** + * Read some bytes from the procfs address space file for the target process. + * + * @param[in] as_fd file descriptor of te opened address space file + * @param[in] pos offset within the file to start the read + * @param[in] sz number of bytes to read + * @param[out] buf destination in which to read the bytes + * + * @returns the number of bytes read. On failure to read, a byte count of 0 is + * returned and errno is set appropriately. + */ +static int +_read_procfs_as(int as_fd, + uintptr_t pos, + size_t sz, + void *buf) +{ + if (lseek(as_fd, (off_t)pos, SEEK_SET) == -1) + { + fprintf(stderr, "error %d in lseek(%" PRIxPTR "): %s\n", errno, pos, strerror(errno)); + return 0; + } + + size_t bytes_read = 0; + for (size_t readn = sz; readn > 0; ) + { + int ret = read(as_fd, buf + bytes_read, readn); + if (ret <= 0) + { + if (errno == EINTR || errno == EAGAIN) + { + continue; + } + else if (ret == 0) + { + errno = EFAULT; + } + return 0; + } + bytes_read += ret; + readn -= ret; + } + + return sz; +} + + +/** + * Indicate of a chunk of memory is a valid ELF header. + * + * @param[in] e_ident A (putative) ELF header + * + * @return true if it's a valid ELF header, false otherwise. + */ +static bool +_is_elf_header(unsigned char e_ident[EI_NIDENT]) +{ + return e_ident[EI_MAG0] == ELFMAG0 + && e_ident[EI_MAG1] == ELFMAG1 + && e_ident[EI_MAG2] == ELFMAG2 + && e_ident[EI_MAG3] == ELFMAG3; +} + + +static int +_get_remote_elf_image(struct elf_image *ei, + pid_t pid, + unw_word_t ip, + unsigned long *segbase, + unsigned long *mapoff, + char *path, + size_t pathlen) +{ + int ret = -UNW_ENOINFO; + + union { - if (path) + procfs_debuginfo i; + char path[PATH_MAX]; + } debug_info; + + int ctl_fd = unw_nto_procfs_open_ctl(pid); + if (ctl_fd < 0) + { + fprintf(stderr, "error %d opening procfs ctl file for pid %d: %s\n", + errno, pid, strerror(errno)); + return ret; + } + + int as_fd = unw_nto_procfs_open_as(pid); + if (as_fd < 0) + { + fprintf(stderr, "error %d opening procfs as file for pid %d: %s\n", + errno, pid, strerror(errno)); + close(ctl_fd); + return -UNW_ENOINFO; + } + + int map_count = _get_map_count(ctl_fd); + size_t maps_size = sizeof(procfs_mapinfo) * map_count; + procfs_mapinfo *maps = malloc(maps_size); + if (maps == NULL) + { + fprintf(stderr, "error %d in malloc(%zu): %s", errno, maps_size, strerror(errno)); + close (as_fd); + close (ctl_fd); + return -UNW_ENOINFO; + } + + int nmaps = 0; + ret = devctl(ctl_fd, DCMD_PROC_MAPINFO, maps, maps_size, &nmaps); + if (ret != EOK) { - strncpy (path, cbi.path, pathlen); + fprintf(stderr, "error %d in devctl(DCMD_PROC_MAPINFO): %s", ret, strerror(ret)); + free(maps); + close (as_fd); + close (ctl_fd); + return -UNW_ENOINFO; } - *mapoff = cbi.offset; - *segbase = cbi.segbase; + int i = 0; + for (; i < nmaps; ++i) + { + if (maps[i].flags & (MAP_ELF | PROT_EXEC)) + { + uintptr_t vaddr = maps[i].vaddr; + + elf_ehdr_t elf_ehdr; + ret = _read_procfs_as(as_fd, vaddr, sizeof(elf_ehdr), &elf_ehdr); + if (ret != sizeof(elf_ehdr)) + { + continue; + } + + /* Skip region if it's not an ELF segment. */ + if (!_is_elf_header(elf_ehdr.e_ident)) + { + continue; + } + size_t size = elf_ehdr.e_ehsize; + + debug_info.i.vaddr = vaddr; + debug_info.i.path[0]=0; + ret = devctl(ctl_fd, DCMD_PROC_MAPDEBUG, &debug_info, sizeof(debug_info), 0); + if (ret != EOK) + { + fprintf(stderr, "error %d in devctl(DCMD_PROC_MAPDEBUG): %s", ret, strerror(ret)); + continue; + } + uintptr_t reloc = debug_info.i.vaddr; + + elf_phdr_t elf_phdr; + uintptr_t phdr_offset = vaddr + elf_ehdr.e_phoff; + for (int i = 0; i < elf_ehdr.e_phnum; ++i, phdr_offset+=elf_ehdr.e_phentsize) + { + ret = _read_procfs_as(as_fd, phdr_offset, sizeof(elf_phdr_t), &elf_phdr); + if (ret == -1) + { + continue; + } + if (elf_phdr.p_type == PT_LOAD && !(elf_phdr.p_flags&PF_W)) + { + size += elf_phdr.p_memsz; + } + } + + /* Skip segment if the IP is not contained within it. */ + if ((ip < vaddr) || (ip >= (vaddr + size))) + { + continue; + } + + *segbase = vaddr; + *mapoff = reloc; + if (path) + { + strncpy(path, debug_info.i.path, pathlen); + path[pathlen - 1] = '\0'; + } + + if (ei) + ret = elf_map_image(ei, path); + else + ret = strlen (debug_info.i.path) >= pathlen ? -UNW_ENOMEM : UNW_ESUCCESS; - ret = elf_map_image (ei, cbi.path); - } + break; + } + } + + free(maps); + close(as_fd); + close(ctl_fd); + return i == nmaps ? -UNW_ENOINFO : ret; +} + + +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) +{ + int ret = -UNW_ENOINFO; + if (pid != getpid()) + { + ret = _get_remote_elf_image(ei, pid, ip, segbase, mapoff, path, pathlen); + return ret; + } + else + { + struct cb_info cbi; + cbi.ip = ip; + cbi.segbase = 0; + cbi.offset = 0; + cbi.path = NULL; + + if (dl_iterate_phdr (phdr_callback, &cbi) != 0) + { + if (path) + { + strncpy (path, cbi.path, pathlen); + path[pathlen - 1] = '\0'; + } + + *mapoff = cbi.offset; + *segbase = cbi.segbase; + + if (ei) + ret = elf_map_image (ei, cbi.path); + else + ret = strlen (cbi.path) >= pathlen ? -UNW_ENOMEM : UNW_ESUCCESS; + } + } return ret; } diff --git a/src/native/external/libunwind/src/os-qnx.h b/src/native/external/libunwind/src/os-qnx.h new file mode 100644 index 00000000000000..daf0b39f142baf --- /dev/null +++ b/src/native/external/libunwind/src/os-qnx.h @@ -0,0 +1,118 @@ +/* + * Copyright 2022-2023 BlackBerry Limited. + * + * 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 OS_QNX_H +#define OS_QNX_H + +#include +#include +#include +#include +#include +#include + + +/** + * Return a buffer contaiing the procfs file name, or NULL on failure. + * @param[in] pid Identify the target process + * @param[in] ftype The type of procfs file to name. + * + * @returns a pointer to a newly-allocated string containing the name of the + * procfs file of type @p ftype for process @p pid. The returned buffer needs to + * be free()d. Returns NULL on error and errno is set appropriately. + */ +static inline char * +get_proc_filename(pid_t pid, char const *ftype) +{ + char *filename = NULL; + int pathlen = snprintf(NULL, 0, "/proc/%d/%s", pid, ftype); + int saved_errno = errno; + if (pathlen > 0) + { + ++pathlen; + filename = malloc(pathlen); + saved_errno = errno; + if (filename != NULL) + { + int len = snprintf(filename, pathlen, "/proc/%d/%s", pid, ftype); + saved_errno = errno; + if (len < 0) + { + free(filename); + filename = NULL; + } + } + } + errno = saved_errno; + return filename; +} + +/** + * Opens the procfs address space file for a process. + * @param[in] pid Identify the target process. + * + * @returns a valid file descriptor for the opened procfs address space file or + * -1 on failure (and errno is set appropriately). + */ +static inline int +unw_nto_procfs_open_as(pid_t pid) +{ + int as_fd = -1; + char *as_filename = get_proc_filename(pid, "as"); + if (as_filename != NULL) + { + as_fd = open(as_filename, O_CLOEXEC | O_RDONLY); + int saved_errno = errno; + free(as_filename); + errno = saved_errno; + } + return as_fd; +} + + +/** + * Opens the procfs control file for a process. + * @param[in] pid Identify the target process. + * + * @returns a valid file descriptor for the opened procfs control file or + * -1 on failure (and errno is set appropriately). + */ +static inline int +unw_nto_procfs_open_ctl(pid_t pid) +{ + int ctl_fd = -1; + char *ctl_filename = get_proc_filename(pid, "ctl"); + if (ctl_filename != NULL) + { + ctl_fd = open(ctl_filename, O_CLOEXEC | O_RDWR); + int saved_errno = errno; + free(ctl_filename); + errno = saved_errno; + } + return ctl_fd; +} + + + +#endif /* OS_QNX_H */ diff --git a/src/native/external/libunwind/src/os-solaris.c b/src/native/external/libunwind/src/os-solaris.c index f0210db1f2b72d..032bacf6711fd0 100644 --- a/src/native/external/libunwind/src/os-solaris.c +++ b/src/native/external/libunwind/src/os-solaris.c @@ -35,7 +35,7 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, char *path, size_t pathlen) { struct map_iterator mi; - int found = 0, rc; + int found = 0, rc = UNW_ESUCCESS; unsigned long hi; if (maps_init (&mi, pid) < 0) @@ -53,11 +53,18 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, maps_close (&mi); return -1; } + if (path) { strncpy(path, mi.path, pathlen); + path[pathlen - 1] = '\0'; } - rc = elf_map_image (ei, mi.path); + + if (ei) + rc = elf_map_image (ei, mi.path); + else + rc = strlen(mi.path) >= pathlen ? -UNW_ENOMEM : UNW_ESUCCESS:; + maps_close (&mi); return rc; } diff --git a/src/native/external/libunwind/src/ppc32/Ginit.c b/src/native/external/libunwind/src/ppc32/Ginit.c index d978a775265328..9444cbb867be72 100644 --- a/src/native/external/libunwind/src/ppc32/Ginit.c +++ b/src/native/external/libunwind/src/ppc32/Ginit.c @@ -127,14 +127,20 @@ static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, void *arg) { + if (unlikely (as->validate) && unlikely (!unw_address_is_valid (addr, sizeof(unw_word_t)))) + { + Debug (16, "mem[%#010lx] invalid\n", (long)addr); + return -1; + } + if (write) { Debug (12, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "mem[%lx] -> %lx\n", addr, *val); } return 0; @@ -157,12 +163,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- %lx\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %lx\n", unw_regname (reg), *val); } return 0; @@ -212,10 +218,23 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void ppc32_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; @@ -225,6 +244,7 @@ ppc32_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = ppc32_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/ppc32/Gstep.c b/src/native/external/libunwind/src/ppc32/Gstep.c index 478d3a6c1b89f5..0ba07b2cda85cf 100644 --- a/src/native/external/libunwind/src/ppc32/Gstep.c +++ b/src/native/external/libunwind/src/ppc32/Gstep.c @@ -57,6 +57,7 @@ unw_step (unw_cursor_t * cursor) unw_word_t back_chain_offset, lr_save_offset; struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc; int ret; + int validate = c->dwarf.as->validate; Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); @@ -69,7 +70,9 @@ unw_step (unw_cursor_t * cursor) /* Try DWARF-based unwinding... */ + c->dwarf.as->validate = 1; ret = dwarf_step (&c->dwarf); + c->dwarf.as->validate = validate; if (ret < 0 && ret != -UNW_ENOINFO) { diff --git a/src/native/external/libunwind/src/ppc32/ucontext_i.h b/src/native/external/libunwind/src/ppc32/ucontext_i.h index 64f8ed878ad8e7..ee93c697941c31 100644 --- a/src/native/external/libunwind/src/ppc32/ucontext_i.h +++ b/src/native/external/libunwind/src/ppc32/ucontext_i.h @@ -44,8 +44,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ //#define MQ_IDX 36 #define LINK_IDX 36 -#define _UC_MCONTEXT_GPR(x) ( (void *)&dmy_ctxt.uc_mcontext.gregs[x] - (void *)&dmy_ctxt) ) -#define _UC_MCONTEXT_FPR(x) ( ((void *)&dmy_ctxt.uc_mcontext.fpregs[x] - (void *)&dmy_ctxt) ) +#define _UC_MCONTEXT_GPR(x) ( ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[x] - (void *)&dmy_ctxt) ) +#define _UC_MCONTEXT_FPR(x) ( ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[x] - (void *)&dmy_ctxt) ) /* These are dummy structures used only for obtaining the offsets of the various structure members. */ diff --git a/src/native/external/libunwind/src/ppc64/Ginit.c b/src/native/external/libunwind/src/ppc64/Ginit.c index b9683ae2dd6519..8c54bab8a972fa 100644 --- a/src/native/external/libunwind/src/ppc64/Ginit.c +++ b/src/native/external/libunwind/src/ppc64/Ginit.c @@ -135,14 +135,20 @@ static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, void *arg) { + if (unlikely (as->validate) && unlikely (!unw_address_is_valid (addr, sizeof(unw_word_t)))) + { + Debug (16, "mem[%#010lx] invalid\n", (long)addr); + return -1; + } + if (write) { Debug (12, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "mem[%lx] -> %lx\n", addr, *val); } return 0; @@ -166,12 +172,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- %lx\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %lx\n", unw_regname (reg), *val); } return 0; @@ -223,6 +229,14 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void ppc64_local_addr_space_init (void) { @@ -232,6 +246,11 @@ ppc64_local_addr_space_init (void) local_addr_space.abi = UNW_PPC64_ABI_ELFv2; #else local_addr_space.abi = UNW_PPC64_ABI_ELFv1; +#endif +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif #endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; @@ -242,6 +261,7 @@ ppc64_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = ppc64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/ppc64/Gstep.c b/src/native/external/libunwind/src/ppc64/Gstep.c index 27c8bebc644765..ac6de903c975ac 100644 --- a/src/native/external/libunwind/src/ppc64/Gstep.c +++ b/src/native/external/libunwind/src/ppc64/Gstep.c @@ -50,6 +50,126 @@ typedef struct /* many more fields here, but they are unused by this code */ } stack_frame_t; +//! Recognise PLT entries +/*! For example: + 0x000000001000d1f0 <+0>: 18 00 41 f8 std r2,24(r1) + 0x000000001000d1f4 <+4>: 30 87 82 e9 ld r12,-30928(r2) + 0x000000001000d1f8 <+8>: a6 03 89 7d mtctr r12 + 0x000000001000d1fc <+12>: 20 04 80 4e bctr + + \note The current implementation only supports little endian modes. +*/ +static int +is_plt_entry (struct dwarf_cursor *c) +{ + unw_word_t w0, w1; + unw_accessors_t *a; + + if (c->as->big_endian) + { + return 0; + } + + /* + A PLT (Procedure Linkage Table) is used by the dynamic linker to map the + relative address of a position independent function call onto the real + address of the function. If we attempt to unwind from any instruction + inside the PLT, and the PLT is missing DWARF unwind information, then + conventional unwinding will fail because although the function has been + "called" we have not yet entered the prologue and set-up the stack frame. + + This code looks to see if the instruction is anywhere within a "recognised" + PLT entry (note that the IP could be anywhere within the PLT, so we have to + examine nearby instructions). + */ + + struct instruction_entry + { + uint32_t pattern; + uint32_t mask; + } instructions[4] = + { + // ppc64le + {0xf8410018,0xffffffff}, + {0xe9820000,0xffff0000}, + {0x7d8903a6,0xffffffff}, + {0x4e800420,0xffffffff}, + }; + + a = unw_get_accessors (c->as); + + if( (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg) < 0 ) + { + return 0; + } + + /* + NB: the following code is endian sensitive! + + The current implementation is for little-endian modes, big-endian modes + will see the first instruction in the high bits of w0, and the second + instruction in the low bits of w0. Some tweaks will be needed to read from + the correct part of the word to support big endian modes. + */ + if(( w0 & instructions[0].mask) == instructions[0].pattern && + ((w0>>32) & instructions[1].mask) == instructions[1].pattern) + { + if( (*a->access_mem) (c->as, c->ip+8, &w1, 0, c->as_arg) >= 0 && + ( w1 & instructions[2].mask) == instructions[2].pattern && + ((w1>>32) & instructions[3].mask) == instructions[3].pattern ) + { + return 1; + } + else + { + return 0; + } + } + else if(( w0 & instructions[2].mask) == instructions[2].pattern && + ((w0>>32) & instructions[3].mask) == instructions[3].pattern) + { + w1 = w0; + if( (*a->access_mem) (c->as, c->ip-8, &w0, 0, c->as_arg) >= 0 && + ( w0 & instructions[0].mask) == instructions[0].pattern && + ((w0>>32) & instructions[1].mask) == instructions[1].pattern ) + { + return 1; + } + else + { + return 0; + } + } + else if(( w0 & instructions[1].mask) == instructions[1].pattern && + ((w0>>32) & instructions[2].mask) == instructions[2].pattern) + { + if( (*a->access_mem) (c->as, c->ip-4, &w0, 0, c->as_arg) < 0 || + (*a->access_mem) (c->as, c->ip+4, &w1, 0, c->as_arg) < 0 ) + { + return 0; + } + } + else if( (w0 & instructions[3].mask) == instructions[3].pattern ) + { + if( (*a->access_mem) (c->as, c->ip-12, &w0, 0, c->as_arg) < 0 || + (*a->access_mem) (c->as, c->ip-4, &w1, 0, c->as_arg) < 0 ) + { + return 0; + } + } + + if(( w0 & instructions[0].mask) == instructions[0].pattern && + ((w0>>32) & instructions[1].mask) == instructions[1].pattern && + ( w1 & instructions[2].mask) == instructions[2].pattern && + ((w1>>32) & instructions[3].mask) == instructions[3].pattern ) + { + return 1; + } + else + { + return 0; + } +} int unw_step (unw_cursor_t * cursor) @@ -59,12 +179,15 @@ unw_step (unw_cursor_t * cursor) unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr; struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc; int ret, i; + int validate = c->dwarf.as->validate; Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); /* Try DWARF-based unwinding... */ + c->dwarf.as->validate = 1; ret = dwarf_step (&c->dwarf); + c->dwarf.as->validate = validate; if (ret < 0 && ret != -UNW_ENOINFO) { @@ -76,49 +199,97 @@ unw_step (unw_cursor_t * cursor) { if (likely (unw_is_signal_frame (cursor) <= 0)) { - /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode - produces the mandatory level of traceback record in the code, but - I get the impression that this is transitory, that eventually gcc - will not produce any traceback records at all. So, for now, we - won't bother to try to find and use these records. - - We can, however, attempt to unwind the frame by using the callback - chain. This is very crude, however, and won't be able to unwind - any registers besides the IP, SP, and LR . */ - - back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); - lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); - - back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); - - if ((ret = - dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) + /* DWARF failed. */ + if (is_plt_entry (&c->dwarf)) { - Debug (2, - "Unable to retrieve CFA from back chain in stack frame - %d\n", - ret); - return ret; + Debug (2, "found plt entry\n"); + + /* + Fallback mode that uses the link register. This is important + for cases where a function without unwind information has been + called, but not yet set-up its stack frame (basically PLT calls). + + In this case we can't trust c->dwarf.cfa (the stack frame) + because it will currently point to the caller's stack frame - + but we can use the current value of the link register to get + back to the caller. We then have to hope that libunwind manages + to resume unwinding properly from the caller IP. + */ + c->dwarf.loc[UNW_PPC64_NIP] = c->dwarf.loc[UNW_PPC64_LR]; + c->dwarf.loc[UNW_PPC64_LR] = DWARF_NULL_LOC; + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[UNW_PPC64_NIP])) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC64_NIP], &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "failed to get pc from link register: %d\n", ret); + return ret; + } + Debug (2, "link register = 0x%016lx\n", c->dwarf.ip); + ret = 1; + } + else + { + Debug (2, "link register was not saved\n"); + c->dwarf.ip = 0; + } } - if (c->dwarf.cfa == 0) - /* Unless the cursor or stack is corrupt or uninitialized we've most - likely hit the top of the stack */ - return 0; - - lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); - - if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) + else { - Debug (2, - "Unable to retrieve IP from lr save in stack frame - %d\n", - ret); - return ret; + /* + Fallback mode that uses a conventional stack unwinding. This is + important for functions without proper DWARF unwind information, + in particular without this fallback the clone() function will not + unwind properly. + + We do the unwind by first looking for the caller stack pointer + saved in the current stack frame. This will point to the caller's + 'linkage area'. If the caller stack pointer is null, we assume we + have reached the top of the stack. + + The address 24(SP) (where SP is the caller stack pointer) contains + the saved 'link register', the link register is effectively the + return address for the called function - so we can use the link + register to get an IP inside the calling function. + + Note: there is no requirement for leaf functions to save the + stack pointer or link register, I'm not entirely sure why + libunwind doesn't handle this case. + */ + Debug (2, "fallback\n"); + + back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); + lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); + + back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); + + if ((ret = + dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) + { + Debug (2, + "Unable to retrieve CFA from back chain in stack frame - %d\n", + ret); + return ret; + } + if (c->dwarf.cfa == 0) + /* Unless the cursor or stack is corrupt or uninitialized we've most + likely hit the top of the stack */ + return 0; + + lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); + + if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) + { + Debug (2, + "Unable to retrieve IP from lr save in stack frame - %d\n", + ret); + return ret; + } + ret = 1; + /* Mark all registers unsaved */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; } - - /* Mark all registers unsaved */ - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - ret = 1; } else { diff --git a/src/native/external/libunwind/src/ptrace/_UPT_access_fpreg.c b/src/native/external/libunwind/src/ptrace/_UPT_access_fpreg.c index 3b993ed15fcdeb..7d8eee83d8ea5e 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_access_fpreg.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_access_fpreg.c @@ -28,7 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if HAVE_DECL_PTRACE_POKEUSER || defined(HAVE_TTRACE) int -_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, +_UPT_access_fpreg (unw_addr_space_t as UNUSED, unw_regnum_t reg, unw_fpreg_t *val, int write, void *arg) { unw_word_t *wp = (unw_word_t *) val; @@ -107,7 +107,11 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, #elif defined(__i386__) memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); #elif defined(__arm__) +# if __FreeBSD_version >= 1400079 + memcpy(&fpreg.fpr_r[reg], val, sizeof(unw_fpreg_t)); +# else memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); +# endif #elif defined(__aarch64__) memcpy(&fpreg.fp_q[reg], val, sizeof(unw_fpreg_t)); #elif defined(__powerpc__) @@ -123,7 +127,11 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, #elif defined(__i386__) memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); #elif defined(__arm__) - memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t)); +# if __FreeBSD_version >= 1400079 + memcpy(&fpreg.fpr_r[reg], val, sizeof(unw_fpreg_t)); +# else + memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); +# endif #elif defined(__aarch64__) memcpy(val, &fpreg.fp_q[reg], sizeof(unw_fpreg_t)); #elif defined(__powerpc__) diff --git a/src/native/external/libunwind/src/ptrace/_UPT_access_mem.c b/src/native/external/libunwind/src/ptrace/_UPT_access_mem.c index 5d6511c56c6c25..5892982cd7d7bb 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_access_mem.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_access_mem.c @@ -28,7 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if HAVE_DECL_PTRACE_POKEDATA || defined(HAVE_TTRACE) int -_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, +_UPT_access_mem (unw_addr_space_t as UNUSED, unw_word_t addr, unw_word_t *val, int write, void *arg) { struct UPT_info *ui = arg; diff --git a/src/native/external/libunwind/src/ptrace/_UPT_access_reg.c b/src/native/external/libunwind/src/ptrace/_UPT_access_reg.c index 033d3aae7f4eaa..316ad19b8abaca 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_access_reg.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_access_reg.c @@ -34,10 +34,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # include "tdep-ia64/rse.h" #endif -#if HAVE_DECL_PTRACE_SETREGSET +#if HAVE_DECL_PTRACE_SETREGSET && (defined(__linux__) && !defined(UNW_TARGET_X86)) #include int -_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, +_UPT_access_reg (unw_addr_space_t as UNUSED, unw_regnum_t reg, unw_word_t *val, int write, void *arg) { struct UPT_info *ui = arg; @@ -77,9 +77,9 @@ _UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); return -UNW_EBADREG; } -#elif HAVE_DECL_PTRACE_POKEUSER || defined(HAVE_TTRACE) +#elif (HAVE_DECL_PTRACE_POKEUSER || defined(HAVE_TTRACE)) && (defined(__linux__) && !defined(UNW_TARGET_X86)) int -_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, +_UPT_access_reg (UNUSED unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, void *arg) { struct UPT_info *ui = arg; @@ -321,10 +321,49 @@ _UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); return -UNW_EBADREG; } -#elif HAVE_DECL_PT_GETREGS +#elif defined(HAVE_DECL_PT_GETREGS) && defined(__linux__) +# include + int _UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + struct user_regs_struct regs; + char *r; + +#if UNW_DEBUG + Debug(16, "using getregs: reg: %s [%u], val: %lx, write: %u\n", unw_regname(reg), (unsigned) reg, (long) val, write); + + if (write) + Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); +#endif + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + { + errno = EINVAL; + goto badreg; + } + r = (char *)®s + _UPT_reg_offset[reg]; + if (ptrace(PT_GETREGS, pid, NULL, ®s) == -1) + goto badreg; + if (write) { + memcpy(r, val, sizeof(unw_word_t)); + if (ptrace(PT_SETREGS, pid, NULL, ®s) == -1) + goto badreg; + } else + memcpy(val, r, sizeof(unw_word_t)); + return 0; + + badreg: + Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); + return -UNW_EBADREG; +} + +#elif defined(HAVE_DECL_PT_GETREGS) && defined(__FreeBSD__) +int +_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) { struct UPT_info *ui = arg; pid_t pid = ui->pid; @@ -337,6 +376,7 @@ _UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, if (write) Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); #endif + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) { errno = EINVAL; diff --git a/src/native/external/libunwind/src/ptrace/_UPT_accessors.c b/src/native/external/libunwind/src/ptrace/_UPT_accessors.c index 4724360bb99b9c..364e70a765a7d7 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_accessors.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_accessors.c @@ -34,5 +34,6 @@ unw_accessors_t _UPT_accessors = .access_reg = _UPT_access_reg, .access_fpreg = _UPT_access_fpreg, .resume = _UPT_resume, - .get_proc_name = _UPT_get_proc_name + .get_proc_name = _UPT_get_proc_name, + .get_elf_filename = _UPT_get_elf_filename }; diff --git a/src/native/external/libunwind/src/ptrace/_UPT_create.c b/src/native/external/libunwind/src/ptrace/_UPT_create.c index dd59e974a7eafc..1536c27e9e853d 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_create.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_create.c @@ -32,6 +32,8 @@ _UPT_create (pid_t pid) { struct UPT_info *ui = malloc (sizeof (struct UPT_info)); + mi_init (); + if (!ui) return NULL; diff --git a/src/native/external/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/native/external/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c index a71f80d3dbd9d5..3156acfdaf115e 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c @@ -77,8 +77,10 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, DWARF2 unwind info. */ static inline int -get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, - int *countp) +get_list_addr (unw_addr_space_t as UNUSED, + unw_word_t *dil_addr UNUSED, + void *arg UNUSED, + int *countp) { # warning Implement get_list_addr(), please. *countp = 0; diff --git a/src/native/external/libunwind/src/ptrace/_UPT_get_elf_filename.c b/src/native/external/libunwind/src/ptrace/_UPT_get_elf_filename.c new file mode 100644 index 00000000000000..401de3d18145c7 --- /dev/null +++ b/src/native/external/libunwind/src/ptrace/_UPT_get_elf_filename.c @@ -0,0 +1,38 @@ +/* + * 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 "_UPT_internal.h" + +int +_UPT_get_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + struct UPT_info *ui = arg; + +#if UNW_ELF_CLASS == UNW_ELFCLASS64 + return _Uelf64_get_elf_filename (as, ui->pid, ip, buf, buf_len, offp); +#elif UNW_ELF_CLASS == UNW_ELFCLASS32 + return _Uelf32_get_elf_filename (as, ui->pid, ip, buf, buf_len, offp); +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/native/external/libunwind/src/ptrace/_UPT_put_unwind_info.c b/src/native/external/libunwind/src/ptrace/_UPT_put_unwind_info.c index d4b84631476b6b..54989a769a70d3 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_put_unwind_info.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_put_unwind_info.c @@ -26,7 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UPT_internal.h" void -_UPT_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +_UPT_put_unwind_info (unw_addr_space_t as UNUSED, unw_proc_info_t *pi, void *arg UNUSED) { if (!pi->unwind_info) return; diff --git a/src/native/external/libunwind/src/ptrace/_UPT_reg_offset.c b/src/native/external/libunwind/src/ptrace/_UPT_reg_offset.c index ea13e6de88cf81..02e0ec6d893662 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_reg_offset.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_reg_offset.c @@ -623,64 +623,6 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] = [UNW_AARCH64_SP] = 0xf8, [UNW_AARCH64_PC] = 0x100, [UNW_AARCH64_PSTATE] = 0x108 -#elif defined(UNW_TARGET_TILEGX) - [UNW_TILEGX_R0] = 0x00, - [UNW_TILEGX_R1] = 0x08, - [UNW_TILEGX_R2] = 0x10, - [UNW_TILEGX_R3] = 0x08, - [UNW_TILEGX_R4] = 0x20, - [UNW_TILEGX_R5] = 0x28, - [UNW_TILEGX_R6] = 0x30, - [UNW_TILEGX_R7] = 0x38, - [UNW_TILEGX_R8] = 0x40, - [UNW_TILEGX_R9] = 0x48, - [UNW_TILEGX_R10] = 0x50, - [UNW_TILEGX_R11] = 0x58, - [UNW_TILEGX_R12] = 0x60, - [UNW_TILEGX_R13] = 0x68, - [UNW_TILEGX_R14] = 0x70, - [UNW_TILEGX_R15] = 0x78, - [UNW_TILEGX_R16] = 0x80, - [UNW_TILEGX_R17] = 0x88, - [UNW_TILEGX_R18] = 0x90, - [UNW_TILEGX_R19] = 0x98, - [UNW_TILEGX_R20] = 0xa0, - [UNW_TILEGX_R21] = 0xa8, - [UNW_TILEGX_R22] = 0xb0, - [UNW_TILEGX_R23] = 0xb8, - [UNW_TILEGX_R24] = 0xc0, - [UNW_TILEGX_R25] = 0xc8, - [UNW_TILEGX_R26] = 0xd0, - [UNW_TILEGX_R27] = 0xd8, - [UNW_TILEGX_R28] = 0xe0, - [UNW_TILEGX_R29] = 0xe8, - [UNW_TILEGX_R30] = 0xf0, - [UNW_TILEGX_R31] = 0xf8, - [UNW_TILEGX_R32] = 0x100, - [UNW_TILEGX_R33] = 0x108, - [UNW_TILEGX_R34] = 0x110, - [UNW_TILEGX_R35] = 0x118, - [UNW_TILEGX_R36] = 0x120, - [UNW_TILEGX_R37] = 0x128, - [UNW_TILEGX_R38] = 0x130, - [UNW_TILEGX_R39] = 0x138, - [UNW_TILEGX_R40] = 0x140, - [UNW_TILEGX_R41] = 0x148, - [UNW_TILEGX_R42] = 0x150, - [UNW_TILEGX_R43] = 0x158, - [UNW_TILEGX_R44] = 0x160, - [UNW_TILEGX_R45] = 0x168, - [UNW_TILEGX_R46] = 0x170, - [UNW_TILEGX_R47] = 0x178, - [UNW_TILEGX_R48] = 0x180, - [UNW_TILEGX_R49] = 0x188, - [UNW_TILEGX_R50] = 0x190, - [UNW_TILEGX_R51] = 0x198, - [UNW_TILEGX_R52] = 0x1a0, - [UNW_TILEGX_R53] = 0x1a8, - [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, diff --git a/src/native/external/libunwind/src/ptrace/_UPT_resume.c b/src/native/external/libunwind/src/ptrace/_UPT_resume.c index d70a0d48218f05..9ca5224cd800a9 100644 --- a/src/native/external/libunwind/src/ptrace/_UPT_resume.c +++ b/src/native/external/libunwind/src/ptrace/_UPT_resume.c @@ -26,10 +26,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UPT_internal.h" int -_UPT_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) +_UPT_resume (unw_addr_space_t as UNUSED, unw_cursor_t *c UNUSED, void *arg) { struct UPT_info *ui = arg; + mi_init (); + #ifdef HAVE_TTRACE # warning No support for ttrace() yet. #elif HAVE_DECL_PTRACE_CONT diff --git a/src/native/external/libunwind/src/remote/mac/missing-functions.c b/src/native/external/libunwind/src/remote/mac/missing-functions.c index f0a7b3f53f27be..119574cb79f834 100644 --- a/src/native/external/libunwind/src/remote/mac/missing-functions.c +++ b/src/native/external/libunwind/src/remote/mac/missing-functions.c @@ -74,3 +74,9 @@ UNW_OBJ(handle_signal_frame) (unw_cursor_t *cursor) { return -UNW_EBADFRAME; } + +int +UNW_OBJ(os_step) (struct cursor *c) +{ + return 0; +} diff --git a/src/native/external/libunwind/src/riscv/Gglobal.c b/src/native/external/libunwind/src/riscv/Gglobal.c index cb8009e1d2696e..9ad2e31884a414 100644 --- a/src/native/external/libunwind/src/riscv/Gglobal.c +++ b/src/native/external/libunwind/src/riscv/Gglobal.c @@ -117,8 +117,6 @@ tdep_init (void) dwarf_init (); #ifndef UNW_REMOTE_ONLY - tdep_init_mem_validate (); - riscv_local_addr_space_init (); #endif atomic_store(&tdep_init_done, 1); /* signal that we're initialized... */ diff --git a/src/native/external/libunwind/src/riscv/Ginit.c b/src/native/external/libunwind/src/riscv/Ginit.c index 4faeecbfd89f2b..861197be328e1a 100644 --- a/src/native/external/libunwind/src/riscv/Ginit.c +++ b/src/native/external/libunwind/src/riscv/Ginit.c @@ -95,233 +95,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, return 0; } -// Memory validation routines are from aarch64 - -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]); - - do_pipe2 (mem_validate_pipe); -} - -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 - { - ret = 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 */ - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ - if (mincore (addr, len, (unsigned char *)mvec) != 0) - { - return -1; - } - - return write_validate (addr); -} -#endif - -/* Initialise memory validation method. On linux kernels <2.6.21, - mincore() returns incorrect value for MAP_PRIVATE mappings, - such as stacks. If mincore() was available at compile time, - check if we can actually use it. If not, use msync() instead. */ -HIDDEN void -tdep_init_mem_validate (void) -{ - open_pipe (); - -#ifdef HAVE_MINCORE - unsigned char present = 1; - size_t len = unw_page_size; - unw_word_t addr = uwn_page_start((unw_word_t)&present); - unsigned char mvec[1]; - int ret; - while ((ret = mincore((void *)addr, len, (unsigned char *)mvec)) == -1 && - errno == EAGAIN) - { - } - if (ret == 0) - { - Debug(1, "using mincore to validate memory\n"); - mem_validate_func = mincore_validate; - } - else -#endif - { - Debug(1, "using msync to validate memory\n"); - mem_validate_func = msync_validate; - } -} - -/* Cache of already validated addresses */ -#define NLGA 4 -#if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD -// thread-local variant -static _Thread_local unw_word_t last_good_addr[NLGA]; -static _Thread_local int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (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; -} - -#else -// global, thread safe variant -static _Atomic unw_word_t last_good_addr[NLGA]; -static _Atomic int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == atomic_load(&last_good_addr[i])) - return 1; - } - return 0; -} - -static void -cache_valid_mem(unw_word_t addr) -{ - int i, victim; - victim = atomic_load(&lga_victim); - unw_word_t zero = 0; - for (i = 0; i < NLGA; i++) { - if (atomic_compare_exchange_strong(&last_good_addr[victim], &zero, addr)) { - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - atomic_store(&last_good_addr[victim], addr); - victim = (victim + 1) % NLGA; - atomic_store(&lga_victim, victim); -} -#endif - -static int -validate_mem (unw_word_t addr) -{ - size_t len = unw_page_size; - addr = uwn_page_start(addr); - - if (addr == 0) - return -1; - - if (is_cached_valid_mem(addr)) - return 0; - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - - cache_valid_mem(addr); - - return 0; -} static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, @@ -338,11 +111,11 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, const struct cursor *c = (const struct cursor *)arg; if (likely (c != NULL) && unlikely (c->validate) - && unlikely (validate_mem (addr))) { + && unlikely (!unw_address_is_valid (addr, sizeof(unw_word_t)))) { Debug (16, "mem[%016lx] -> invalid\n", addr); return -1; } - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (16, "mem[%lx] -> %lx\n", addr, *val); } return 0; @@ -369,7 +142,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %lx\n", unw_regname (reg), *val); } return 0; @@ -420,11 +193,24 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return elf_w (get_elf_filename) (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void riscv_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.addr_size = sizeof (void *); local_addr_space.acc.find_proc_info = dwarf_find_proc_info; @@ -435,6 +221,7 @@ riscv_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = riscv_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; local_addr_space.big_endian = target_is_big_endian(); unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/s390x/Gglobal.c b/src/native/external/libunwind/src/s390x/Gglobal.c index 20544a57fa0172..e201c5228942b3 100644 --- a/src/native/external/libunwind/src/s390x/Gglobal.c +++ b/src/native/external/libunwind/src/s390x/Gglobal.c @@ -90,8 +90,6 @@ tdep_init (void) dwarf_init (); #ifndef UNW_REMOTE_ONLY - tdep_init_mem_validate (); - s390x_local_addr_space_init (); #endif atomic_store(&tdep_init_done, 1); /* signal that we're initialized... */ diff --git a/src/native/external/libunwind/src/s390x/Ginit.c b/src/native/external/libunwind/src/s390x/Ginit.c index 2bce2f4b687feb..3cf07a5d71ef60 100644 --- a/src/native/external/libunwind/src/s390x/Ginit.c +++ b/src/native/external/libunwind/src/s390x/Ginit.c @@ -94,155 +94,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, return 0; } -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 + unw_page_size - 1) / unw_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; - size_t len = unw_page_size; - unw_word_t addr = uwn_page_start((unw_word_t)&present); - unsigned char mvec[1]; - int ret; - while ((ret = mincore((void *)addr, len, 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 = unw_page_size; - addr = uwn_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) @@ -250,18 +101,18 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, if (unlikely (write)) { Debug (16, "mem[%016lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { /* validate address */ const struct cursor *c = (const struct cursor *)arg; if (likely (c != NULL) && unlikely (c->validate) - && unlikely (validate_mem (addr))) { + && unlikely (!unw_address_is_valid (addr, sizeof(unw_word_t)))) { Debug (16, "mem[%016lx] -> invalid\n", addr); return -1; } - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (16, "mem[%016lx] -> %lx\n", addr, *val); } return 0; @@ -282,12 +133,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); } return 0; @@ -338,10 +189,23 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void s390x_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif 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; @@ -351,10 +215,8 @@ s390x_local_addr_space_init (void) 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; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; 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/native/external/libunwind/src/setjmp/longjmp.c b/src/native/external/libunwind/src/setjmp/longjmp.c index 8295a9b8ed40de..ced9052aa2f92b 100644 --- a/src/native/external/libunwind/src/setjmp/longjmp.c +++ b/src/native/external/libunwind/src/setjmp/longjmp.c @@ -54,6 +54,10 @@ static void longjmp (jmp_buf env, int val); #endif #endif /* __GLIBC__ */ +#ifndef _JB_STK_SHIFT +#define _JB_STK_SHIFT 0 +#endif + void _longjmp (jmp_buf env, int val) { @@ -70,11 +74,7 @@ _longjmp (jmp_buf env, int val) { if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) abort (); -#ifdef __FreeBSD__ - if (sp != wp[JB_SP] + sizeof(unw_word_t)) -#else - if (sp != wp[JB_SP]) -#endif + if (sp != (wp[JB_SP] + _JB_STK_SHIFT)) continue; if (!bsp_match (&c, wp)) diff --git a/src/native/external/libunwind/src/setjmp/setjmp_i.h b/src/native/external/libunwind/src/setjmp/setjmp_i.h index 4d9139693ecfb7..3c19185ed9d0d8 100644 --- a/src/native/external/libunwind/src/setjmp/setjmp_i.h +++ b/src/native/external/libunwind/src/setjmp/setjmp_i.h @@ -23,10 +23,13 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if UNW_TARGET_IA64 +#ifndef libunwind_setjmp_setjmp_i_h +#define libunwind_setjmp_setjmp_i_h #include "libunwind_i.h" -#include "tdep-ia64/rse.h" + +#if UNW_TARGET_IA64 +# include "tdep-ia64/rse.h" static inline int bsp_match (unw_cursor_t *c, unw_word_t *wp) @@ -103,16 +106,18 @@ resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) #else /* !UNW_TARGET_IA64 */ static inline int -bsp_match (unw_cursor_t *c, unw_word_t *wp) +bsp_match (unw_cursor_t *c UNUSED, unw_word_t *wp UNUSED) { return 1; } static inline int -resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) +resume_restores_sigmask (unw_cursor_t *c UNUSED, unw_word_t *wp UNUSED) { /* We may want to do this analogously as for ia64... */ return 0; } #endif /* !UNW_TARGET_IA64 */ + +#endif /* libunwind_setjmp_setjmp_i_h */ diff --git a/src/native/external/libunwind/src/setjmp/siglongjmp.c b/src/native/external/libunwind/src/setjmp/siglongjmp.c index dd330ce9e19db6..05e18176fe751f 100644 --- a/src/native/external/libunwind/src/setjmp/siglongjmp.c +++ b/src/native/external/libunwind/src/setjmp/siglongjmp.c @@ -57,6 +57,10 @@ static void siglongjmp (sigjmp_buf env, int val) UNUSED; #endif #endif /* __GLIBC_PREREQ */ +#ifndef _JB_STK_SHIFT +#define _JB_STK_SHIFT 0 +#endif + void siglongjmp (sigjmp_buf env, int val) { @@ -75,11 +79,7 @@ siglongjmp (sigjmp_buf env, int val) { if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) abort (); -#ifdef __FreeBSD__ - if (sp != wp[JB_SP] + sizeof(unw_word_t)) -#else - if (sp != wp[JB_SP]) -#endif + if (sp != (wp[JB_SP] + _JB_STK_SHIFT)) continue; if (!bsp_match (&c, wp)) @@ -93,7 +93,11 @@ siglongjmp (sigjmp_buf env, int val) /* Order of evaluation is important here: if unw_resume() restores signal mask, we must set it up appropriately, even if wp[JB_MASK_SAVED] is FALSE. */ +#ifdef __FreeBSD__ + if ((wp[JB_MASK_SAVED] & 0x1) == 0x1) +#else if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) +#endif { /* sigmask was saved */ #if defined(__linux__) || defined(__sun) @@ -108,7 +112,7 @@ siglongjmp (sigjmp_buf env, int val) && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0)) abort (); #elif defined(__FreeBSD__) - if (unw_set_reg (&c, UNW_REG_EH + 2, &wp[JB_MASK]) < 0) + if (unw_set_reg (&c, UNW_REG_EH + 2, (unw_word_t)&wp[JB_MASK]) < 0) abort(); #else #error Port me diff --git a/src/native/external/libunwind/src/sh/Ginit.c b/src/native/external/libunwind/src/sh/Ginit.c index 9fe96d2bd4d8eb..ba62484c5be486 100644 --- a/src/native/external/libunwind/src/sh/Ginit.c +++ b/src/native/external/libunwind/src/sh/Ginit.c @@ -85,11 +85,11 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, if (write) { Debug (16, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (16, "mem[%x] -> %x\n", addr, *val); } return 0; @@ -110,12 +110,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- %x\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %x\n", unw_regname (reg), *val); } return 0; @@ -166,10 +166,23 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void sh_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; @@ -179,6 +192,7 @@ sh_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = sh_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/tilegx/Gapply_reg_state.c b/src/native/external/libunwind/src/tilegx/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Gcreate_addr_space.c b/src/native/external/libunwind/src/tilegx/Gcreate_addr_space.c deleted file mode 100644 index a37c1282f610f8..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gcreate_addr_space.c +++ /dev/null @@ -1,62 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - /* - * Tilegx supports only big or little-endian, not weird stuff like - * PDP_ENDIAN. - */ - if (byte_order != 0 && byte_order_is_valid(byte_order) == 0) - return NULL; - - unw_addr_space_t as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - if (byte_order == 0) - /* use host default: */ - as->big_endian = target_is_big_endian(); - else - as->big_endian = (byte_order == UNW_BIG_ENDIAN); - - as->abi = UNW_TILEGX_ABI_N64; - as->addr_size = 8; - - return as; -#endif -} diff --git a/src/native/external/libunwind/src/tilegx/Gget_proc_info.c b/src/native/external/libunwind/src/tilegx/Gget_proc_info.c deleted file mode 100644 index 3a158da2df7aa6..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gget_proc_info.c +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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; - int ret; - - ret = dwarf_make_proc_info (&c->dwarf); - - if (ret < 0) - { - /* On Tilegx, some routines i.e. _start() etc has no dwarf info. - Just simply mark the end of the frames. */ - 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/native/external/libunwind/src/tilegx/Gget_save_loc.c b/src/native/external/libunwind/src/tilegx/Gget_save_loc.c deleted file mode 100644 index fcf0697892880b..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gget_save_loc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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" */ - - if (reg <= UNW_TILEGX_R55) - loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; - else - printf("\nInvalid register!"); - - 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/native/external/libunwind/src/tilegx/Gglobal.c b/src/native/external/libunwind/src/tilegx/Gglobal.c deleted file mode 100644 index 5232d41c23bba9..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gglobal.c +++ /dev/null @@ -1,64 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 "dwarf_i.h" - -__attribute__((weak)) -pthread_mutex_t tilegx_lock = PTHREAD_MUTEX_INITIALIZER; -HIDDEN atomic_bool tdep_init_done = 0; - -HIDDEN const uint8_t dwarf_to_unw_regnum_map[] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55 - }; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&tilegx_lock, saved_mask); - - if (atomic_load(&tdep_init_done)) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - tilegx_local_addr_space_init (); -#endif - atomic_store(&tdep_init_done, 1); /* signal that we're initialized... */ - - out: - lock_release (&tilegx_lock, saved_mask); -} diff --git a/src/native/external/libunwind/src/tilegx/Ginit.c b/src/native/external/libunwind/src/tilegx/Ginit.c deleted file mode 100644 index 9d6c92ad4f91ec..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Ginit.c +++ /dev/null @@ -1,166 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 "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; - -/* Return the address of the 64-bit slot in UC for REG (even for o32, - where registers are 32-bit, the slots are still 64-bit). */ - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - if (reg >= UNW_TILEGX_R0 && reg < UNW_TILEGX_R0 + 56) - return &uc->uc_mcontext.gregs[reg - UNW_TILEGX_R0]; - else if (reg == UNW_TILEGX_PC) - return &uc->uc_mcontext.pc; - else - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - char *addr = uc_addr (uc, reg); - return addr; -} - -# 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; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if ((long long)addr & (sizeof(unw_word_t) - 1)) - return 0; - - if (write) - { - Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val); - *(unw_word_t *) (intptr_t) addr = *val; - } - else - { - *val = *(unw_word_t *) (intptr_t) addr; - Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *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 = arg; - - if (unw_is_fpreg (reg)) - goto badreg; - - Debug (16, "reg = %s\n", unw_regname (reg)); - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) (intptr_t) addr = (tilegx_reg_t) *val; - Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val); - } - else - { - *val = (tilegx_reg_t) *(unw_word_t *) (intptr_t) addr; - Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - 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 elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); -} - -__attribute__((weak)) void -tilegx_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.big_endian = target_is_big_endian(); - - local_addr_space.abi = UNW_TILEGX_ABI_N64; - local_addr_space.addr_size = sizeof (void *); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - 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 = NULL; - local_addr_space.acc.resume = tilegx_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/native/external/libunwind/src/tilegx/Ginit_remote.c b/src/native/external/libunwind/src/tilegx/Ginit_remote.c deleted file mode 100644 index d6a874c13e82bd..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Ginit_remote.c +++ /dev/null @@ -1,47 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 (!atomic_load(&tdep_init_done)) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/native/external/libunwind/src/tilegx/Gis_signal_frame.c b/src/native/external/libunwind/src/tilegx/Gis_signal_frame.c deleted file mode 100644 index eea00e47fc1779..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gis_signal_frame.c +++ /dev/null @@ -1,118 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 -#include "offsets.h" - -#ifdef __linux__ -#include -#include -#else -# error "Only support Linux!" -#endif - -#define MOVELI_R10_RT_SIGRETURN \ - ( 0x000007e051483000ULL | \ - ((unsigned long)__NR_rt_sigreturn << 43) | \ - ((unsigned long)TREG_SYSCALL_NR << 31) ) -#define SWINT1 0x286b180051485000ULL - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor*) cursor; - unw_word_t w0, w1, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - ip = c->dwarf.ip; - - if (!ip || !a->access_mem || (ip & (sizeof(unw_word_t) - 1))) - return 0; - - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) - return ret; - - if ((ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) - return ret; - - /* Return 1 if the IP points to a RT sigreturn sequence. */ - if (w0 == MOVELI_R10_RT_SIGRETURN && - w1 == SWINT1) - { - return 1; - } - return 0; -} - - -HIDDEN int -tilegx_handle_signal_frame (unw_cursor_t *cursor) -{ - int i; - struct cursor *c = (struct cursor *) cursor; - unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; - struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); - int ret; - - if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) - return -UNW_EUNSPEC; - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - - c->sigcontext_addr = sp_addr + sizeof (siginfo_t) + - C_ABI_SAVE_AREA_SIZE; - sc_addr = c->sigcontext_addr + LINUX_UC_MCONTEXT_OFF; - - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - -#define SC_REG_OFFSET(X) (8 * X) - - for (i = UNW_TILEGX_R0; i <= UNW_TILEGX_R55; i++) - { - c->dwarf.loc[i] = DWARF_LOC (sc_addr + SC_REG_OFFSET(i), 0); - } - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R54], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R55], &c->dwarf.ip); - - return 1; -} diff --git a/src/native/external/libunwind/src/tilegx/Greg_states_iterate.c b/src/native/external/libunwind/src/tilegx/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Gregs.c b/src/native/external/libunwind/src/tilegx/Gregs.c deleted file mode 100644 index 565c6f4432a28e..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gregs.c +++ /dev/null @@ -1,76 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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; - - if (reg == UNW_TILEGX_R54 && !write) - { - reg = UNW_TILEGX_CFA; - } - - if (reg <= UNW_TILEGX_R55) - loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; - else if (reg == UNW_TILEGX_CFA) - { - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - } - else - { - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - { - if (ci->dwarf.use_prev_instr == 0) { - if (reg == UNW_TILEGX_PC) - c->dwarf.ip = *valp; /* update the IP cache */ - } - else { - if (reg == UNW_TILEGX_R55) - c->dwarf.ip = *valp; /* update the IP cache */ - } - 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) -{ - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} diff --git a/src/native/external/libunwind/src/tilegx/Gresume.c b/src/native/external/libunwind/src/tilegx/Gresume.c deleted file mode 100644 index ece443a5b56fc9..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gresume.c +++ /dev/null @@ -1,94 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 "offsets.h" -#include - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -tilegx_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - int i; - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = c->dwarf.as_arg; - - Debug (1, "(cursor=%p\n", c); - - return setcontext(uc); -} - -#endif /* !UNW_REMOTE_ONLY */ - -static inline void -establish_machine_state (struct cursor *c) -{ - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - 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)) - { - Debug (1, "no fp!"); - abort (); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - as->acc.access_reg (as, reg, &val, 1, arg); - } - } -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - Debug (1, "(cursor=%p) ip=0x%lx\n", c, c->dwarf.ip); - - if (!c->dwarf.ip) - { - /* This can happen easily when the frame-chain gets truncated - due to bad or missing unwind-info. */ - Debug (1, "refusing to resume execution at address 0\n"); - return -UNW_EINVAL; - } - - establish_machine_state (c); - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/native/external/libunwind/src/tilegx/Gstep.c b/src/native/external/libunwind/src/tilegx/Gstep.c deleted file mode 100644 index b4456897bed0a4..00000000000000 --- a/src/native/external/libunwind/src/tilegx/Gstep.c +++ /dev/null @@ -1,53 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 "offsets.h" - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p, ip=0x%016lx, sp=0x%016lx)\n", - c, c->dwarf.ip, c->dwarf.cfa); - - /* Special handling the signal frame. */ - if (unw_is_signal_frame (cursor) > 0) - return tilegx_handle_signal_frame (cursor); - - /* Try DWARF-based unwinding... */ - ret = dwarf_step (&c->dwarf); - - if (unlikely (ret == -UNW_ESTOPUNWIND)) - return ret; - - /* Dwarf unwinding didn't work, stop. */ - if (unlikely (ret < 0)) - return 0; - - return (c->dwarf.ip == 0) ? 0 : 1; -} diff --git a/src/native/external/libunwind/src/tilegx/Lget_save_loc.c b/src/native/external/libunwind/src/tilegx/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Linit_remote.c b/src/native/external/libunwind/src/tilegx/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Lis_signal_frame.c b/src/native/external/libunwind/src/tilegx/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Lreg_states_iterate.c b/src/native/external/libunwind/src/tilegx/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Lregs.c b/src/native/external/libunwind/src/tilegx/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Lresume.c b/src/native/external/libunwind/src/tilegx/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/Lstep.c b/src/native/external/libunwind/src/tilegx/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/native/external/libunwind/src/tilegx/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/native/external/libunwind/src/tilegx/elfxx.c b/src/native/external/libunwind/src/tilegx/elfxx.c deleted file mode 100644 index 07d3d12b94fe00..00000000000000 --- a/src/native/external/libunwind/src/tilegx/elfxx.c +++ /dev/null @@ -1,27 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - -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" - -#include "../src/elfxx.c" diff --git a/src/native/external/libunwind/src/tilegx/gen-offsets.c b/src/native/external/libunwind/src/tilegx/gen-offsets.c deleted file mode 100644 index 8704bb215e3cb7..00000000000000 --- a/src/native/external/libunwind/src/tilegx/gen-offsets.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -#define UC(N,X) \ - printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) - -#define SC(N,X) \ - printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) - -int -main (void) -{ - printf ( -"/* Linux-specific definitions: */\n\n" - -"/* Define various structure offsets to simplify cross-compilation. */\n\n" - -"/* Offsets for TILEGX Linux \"ucontext_t\": */\n\n"); - - UC ("FLAGS", uc_flags); - UC ("LINK", uc_link); - UC ("STACK", uc_stack); - UC ("MCONTEXT", uc_mcontext); - UC ("SIGMASK", uc_sigmask); - - UC ("MCONTEXT_GREGS", uc_mcontext.gregs); - - return 0; -} diff --git a/src/native/external/libunwind/src/tilegx/getcontext.S b/src/native/external/libunwind/src/tilegx/getcontext.S deleted file mode 100644 index fbc8654bc7f1f9..00000000000000 --- a/src/native/external/libunwind/src/tilegx/getcontext.S +++ /dev/null @@ -1,36 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 "offsets.h" -#include - - .text - # define REG(X) LINUX_UC_MCONTEXT_GREGS + 8 * (X) - .global _Utilegx_getcontext - .type _Utilegx_getcontext, %function - # This is a stub version of getcontext() for TILEGX. -_Utilegx_getcontext: - - diff --git a/src/native/external/libunwind/src/tilegx/init.h b/src/native/external/libunwind/src/tilegx/init.h deleted file mode 100644 index 0e0f7fd1da819c..00000000000000 --- a/src/native/external/libunwind/src/tilegx/init.h +++ /dev/null @@ -1,63 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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, i; - - for (i = 0; i < 56; i++) - c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R0 + i); - for (i = 56; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - if (use_prev_instr == 0) - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_PC), - &c->dwarf.ip); - else - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R55), - &c->dwarf.ip); - - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R54), - &c->dwarf.cfa); - - if (ret < 0) - return ret; - - 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; - - return 0; -} diff --git a/src/native/external/libunwind/src/tilegx/offsets.h b/src/native/external/libunwind/src/tilegx/offsets.h deleted file mode 100644 index 6d30f1edcff1ef..00000000000000 --- a/src/native/external/libunwind/src/tilegx/offsets.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* Offsets for TILEGX Linux "ucontext_t": */ - -#define LINUX_UC_FLAGS_OFF 0x0 -#define LINUX_UC_LINK_OFF 0x8 -#define LINUX_UC_STACK_OFF 0x10 -#define LINUX_UC_MCONTEXT_OFF 0x28 -#define LINUX_UC_SIGMASK_OFF 0x228 -#define LINUX_UC_MCONTEXT_GREGS 0x28 diff --git a/src/native/external/libunwind/src/tilegx/regname.c b/src/native/external/libunwind/src/tilegx/regname.c deleted file mode 100644 index 0ce47b9d66ed85..00000000000000 --- a/src/native/external/libunwind/src/tilegx/regname.c +++ /dev/null @@ -1,55 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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[] = - { - /* 0. */ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - /* 8. */ - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - /* 16. */ - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - /* 24. */ - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - /* 32. */ - "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", - /* 40. */ - "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", - /* 48. */ - "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", - /* pc, cfa */ - "pc", "cfa" - }; - -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/native/external/libunwind/src/tilegx/siglongjmp.S b/src/native/external/libunwind/src/tilegx/siglongjmp.S deleted file mode 100644 index bccb1c77854339..00000000000000 --- a/src/native/external/libunwind/src/tilegx/siglongjmp.S +++ /dev/null @@ -1,7 +0,0 @@ - /* Dummy implementation for now. */ - .globl _UI_siglongjmp_cont - .globl _UI_longjmp_cont - -_UI_siglongjmp_cont: -_UI_longjmp_cont: - jrp lr diff --git a/src/native/external/libunwind/src/tilegx/unwind_i.h b/src/native/external/libunwind/src/tilegx/unwind_i.h deleted file mode 100644 index 9d41c90b4d10bc..00000000000000 --- a/src/native/external/libunwind/src/tilegx/unwind_i.h +++ /dev/null @@ -1,46 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - -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 - -#include "libunwind_i.h" - -#define tilegx_local_resume UNW_OBJ(local_resume) -#define tilegx_local_addr_space_init UNW_OBJ(local_addr_space_init) - -extern int tilegx_local_resume (unw_addr_space_t as, - unw_cursor_t *cursor, - void *arg); -#define tilegx_handle_signal_frame UNW_OBJ(handle_signal_frame) -extern int tilegx_handle_signal_frame(unw_cursor_t *cursor); - -extern void tilegx_local_addr_space_init (void); - -#endif /* unwind_i_h */ diff --git a/src/native/external/libunwind/src/x86/Ginit.c b/src/native/external/libunwind/src/x86/Ginit.c index 4261fb5235aa3c..956d8088b6afe9 100644 --- a/src/native/external/libunwind/src/x86/Ginit.c +++ b/src/native/external/libunwind/src/x86/Ginit.c @@ -74,53 +74,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, return 0; } -/* 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; -#ifdef HAVE_MINCORE - unsigned char mvec[2]; /* Unaligned access may cross page boundary */ -#endif - size_t len = unw_page_size; - addr = uwn_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; - } - -#ifdef HAVE_MINCORE - if (mincore ((void *) addr, len, mvec) == -1) -#else - if (msync ((void *) addr, len, MS_ASYNC) == -1) -#endif - 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, @@ -129,15 +82,18 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, if (write) { Debug (16, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { /* validate address */ const struct cursor *c = (const struct cursor *)arg; - if (c && c->validate && validate_mem(addr)) - return -1; - *val = *(unw_word_t *) addr; + if (unlikely (c && c->validate) && !unw_address_is_valid (addr, sizeof(unw_word_t))) + { + Debug (16, "mem[%#010lx] -> invalid\n", (long)addr); + return -1; + } + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (16, "mem[%x] -> %x\n", addr, *val); } return 0; @@ -158,12 +114,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- %x\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> %x\n", unw_regname (reg), *val); } return 0; @@ -214,10 +170,23 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void x86_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; @@ -227,6 +196,7 @@ x86_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = x86_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/x86/Gos-freebsd.c b/src/native/external/libunwind/src/x86/Gos-freebsd.c index 28e6722af161a5..ca95f17c20af43 100644 --- a/src/native/external/libunwind/src/x86/Gos-freebsd.c +++ b/src/native/external/libunwind/src/x86/Gos-freebsd.c @@ -111,6 +111,7 @@ x86_handle_signal_frame (unw_cursor_t *cursor) struct sigframe *sf; uintptr_t uc_addr; struct dwarf_loc esp_loc; + int i; sf = (struct sigframe *)c->dwarf.cfa; uc_addr = (uintptr_t)&(sf->sf_uc); @@ -124,7 +125,7 @@ x86_handle_signal_frame (unw_cursor_t *cursor) return 0; } - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + for (int i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) c->dwarf.loc[i] = DWARF_NULL_LOC; c->dwarf.loc[EIP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EIP_OFF, 0); diff --git a/src/native/external/libunwind/src/x86/Gos-linux.c b/src/native/external/libunwind/src/x86/Gos-linux.c index 0908e3a11d6ca2..725ef73827f33d 100644 --- a/src/native/external/libunwind/src/x86/Gos-linux.c +++ b/src/native/external/libunwind/src/x86/Gos-linux.c @@ -136,6 +136,10 @@ x86_handle_signal_frame (unw_cursor_t *cursor) c->dwarf.loc[EIP] = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0); c->dwarf.loc[ESP] = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); + ret = dwarf_get (&c->dwarf, c->dwarf.loc[ESP], &c->dwarf.cfa); + c->dwarf.use_prev_instr = 0; + return 0; } @@ -287,49 +291,11 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) struct cursor *c = (struct cursor *) cursor; ucontext_t *uc = c->uc; - /* Ensure c->pi is up-to-date. On x86, 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); - - if (unlikely (c->sigcontext_format != X86_SCF_NONE)) - { - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - - Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); + Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); #if !defined(__ANDROID__) - x86_sigreturn (sc); + setcontext (uc); #endif - } - else - { - Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); -#if !defined(__ANDROID__) - setcontext (uc); -#endif - } return -UNW_EINVAL; } -/* sigreturn() is a no-op on x86 glibc. */ -HIDDEN void -x86_sigreturn (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - mcontext_t *sc_mcontext = &((ucontext_t*)sc)->uc_mcontext; - /* Copy in saved uc - all preserved regs are at the start of sigcontext */ - memcpy(sc_mcontext, &c->uc->uc_mcontext, - DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t)); - - Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", - (unsigned long long) c->dwarf.ip, sc); - __asm__ __volatile__ ("mov %0, %%esp;" - "mov %1, %%eax;" - "syscall" - :: "r"(sc), "i"(SYS_rt_sigreturn) - : "memory"); - abort(); -} #endif diff --git a/src/native/external/libunwind/src/x86/Gstep.c b/src/native/external/libunwind/src/x86/Gstep.c index 061dcbaaa28097..52e327eded96c1 100644 --- a/src/native/external/libunwind/src/x86/Gstep.c +++ b/src/native/external/libunwind/src/x86/Gstep.c @@ -31,11 +31,24 @@ unw_step (unw_cursor_t *cursor) { struct cursor *c = (struct cursor *) cursor; int ret, i; + int validate = c->validate; + c->validate = 1; Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); + /* + * Special-case the signal trampoline since on many OS targets it lacks DWARF + * unwind info. + */ + if (unw_is_signal_frame (cursor) > 0) + { + ret = x86_handle_signal_frame(cursor); + return 1; + } + /* Try DWARF-based unwinding... */ ret = dwarf_step (&c->dwarf); + c->validate = validate; if (ret < 0 && ret != -UNW_ENOINFO) { @@ -45,54 +58,40 @@ unw_step (unw_cursor_t *cursor) if (unlikely (ret < 0)) { - /* DWARF failed, let's see if we can follow the frame-chain - or skip over the signal trampoline. */ + /* DWARF failed, let's see if we can follow the frame-chain */ struct dwarf_loc ebp_loc, eip_loc, esp_loc; - /* We could get here because of missing/bad unwind information. - Validate all addresses before dereferencing. */ - c->validate = 1; Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); - if (unw_is_signal_frame (cursor) > 0) + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa); + if (ret < 0) { - ret = x86_handle_signal_frame(cursor); - if (ret < 0) - { - Debug (2, "returning 0\n"); - return 0; - } + Debug (2, "returning %d\n", ret); + return ret; } - else - { - ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]), - c->dwarf.cfa); - ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); - esp_loc = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); - eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); - c->dwarf.cfa += 8; + Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]), c->dwarf.cfa); - /* Mark all registers unsaved, since we don't know where - they are saved (if at all), except for the EBP and - EIP. */ - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; + ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); + esp_loc = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); + eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); + c->dwarf.cfa += 8; - c->dwarf.loc[EBP] = ebp_loc; - c->dwarf.loc[ESP] = esp_loc; - c->dwarf.loc[EIP] = eip_loc; - c->dwarf.use_prev_instr = 1; + /* + * Mark all registers unsaved, since we don't know where they are saved + * (if at all), except for the EBP and EIP. + */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + { + c->dwarf.loc[i] = DWARF_NULL_LOC; } + c->dwarf.loc[EBP] = ebp_loc; + c->dwarf.loc[ESP] = esp_loc; + c->dwarf.loc[EIP] = eip_loc; + c->dwarf.use_prev_instr = 1; + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[EBP])) { ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); diff --git a/src/native/external/libunwind/src/x86/unwind_i.h b/src/native/external/libunwind/src/x86/unwind_i.h index caa7e02dee40e0..2acc8cbb6be7f3 100644 --- a/src/native/external/libunwind/src/x86/unwind_i.h +++ b/src/native/external/libunwind/src/x86/unwind_i.h @@ -52,7 +52,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define x86_scratch_loc UNW_OBJ(scratch_loc) #define x86_get_scratch_loc UNW_OBJ(get_scratch_loc) #define x86_r_uc_addr UNW_OBJ(r_uc_addr) -#define x86_sigreturn UNW_OBJ(sigreturn) extern void x86_local_addr_space_init (void); extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, @@ -61,7 +60,6 @@ extern dwarf_loc_t x86_scratch_loc (struct cursor *c, unw_regnum_t reg); extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg); extern void *x86_r_uc_addr (ucontext_t *uc, int reg); -extern void x86_sigreturn (unw_cursor_t *cursor); #define x86_handle_signal_frame UNW_OBJ(handle_signal_frame) extern int x86_handle_signal_frame(unw_cursor_t *cursor); diff --git a/src/native/external/libunwind/src/x86_64/Gcreate_addr_space.c b/src/native/external/libunwind/src/x86_64/Gcreate_addr_space.c index 9b2db9810abe00..3618d04eba9c86 100644 --- a/src/native/external/libunwind/src/x86_64/Gcreate_addr_space.c +++ b/src/native/external/libunwind/src/x86_64/Gcreate_addr_space.c @@ -30,12 +30,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "unwind_i.h" -#if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) -#define __LITTLE_ENDIAN _LITTLE_ENDIAN -#endif - unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) +unw_create_addr_space (unw_accessors_t *a UNUSED, int byte_order UNUSED) { #ifdef UNW_LOCAL_ONLY return NULL; @@ -45,7 +41,7 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order) /* * x86_64 supports only little-endian. */ - if (byte_order != 0 && byte_order != __LITTLE_ENDIAN) + if (byte_order != 0 && byte_order != UNW_LITTLE_ENDIAN) return NULL; as = malloc (sizeof (*as)); diff --git a/src/native/external/libunwind/src/x86_64/Gglobal.c b/src/native/external/libunwind/src/x86_64/Gglobal.c index 812cfb54298e8c..0964d5f3964480 100644 --- a/src/native/external/libunwind/src/x86_64/Gglobal.c +++ b/src/native/external/libunwind/src/x86_64/Gglobal.c @@ -94,8 +94,6 @@ tdep_init (void) dwarf_init (); #ifndef UNW_REMOTE_ONLY - tdep_init_mem_validate (); - x86_64_local_addr_space_init (); #endif atomic_store(&tdep_init_done, 1); /* signal that we're initialized... */ diff --git a/src/native/external/libunwind/src/x86_64/Ginit.c b/src/native/external/libunwind/src/x86_64/Ginit.c index 88146a3e78156c..ca3c0228091391 100644 --- a/src/native/external/libunwind/src/x86_64/Ginit.c +++ b/src/native/external/libunwind/src/x86_64/Ginit.c @@ -54,14 +54,14 @@ static struct unw_addr_space local_addr_space; unw_addr_space_t unw_local_addr_space = &local_addr_space; static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +put_unwind_info (unw_addr_space_t as UNUSED, unw_proc_info_t *proc_info UNUSED, void *arg UNUSED) { /* 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) +get_dyn_info_list_addr (unw_addr_space_t as UNUSED, unw_word_t *dyn_info_list_addr, + void *arg UNUSED) { #ifndef UNW_LOCAL_ONLY # pragma weak _U_dyn_info_list_addr @@ -73,260 +73,32 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, return 0; } -static int mem_validate_pipe[2] = {-1, -1}; -#ifdef HAVE_PIPE2 -static inline void -do_pipe2 (int pipefd[2]) -{ - int result UNUSED = 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]); - - do_pipe2 (mem_validate_pipe); -} - -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 - { -#ifdef HAVE_SYS_SYSCALL_H - /* use syscall insteadof write() so that ASAN does not complain */ - ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1); -#else - ret = write (mem_validate_pipe[1], addr, 1); -#endif - } - 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 */ - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ - if (mincore (addr, len, (unsigned char *)mvec) != 0) - { - return -1; - } - - return write_validate (addr); -} -#endif - -/* Initialise memory validation method. On linux kernels <2.6.21, - mincore() returns incorrect value for MAP_PRIVATE mappings, - such as stacks. If mincore() was available at compile time, - check if we can actually use it. If not, use msync() instead. */ -HIDDEN void -tdep_init_mem_validate (void) -{ - open_pipe (); - -#ifdef HAVE_MINCORE - unsigned char present = 1; - size_t len = unw_page_size; - unw_word_t addr = uwn_page_start((unw_word_t)&present); - unsigned char mvec[1]; - int ret; - while ((ret = mincore ((void*)addr, len, (unsigned char *)mvec)) == -1 && - errno == EAGAIN) {} - if (ret == 0) - { - Debug(1, "using mincore to validate memory\n"); - mem_validate_func = mincore_validate; - } - else -#endif - { - Debug(1, "using msync to validate memory\n"); - mem_validate_func = msync_validate; - } -} - -/* Cache of already validated addresses */ -#define NLGA 4 -#if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD -// thread-local variant -static _Thread_local unw_word_t last_good_addr[NLGA]; -static _Thread_local int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (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; -} - -#else -// global, thread safe variant -static _Atomic unw_word_t last_good_addr[NLGA]; -static _Atomic int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == atomic_load(&last_good_addr[i])) - return 1; - } - return 0; -} - -static void -cache_valid_mem(unw_word_t addr) -{ - int i, victim; - victim = atomic_load(&lga_victim); - unw_word_t zero = 0; - for (i = 0; i < NLGA; i++) { - if (atomic_compare_exchange_strong(&last_good_addr[victim], &zero, addr)) { - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - atomic_store(&last_good_addr[victim], addr); - victim = (victim + 1) % NLGA; - atomic_store(&lga_victim, victim); -} -#endif - -static int -validate_mem (unw_word_t addr) -{ - size_t len = unw_page_size; - addr = uwn_page_start(addr); - - if (addr == 0) - return -1; - - if (is_cached_valid_mem(addr)) - return 0; - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - - cache_valid_mem(addr); - - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, +access_mem (unw_addr_space_t as UNUSED, 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; + memcpy ((void *) addr, val, sizeof(unw_word_t)); } else { /* validate address */ if (unlikely (AS_ARG_GET_VALIDATE(arg)) - && unlikely (validate_mem (addr))) { + && unlikely (!unw_address_is_valid (addr, sizeof (unw_word_t)))) { Debug (16, "mem[%016lx] -> invalid\n", addr); return -1; } - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); 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, +access_reg (unw_addr_space_t as UNUSED, unw_regnum_t reg, unw_word_t *val, int write, void *arg) { unw_word_t *addr; @@ -340,12 +112,12 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, if (write) { - *(unw_word_t *) addr = *val; + memcpy ((void *) addr, val, sizeof(unw_word_t)); Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); } else { - *val = *(unw_word_t *) addr; + memcpy (val, (void *) addr, sizeof(unw_word_t)); Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); } return 0; @@ -356,7 +128,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, } static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, +access_fpreg (unw_addr_space_t as UNUSED, unw_regnum_t reg, unw_fpreg_t *val, int write, void *arg) { ucontext_t *uc = AS_ARG_GET_UC_PTR(arg); @@ -391,15 +163,28 @@ access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, 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) + void *arg UNUSED) { return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } +static int +get_static_elf_filename (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg UNUSED) +{ + return _Uelf64_get_elf_filename (as, getpid (), ip, buf, buf_len, offp); +} + HIDDEN void x86_64_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); +#ifndef UNW_REMOTE_ONLY +# if defined(HAVE_DL_ITERATE_PHDR) + local_addr_space.iterate_phdr_function = dl_iterate_phdr; +# endif +#endif local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; @@ -409,6 +194,7 @@ x86_64_local_addr_space_init (void) local_addr_space.acc.access_fpreg = access_fpreg; local_addr_space.acc.resume = x86_64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.acc.get_elf_filename = get_static_elf_filename; unw_flush_cache (&local_addr_space, 0, 0); } diff --git a/src/native/external/libunwind/src/x86_64/Ginit_remote.c b/src/native/external/libunwind/src/x86_64/Ginit_remote.c index 51761a7102f925..1675aeb5f1561d 100644 --- a/src/native/external/libunwind/src/x86_64/Ginit_remote.c +++ b/src/native/external/libunwind/src/x86_64/Ginit_remote.c @@ -30,7 +30,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "unwind_i.h" int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +unw_init_remote (unw_cursor_t *cursor UNUSED, unw_addr_space_t as UNUSED, void *as_arg UNUSED) { #ifdef UNW_LOCAL_ONLY return -UNW_EINVAL; diff --git a/src/native/external/libunwind/src/x86_64/Gos-freebsd.c b/src/native/external/libunwind/src/x86_64/Gos-freebsd.c index e8f04381679f08..59706b977b812e 100644 --- a/src/native/external/libunwind/src/x86_64/Gos-freebsd.c +++ b/src/native/external/libunwind/src/x86_64/Gos-freebsd.c @@ -38,7 +38,7 @@ unw_is_signal_frame (unw_cursor_t *cursor) { /* XXXKIB */ struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, w2, b0, ip; + unw_word_t w0, w1, w2, ip; unw_addr_space_t as; unw_accessors_t *a; void *arg; @@ -69,22 +69,9 @@ eb fd jmp 0b w2 == 0x0000000000fdebf4) { c->sigcontext_format = X86_64_SCF_FREEBSD_SIGFRAME; - return (c->sigcontext_format); + return (1); } - /* Check if RIP points at standard syscall sequence. -49 89 ca mov %rcx,%r10 -0f 05 syscall - */ - if ((ret = (*a->access_mem) (as, ip - 5, &b0, 0, arg)) < 0) - return (0); - Debug (12, "b0 0x%lx\n", b0); - if ((b0 & 0xffffffffffffff) == 0x050fca89490000 || - (b0 & 0xffffffffff) == 0x050fca8949) - { - c->sigcontext_format = X86_64_SCF_FREEBSD_SYSCALL; - return (c->sigcontext_format); - } - return (X86_64_SCF_NONE); + return (0); } HIDDEN int @@ -131,26 +118,6 @@ x86_64_handle_signal_frame (unw_cursor_t *cursor) return 0; } - else if (c->sigcontext_format == X86_64_SCF_FREEBSD_SYSCALL) - { - c->dwarf.loc[RCX] = c->dwarf.loc[R10]; - /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ - /* rbp_loc = c->dwarf.loc[RBP]; */ - c->dwarf.loc[RSP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); - c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); - Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", - (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), - (unsigned long long) c->dwarf.ip); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - c->dwarf.cfa += 8; - c->dwarf.use_prev_instr = 1; - return 1; - } else return -UNW_EBADFRAME; @@ -220,3 +187,50 @@ x86_64_sigreturn (unw_cursor_t *cursor) abort(); } #endif + +HIDDEN int +x86_64_os_step(struct cursor *c) +{ + unw_word_t b0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + ip = c->dwarf.ip; + + /* + * Check if RIP points at standard syscall sequence. + * 49 89 ca mov %rcx,%r10 + * 0f 05 syscall + */ + if ((ret = (*a->access_mem) (as, ip - 5, &b0, 0, arg)) < 0) + return (0); + Debug (12, "b0 0x%lx\n", b0); + if ((b0 & 0xffffffffffffff) == 0x050fca89490000 || + (b0 & 0xffffffffff) == 0x050fca8949) + { + c->sigcontext_format = X86_64_SCF_FREEBSD_SYSCALL; + c->dwarf.loc[RCX] = c->dwarf.loc[R10]; + /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ + /* rbp_loc = c->dwarf.loc[RBP]; */ + c->dwarf.loc[RSP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", + (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), + (unsigned long long) c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + c->dwarf.cfa += 8; + c->dwarf.use_prev_instr = 1; + return 1; + } + return (0); +} diff --git a/src/native/external/libunwind/src/x86_64/Gos-linux.c b/src/native/external/libunwind/src/x86_64/Gos-linux.c index b4893297b16fbc..c10ce6eed2edf1 100644 --- a/src/native/external/libunwind/src/x86_64/Gos-linux.c +++ b/src/native/external/libunwind/src/x86_64/Gos-linux.c @@ -25,6 +25,10 @@ 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_ASM_VSYSCALL_H +#include +#endif + #include "libunwind_i.h" #include "unwind_i.h" #include "ucontext_i.h" @@ -32,7 +36,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include HIDDEN void -tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip, int need_unwind_info) +tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip UNUSED, int need_unwind_info UNUSED) { struct cursor *c = (struct cursor *) dw; assert(! need_unwind_info || dw->pi_valid); @@ -85,7 +89,7 @@ unw_is_signal_frame (unw_cursor_t *cursor) } HIDDEN int -x86_64_handle_signal_frame (unw_cursor_t *cursor) +x86_64_handle_signal_frame (unw_cursor_t *cursor UNUSED) { #if UNW_DEBUG /* To silence compiler warnings */ /* Should not get here because we now use kernel-provided dwarf @@ -155,3 +159,33 @@ x86_64_sigreturn (unw_cursor_t *cursor) } #endif + +static int +is_vsyscall (struct dwarf_cursor *c UNUSED) +{ +#if defined(VSYSCALL_START) && defined(VSYSCALL_END) + return c->ip >= VSYSCALL_START && c->ip < VSYSCALL_END; +#elif defined(VSYSCALL_ADDR) + /* Linux 3.16 removes `VSYSCALL_START` and `VSYSCALL_END`. Assume + a single page is mapped for vsyscalls. */ + return c->ip >= VSYSCALL_ADDR && c->ip < VSYSCALL_ADDR + unw_page_size; +#else + return 0; +#endif +} + +HIDDEN int +x86_64_os_step(struct cursor *c) +{ + if (is_vsyscall (&c->dwarf)) + { + Debug (2, "in vsyscall region\n"); + c->frame_info.cfa_reg_offset = 8; + c->frame_info.cfa_reg_rsp = -1; + c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + c->dwarf.cfa += 8; + return (1); + } + return (0); +} diff --git a/src/native/external/libunwind/src/x86_64/Gos-qnx.c b/src/native/external/libunwind/src/x86_64/Gos-qnx.c new file mode 100644 index 00000000000000..be4e187a113495 --- /dev/null +++ b/src/native/external/libunwind/src/x86_64/Gos-qnx.c @@ -0,0 +1,214 @@ +/* + * Copyright 2022, 2023 BlackBerry Limited. + * + * 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 "ucontext_i.h" +#include + + +/** + * @brief Predicate to check if current IP is a signal trampoline. + * @param[in] cursor The current unwinding state. + * + * This function assumes the IP points to the first instruction after the call + * to the signal handler, and the bytes checked are the opcodes dumped by + * objdump between the call and the syscall that returns from the signal. + * + * This is not 100% robust but it's unlikely any other syscall setup is + * identical. + * + * @returns 0 if it does not detect the current function is a signal trampoline, + * 1 if it detects the trampoline. + */ +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + const unsigned char sig[] = + { + 0x4c, 0x89, 0xef, // mov %r13,%rdi + 0x49, 0x8b, 0x74, 0x24, 0x30, // mov 0x30(%r12),%rsi + 0x49, 0x8b, 0x54, 0x24, 0x38, // mov 0x38(%r12),%rdx + 0x4d, 0x8b, 0x44, 0x24, 0x48, // mov 0x48(%r12),%r8 + 0x4d, 0x8b, 0x4c, 0x24, 0x50, // mov 0x50(%r12),%r9 + 0x49, 0x8b, 0x5c, 0x24, 0x60, // mov 0x60(%r12),%rbx + 0x49, 0x8b, 0x6c, 0x24, 0x68, // mov 0x68(%r12),%rbp + 0x4d, 0x8b, 0xac, 0x24, 0x88, 0x00, 0x00, 0x00, // mov 0x88(%r12),%r13 + 0x4d, 0x8b, 0xb4, 0x24, 0x90, 0x00, 0x00, 0x00, // mov 0x90(%r12),%r14 + 0x4d, 0x8b, 0xbc, 0x24, 0x98, 0x00, 0x00, 0x00, // mov 0x98(%r12),%r15 + 0x4d, 0x8b, 0xa4, 0x24, 0x80, 0x00, 0x00, 0x00, // mov 0x80(%r12),%r12 + 0x48, 0xc7, 0xc0, 0x1b, 0x00, 0x00, 0x00, // mov $0x1b,%rax + 0x0f, 0x05, // syscall + }; + + struct cursor *c = (struct cursor *) cursor; + unw_addr_space_t as = c->dwarf.as; + unw_accessors_t *a = unw_get_accessors_int (as); + unw_word_t ip = c->dwarf.ip; + int retval = 1; + +#if CONSERVATIVE_CHECKS + int val = 0; + if (c->dwarf.as == unw_local_addr_space) { + val = dwarf_get_validate(&c->dwarf); + dwarf_set_validate(&c->dwarf, 1); + } +#endif + + unw_word_t w = 0; + for (size_t i = 0; i != sizeof(sig)/sizeof(sig[0]); ++i) + { + size_t byte_index = i % sizeof(unw_word_t); + if (0 == byte_index) + { + int ret = a->access_mem (as, ip, &w, 0, c->dwarf.as_arg); + if (ret < 0) + { + retval = 0; + break; + } + ip += sizeof(w); + } + + if (sig[i] != (w&0xff)) + { + retval = 0; + break; + } + w >>= 8; + } + +#if CONSERVATIVE_CHECKS + if (c->dwarf.as == unw_local_addr_space) { + dwarf_set_validate(&c->dwarf, val); + } +#endif + + return retval; +} + + +/** + * @brief Special handling when a signal trampoline is detected + * @param[in] cursor The current unwinding state. + * + * If this is a signal trampoline then %rsp points directly at the kernel + * sighandler info so it's easy to get the ucontext. + * + * @returns < 0 on failure, 0 on success. + */ +HIDDEN int +x86_64_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor * c = (struct cursor *) cursor; + unw_addr_space_t as = c->dwarf.as; + unw_accessors_t * a = unw_get_accessors_int (as); + unw_word_t sp = c->dwarf.cfa; + unw_word_t uc_ptr_addr = sp + offsetof(struct _sighandler_info, context); + + ucontext_t *context = NULL; + int ret = a->access_mem (as, uc_ptr_addr, (unw_word_t*)&context, 0, c->dwarf.as_arg); + if (ret < 0) + { + return -UNW_EBADFRAME; + } + Debug(3, "unwind context at %#010lx\n", (long)context); + + for (size_t i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + { + c->dwarf.loc[i] = DWARF_NULL_LOC; + } + + c->dwarf.loc[RAX] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rax); + c->dwarf.loc[RDX] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rdx); + c->dwarf.loc[RCX] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rcx); + c->dwarf.loc[RBX] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rbx); + c->dwarf.loc[RSI] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rsi); + c->dwarf.loc[RDI] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rdi); + c->dwarf.loc[RBP] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rbp); + c->dwarf.loc[RSP] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rsp); + c->dwarf.loc[ R8] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r8); + c->dwarf.loc[ R9] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r9); + c->dwarf.loc[R10] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r10); + c->dwarf.loc[R11] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r11); + c->dwarf.loc[R12] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r12); + c->dwarf.loc[R13] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r13); + c->dwarf.loc[R14] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r14); + c->dwarf.loc[R15] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.r15); + c->dwarf.loc[RIP] = DWARF_VAL_LOC (&c->dwarf, context->uc_mcontext.cpu.rip); + + dwarf_get (&c->dwarf, c->dwarf.loc[RSP], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + + return 0; +} + + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.cpu.r8; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.cpu.r9; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.cpu.r10; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.cpu.r11; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.cpu.r12; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.cpu.r13; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.cpu.r14; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.cpu.r15; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.cpu.rdi; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.cpu.rsi; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.cpu.rbp; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.cpu.rbx; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.cpu.rdx; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.cpu.rax; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.cpu.rcx; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.cpu.rsp; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.cpu.rip; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + Debug(0, "Unsupported function.\n"); + abort(); +} + +#endif + +HIDDEN int +x86_64_os_step(struct cursor *c) +{ + return (0); +} diff --git a/src/native/external/libunwind/src/x86_64/Gos-solaris.c b/src/native/external/libunwind/src/x86_64/Gos-solaris.c index a9957ba8c9d762..d570d08e101164 100644 --- a/src/native/external/libunwind/src/x86_64/Gos-solaris.c +++ b/src/native/external/libunwind/src/x86_64/Gos-solaris.c @@ -135,3 +135,9 @@ x86_64_sigreturn (unw_cursor_t *cursor) } #endif + +HIDDEN int +x86_64_os_step(struct cursor *c) +{ + return (0); +} diff --git a/src/native/external/libunwind/src/x86_64/Gregs.c b/src/native/external/libunwind/src/x86_64/Gregs.c index dff5bcbe74b6e0..88c466b9ec612c 100644 --- a/src/native/external/libunwind/src/x86_64/Gregs.c +++ b/src/native/external/libunwind/src/x86_64/Gregs.c @@ -131,8 +131,8 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, } HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) +tdep_access_fpreg (struct cursor *c UNUSED, unw_regnum_t reg UNUSED, + unw_fpreg_t *valp UNUSED, int write UNUSED) { return -UNW_EBADREG; } diff --git a/src/native/external/libunwind/src/x86_64/Gresume.c b/src/native/external/libunwind/src/x86_64/Gresume.c index becb1bd6cd7690..572e048953a509 100644 --- a/src/native/external/libunwind/src/x86_64/Gresume.c +++ b/src/native/external/libunwind/src/x86_64/Gresume.c @@ -28,13 +28,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include "libunwind_i.h" -#include "offsets.h" #include "unwind_i.h" #ifndef UNW_REMOTE_ONLY HIDDEN inline int -x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +x86_64_local_resume (unw_addr_space_t as UNUSED, unw_cursor_t *cursor, void *arg UNUSED) { struct cursor *c = (struct cursor *) cursor; ucontext_t *uc = dwarf_get_uc(&c->dwarf); diff --git a/src/native/external/libunwind/src/x86_64/Gstep.c b/src/native/external/libunwind/src/x86_64/Gstep.c index 146c27ee49f92d..72ebbd9643cfbd 100644 --- a/src/native/external/libunwind/src/x86_64/Gstep.c +++ b/src/native/external/libunwind/src/x86_64/Gstep.c @@ -25,10 +25,6 @@ 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_ASM_VSYSCALL_H -#include -#endif - #include "libunwind_i.h" #include "unwind_i.h" #include @@ -57,20 +53,6 @@ is_plt_entry (struct dwarf_cursor *c) return ret; } -static int -is_vsyscall (struct dwarf_cursor *c) -{ -#if defined(VSYSCALL_START) && defined(VSYSCALL_END) - return c->ip >= VSYSCALL_START && c->ip < VSYSCALL_END; -#elif defined(VSYSCALL_ADDR) - /* Linux 3.16 removes `VSYSCALL_START` and `VSYSCALL_END`. Assume - a single page is mapped for vsyscalls. */ - return c->ip >= VSYSCALL_ADDR && c->ip < VSYSCALL_ADDR + sysconf(_SC_PAGESIZE); -#else - return 0; -#endif -} - int unw_step (unw_cursor_t *cursor) { @@ -140,7 +122,15 @@ unw_step (unw_cursor_t *cursor) Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); - if (unw_is_signal_frame (cursor) > 0) + if ((ret = x86_64_os_step (c)) != 0) + { + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + } + else if (unw_is_signal_frame (cursor) > 0) { ret = x86_64_handle_signal_frame(cursor); if (ret < 0) @@ -159,15 +149,6 @@ unw_step (unw_cursor_t *cursor) c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); c->dwarf.cfa += 8; } - else if (is_vsyscall (&c->dwarf)) - { - Debug (2, "in vsyscall region\n"); - c->frame_info.cfa_reg_offset = 8; - c->frame_info.cfa_reg_rsp = -1; - c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; - c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); - c->dwarf.cfa += 8; - } else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) { for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) @@ -231,15 +212,19 @@ unw_step (unw_cursor_t *cursor) */ 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); + rbp_loc = c->dwarf.loc[RBP]; + rsp_loc = DWARF_VAL_LOC (c, rsp + 8); 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); + { + Debug (2, "new_ip 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used) != 0\n", new_ip); + } } - else + 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 diff --git a/src/native/external/libunwind/src/x86_64/Gtrace.c b/src/native/external/libunwind/src/x86_64/Gtrace.c index 7f8964199b61bd..491085165fdda2 100644 --- a/src/native/external/libunwind/src/x86_64/Gtrace.c +++ b/src/native/external/libunwind/src/x86_64/Gtrace.c @@ -69,7 +69,7 @@ trace_cache_free (void *arg) } tls_cache_destroyed = 1; tls_cache = NULL; - munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mi_munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); mempool_free (&trace_cache_pool, cache); Debug(5, "freed cache %p\n", cache); } @@ -151,7 +151,7 @@ trace_cache_expand (unw_trace_cache_t *cache) } Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); - munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + mi_munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); cache->frames = new_frames; cache->log_size = new_log_size; cache->used = 0; @@ -406,7 +406,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) int ret; int validate UNUSED = 0; - /* Check input parametres. */ + /* Check input parameters. */ if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) return -UNW_EINVAL; @@ -477,6 +477,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) /* Fall thru to standard processing after forcing validation. */ if (d->as == unw_local_addr_space) dwarf_set_validate(d, 1); + FALLTHROUGH; case UNW_X86_64_FRAME_STANDARD: /* Advance standard traceable frame. */ diff --git a/src/native/external/libunwind/src/x86_64/Los-qnx.c b/src/native/external/libunwind/src/x86_64/Los-qnx.c new file mode 100644 index 00000000000000..05c771bb944214 --- /dev/null +++ b/src/native/external/libunwind/src/x86_64/Los-qnx.c @@ -0,0 +1,29 @@ +/* + * Copyright 2022 BlackBerry Limited. + * + * 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. + */ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-qnx.c" +#endif diff --git a/src/native/external/libunwind/src/x86_64/getcontext.S b/src/native/external/libunwind/src/x86_64/getcontext.S index e1450719b7da1a..a08fccd6c32288 100644 --- a/src/native/external/libunwind/src/x86_64/getcontext.S +++ b/src/native/external/libunwind/src/x86_64/getcontext.S @@ -88,6 +88,7 @@ _Ux86_64_getcontext: movw %gs, UC_MCONTEXT_GS(%rdi) #endif movq $UC_MCONTEXT_MC_LEN_VAL, UC_MCONTEXT_MC_LEN(%rdi) +#elif defined(__QNX__) #else #error Port me #endif diff --git a/src/native/external/libunwind/src/x86_64/is_fpreg.c b/src/native/external/libunwind/src/x86_64/is_fpreg.c index 5c036137b630fc..8edf6d3a444ed1 100644 --- a/src/native/external/libunwind/src/x86_64/is_fpreg.c +++ b/src/native/external/libunwind/src/x86_64/is_fpreg.c @@ -28,7 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "libunwind_i.h" int -unw_is_fpreg (int regnum) +unw_is_fpreg (int regnum UNUSED) { #if 0 return ((regnum >= UNW_X86_ST0 && regnum <= UNW_X86_ST7) diff --git a/src/native/external/libunwind/src/x86_64/offsets.h b/src/native/external/libunwind/src/x86_64/offsets.h deleted file mode 100644 index 0807960f30c0c9..00000000000000 --- a/src/native/external/libunwind/src/x86_64/offsets.h +++ /dev/null @@ -1,3 +0,0 @@ -/* FreeBSD specific definitions */ - -#define FREEBSD_UC_MCONTEXT_OFF 0x10 diff --git a/src/native/external/libunwind/src/x86_64/setcontext.S b/src/native/external/libunwind/src/x86_64/setcontext.S index 17e5ae12032aad..17c4b94ba23b1d 100644 --- a/src/native/external/libunwind/src/x86_64/setcontext.S +++ b/src/native/external/libunwind/src/x86_64/setcontext.S @@ -54,6 +54,7 @@ _Ux86_64_setcontext: jne 1f fxrstor UC_MCONTEXT_FPSTATE(%rdi) 1: +#elif defined (__QNX__) #else #error Port me #endif diff --git a/src/native/external/libunwind/src/x86_64/siglongjmp.S b/src/native/external/libunwind/src/x86_64/siglongjmp.S index 32489e53a9f19c..c75d027c09a7cb 100644 --- a/src/native/external/libunwind/src/x86_64/siglongjmp.S +++ b/src/native/external/libunwind/src/x86_64/siglongjmp.S @@ -23,10 +23,28 @@ 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(__FreeBSD__) +#define SIG_SETMASK 3 +#endif + .globl _UI_siglongjmp_cont .type _UI_siglongjmp_cont, @function _UI_siglongjmp_cont: +#if defined(__linux__) || defined(__QNX__) retq +#elif defined(__FreeBSD__) + pushq %rax /* return address */ + pushq %rdx /* return value */ + movq $SIG_SETMASK,%rdi + movq %rcx,%rsi + xorq %rdx,%rdx + movq $340,%rax + syscall + popq %rax /* return value */ + retq /* return address on stack */ +#else +#error Port me +#endif .size _UI_siglongjmp_cont, . - _UI_siglongjmp_cont /* We do not need executable stack. */ .section .note.GNU-stack,"",@progbits diff --git a/src/native/external/libunwind/src/x86_64/ucontext_i.h b/src/native/external/libunwind/src/x86_64/ucontext_i.h index e886c948453ceb..a4c0d340239825 100644 --- a/src/native/external/libunwind/src/x86_64/ucontext_i.h +++ b/src/native/external/libunwind/src/x86_64/ucontext_i.h @@ -78,6 +78,25 @@ 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(__QNX__) +#define UC_SIGMASK 0x0 +#define UC_MCONTEXT_GREGS_R8 0x48 +#define UC_MCONTEXT_GREGS_R9 0x50 +#define UC_MCONTEXT_GREGS_R10 0x40 +#define UC_MCONTEXT_GREGS_R11 0x78 +#define UC_MCONTEXT_GREGS_R12 0x80 +#define UC_MCONTEXT_GREGS_R13 0x88 +#define UC_MCONTEXT_GREGS_R14 0x90 +#define UC_MCONTEXT_GREGS_R15 0x98 +#define UC_MCONTEXT_GREGS_RDI 0x28 +#define UC_MCONTEXT_GREGS_RSI 0x30 +#define UC_MCONTEXT_GREGS_RBP 0x68 +#define UC_MCONTEXT_GREGS_RBX 0x60 +#define UC_MCONTEXT_GREGS_RDX 0x38 +#define UC_MCONTEXT_GREGS_RAX 0x58 +#define UC_MCONTEXT_GREGS_RCX 0x70 +#define UC_MCONTEXT_GREGS_RSP 0xb8 +#define UC_MCONTEXT_GREGS_RIP 0xa0 #elif defined __sun #define UC_MCONTEXT_GREGS_R8 0x78 #define UC_MCONTEXT_GREGS_R9 0x70 diff --git a/src/native/external/libunwind/src/x86_64/unwind_i.h b/src/native/external/libunwind/src/x86_64/unwind_i.h index 49fa078fb21cf2..a20c22f99d37a7 100644 --- a/src/native/external/libunwind/src/x86_64/unwind_i.h +++ b/src/native/external/libunwind/src/x86_64/unwind_i.h @@ -89,5 +89,7 @@ extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); extern NORETURN void x86_64_sigreturn (unw_cursor_t *cursor); #define x86_64_handle_signal_frame UNW_OBJ(handle_signal_frame) extern int x86_64_handle_signal_frame(unw_cursor_t *cursor); +#define x86_64_os_step UNW_OBJ(os_step) +extern HIDDEN int x86_64_os_step(struct cursor *c); #endif /* unwind_i_h */ diff --git a/src/native/external/libunwind/tests/Gperf-simple.c b/src/native/external/libunwind/tests/Gperf-simple.c index e1819182140349..20406050348111 100644 --- a/src/native/external/libunwind/tests/Gperf-simple.c +++ b/src/native/external/libunwind/tests/Gperf-simple.c @@ -38,7 +38,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ long dummy; static long iterations = 10000; -static int maxlevel = 100; #define KB 1024 #define MB (1024*1024) @@ -110,7 +109,7 @@ f1 (int level, int maxlevel, double *step) } static void -doit (const char *label) +doit (const char *label, int maxlevel) { double step, min_step, first_step, sum_step; int i; @@ -232,10 +231,11 @@ measure_init (void) int main (int argc, char **argv) { - struct rlimit rlim; - - rlim.rlim_cur = RLIM_INFINITY; - rlim.rlim_max = RLIM_INFINITY; + int maxlevel = 100; + struct rlimit rlim = { + .rlim_cur = RLIM_INFINITY, + .rlim_max = RLIM_INFINITY + }; setrlimit (RLIMIT_STACK, &rlim); memset (big, 0xaa, sizeof (big)); @@ -244,21 +244,21 @@ main (int argc, char **argv) { maxlevel = atol (argv[1]); if (argc > 2) - iterations = atol (argv[2]); + iterations = atol (argv[2]); } measure_init (); - doit ("default "); + doit ("default ", maxlevel); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); - doit ("no cache "); + doit ("no cache ", maxlevel); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); - doit ("global cache "); + doit ("global cache ", maxlevel); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); - doit ("per-thread cache"); + doit ("per-thread cache", maxlevel); return 0; } diff --git a/src/native/external/libunwind/tests/Gperf-trace.c b/src/native/external/libunwind/tests/Gperf-trace.c index 4d24fa5ca86574..51ee5ee69f6d98 100644 --- a/src/native/external/libunwind/tests/Gperf-trace.c +++ b/src/native/external/libunwind/tests/Gperf-trace.c @@ -32,13 +32,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#define panic(args...) \ - do { fprintf (stderr, args); exit (-1); } while (0) +#define panic(...) \ + do { fprintf (stderr, __VA_ARGS__); exit (-1); } while (0) long dummy; static long iterations = 10000; -static int maxlevel = 100; #define KB 1024 #define MB (1024*1024) @@ -96,7 +95,7 @@ f1 (int level, int maxlevel, double *step) } static void -doit (const char *label) +doit (const char *label, int maxlevel) { double step, min_step, first_step, sum_step; int i; @@ -218,10 +217,11 @@ measure_init (void) int main (int argc, char **argv) { - struct rlimit rlim; - - rlim.rlim_cur = RLIM_INFINITY; - rlim.rlim_max = RLIM_INFINITY; + int maxlevel = 100; + struct rlimit rlim = { + .rlim_cur = RLIM_INFINITY, + .rlim_max = RLIM_INFINITY + }; setrlimit (RLIMIT_STACK, &rlim); memset (big, 0xaa, sizeof (big)); @@ -230,21 +230,21 @@ main (int argc, char **argv) { maxlevel = atol (argv[1]); if (argc > 2) - iterations = atol (argv[2]); + iterations = atol (argv[2]); } measure_init (); - doit ("default "); + doit ("default ", maxlevel); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); - doit ("no cache "); + doit ("no cache ", maxlevel); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); - doit ("global cache "); + doit ("global cache ", maxlevel); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); - doit ("per-thread cache"); + doit ("per-thread cache", maxlevel); return 0; } diff --git a/src/native/external/libunwind/tests/Gtest-bt.c b/src/native/external/libunwind/tests/Gtest-bt.c index 809970db93d57e..d1ac6f3d421cb0 100644 --- a/src/native/external/libunwind/tests/Gtest-bt.c +++ b/src/native/external/libunwind/tests/Gtest-bt.c @@ -38,17 +38,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include +#include #include #include #include -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } +#include "ident.h" + +#define panic(...) \ + { fprintf (stderr, __VA_ARGS__); exit (-1); } #define SIG_STACK_SIZE 0x100000 int verbose; int num_errors; +sigjmp_buf env; /* These variables are global because they * cause the signal stack to overflow */ @@ -102,6 +106,10 @@ do_backtrace (void) } #endif printf ("\n"); + + name[0] = '\0'; + if (unw_get_elf_filename (&cursor, name, sizeof (name), &off) == UNW_ESUCCESS) + printf ("\t[%s+0x%lx]\n", name, (long) off); } ret = unw_step (&cursor); @@ -137,8 +145,8 @@ foo (long val UNUSED) void bar (long v) { - extern long f (long); int arr[v]; + arr[0] = 0; /* This is a vain attempt to use up lots of registers to force the frame-chain info to be saved on the memory stack on ia64. @@ -166,7 +174,17 @@ bar (long v) } void -sighandler (int signal, void *siginfo UNUSED, void *context) +segv_handler (int signal, siginfo_t *siginfo UNUSED, void *context UNUSED) +{ + if (verbose) + fprintf (stderr, "segv_handler: got signal %d\n", signal); + + do_backtrace (); + siglongjmp (env, 42); +} + +void +sighandler (int signal, siginfo_t *siginfo UNUSED, void *context) { ucontext_t *uc UNUSED; int sp; @@ -175,7 +193,7 @@ sighandler (int signal, void *siginfo UNUSED, void *context) if (verbose) { - printf ("sighandler: got signal %d, sp=%p", signal, &sp); + printf ("sighandler: got signal %d, sp=%p", signal, (void *)&sp); #if UNW_TARGET_IA64 # if defined(__linux__) || defined __sun printf (" @ %lx", uc->uc_mcontext.sc_ip); @@ -202,9 +220,9 @@ sighandler (int signal, void *siginfo UNUSED, void *context) printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); # endif #elif UNW_TARGET_AARCH64 -# if defined(__QNXNTO__) +# if defined(__QNX__) fprintf (stderr, " @ %#010lx", (unsigned long) uc->uc_mcontext.cpu.elr); -# endif /* defined(__QNXNTO__) */ +# endif /* defined(__QNX__) */ #endif printf ("\n"); } @@ -227,8 +245,8 @@ main (int argc, char **argv UNUSED) bar (1); memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; act.sa_flags = SA_SIGINFO; + act.sa_sigaction = sighandler; if (sigaction (SIGTERM, &act, NULL) < 0) panic ("sigaction: %s\n", strerror (errno)); @@ -236,6 +254,20 @@ main (int argc, char **argv UNUSED) printf ("\nBacktrace across signal handler:\n"); kill (getpid (), SIGTERM); + if (verbose) + printf ("\nBacktrace across SIGSEGV handler:\n"); + + act.sa_sigaction = segv_handler; + if (sigaction (SIGSEGV, &act, NULL) < 0) + panic ("sigaction: %s\n", strerror (errno)); + + if (sigsetjmp (env, 1) == 0) + { + /* Make a NULL pointer dereference. */ + int *bad_ptr = NULL; + *bad_ptr = 0; + } + #ifdef HAVE_SIGALTSTACK if (verbose) printf ("\nBacktrace across signal handler on alternate stack:\n"); @@ -248,8 +280,8 @@ main (int argc, char **argv UNUSED) panic ("sigaltstack: %s\n", strerror (errno)); memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; act.sa_flags = SA_ONSTACK | SA_SIGINFO; + act.sa_sigaction = sighandler; if (sigaction (SIGTERM, &act, NULL) < 0) panic ("sigaction: %s\n", strerror (errno)); kill (getpid (), SIGTERM); diff --git a/src/native/external/libunwind/tests/Gtest-concurrent.c b/src/native/external/libunwind/tests/Gtest-concurrent.c index 6f3447fd844da1..64c337ff63c1f7 100644 --- a/src/native/external/libunwind/tests/Gtest-concurrent.c +++ b/src/native/external/libunwind/tests/Gtest-concurrent.c @@ -39,8 +39,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define NTHREADS 128 -#define panic(args...) \ - do { fprintf (stderr, args); ++nerrors; } while (0) +#define panic(...) \ + do { fprintf (stderr, __VA_ARGS__); ++nerrors; } while (0) int verbose; int nerrors; diff --git a/src/native/external/libunwind/tests/Gtest-exc.c b/src/native/external/libunwind/tests/Gtest-exc.c index 29c1993f2dee8b..5474fa41b28900 100644 --- a/src/native/external/libunwind/tests/Gtest-exc.c +++ b/src/native/external/libunwind/tests/Gtest-exc.c @@ -40,8 +40,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # include #endif -#define panic(args...) \ - { ++nerrors; fprintf (stderr, args); } +#define panic(...) \ + { ++nerrors; fprintf (stderr, __VA_ARGS__); } int nerrors = 0; int verbose = 0; @@ -112,7 +112,7 @@ a (int n) if (verbose) printf ("a(n=%d): sp=%p bsp=0x%lx\n", - n, &stack, (unsigned long) get_bsp ()); + n, (void *)&stack, (unsigned long) get_bsp ()); if (n > 0) a (n - 1); @@ -122,7 +122,7 @@ a (int n) if (verbose) { printf ("exception handler: here we go (sp=%p, bsp=0x%lx)...\n", - &stack, (unsigned long) get_bsp ()); + (void *)&stack, (unsigned long) get_bsp ()); /* This call works around a bug in gcc (up-to pre3.4) which causes invalid assembly code to be generated when __builtin_ia64_bsp() gets predicated. */ diff --git a/src/native/external/libunwind/tests/Gtest-init.cxx b/src/native/external/libunwind/tests/Gtest-init.cxx index afded019273f53..b50c65979bbab0 100644 --- a/src/native/external/libunwind/tests/Gtest-init.cxx +++ b/src/native/external/libunwind/tests/Gtest-init.cxx @@ -49,7 +49,8 @@ static void do_backtrace (void) { char name[128], off[32]; - unw_word_t ip, offset; + char filename[256]; + unw_word_t ip, offset, file_offset; unw_cursor_t cursor; unw_context_t uc; int ret, count = 0; @@ -63,12 +64,17 @@ do_backtrace (void) name[0] = '\0'; off[0] = '\0'; if (unw_get_proc_name (&cursor, name, sizeof (name), &offset) == 0 - && offset > 0) - snprintf (off, sizeof (off), "+0x%lx", (long) offset); + && offset > 0) + snprintf (off, sizeof (off), "+0x%lx", (long) offset); if (verbose) - printf (" [%lx] <%s%s>\n", (long) ip, name, off); + printf (" [%lx] <%s%s>\n", (long) ip, name, off); + + if (unw_get_elf_filename (&cursor, filename, sizeof (filename), &file_offset) == 0) + if (verbose) + printf (" [%s+0x%lx]\n", filename, (long) file_offset); + if (++count > 32) - panic ("FAILURE: didn't reach beginning of unwind-chain\n"); + panic ("FAILURE: didn't reach beginning of unwind-chain\n"); } while ((ret = unw_step (&cursor)) > 0); diff --git a/src/native/external/libunwind/tests/Gtest-resume-sig.c b/src/native/external/libunwind/tests/Gtest-resume-sig.c index 18ec65da713440..cda8a5cd83e326 100644 --- a/src/native/external/libunwind/tests/Gtest-resume-sig.c +++ b/src/native/external/libunwind/tests/Gtest-resume-sig.c @@ -41,8 +41,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # include #endif -#define panic(args...) \ - do { fprintf (stderr, args); ++nerrors; } while (0) +#define panic(...) \ + do { fprintf (stderr, __VA_ARGS__); ++nerrors; } while (0) int verbose; int nerrors; @@ -119,11 +119,6 @@ handler (int sig) if ((ret = unw_step (&c)) < 0) /* step to kill() */ panic ("unw_step(2) failed: ret=%d\n", ret); -#if defined(UNW_TARGET_TILEGX) - if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */ - panic ("unw_step(2) failed: ret=%d\n", ret); -#endif - if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0) panic ("unw_get_reg(IP) failed: ret=%d\n", ret); if (verbose) diff --git a/src/native/external/libunwind/tests/Gtest-trace.c b/src/native/external/libunwind/tests/Gtest-trace.c index 5f22f1fb779865..a505f0ccd5e4ce 100644 --- a/src/native/external/libunwind/tests/Gtest-trace.c +++ b/src/native/external/libunwind/tests/Gtest-trace.c @@ -40,8 +40,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } +#include "ident.h" + +#define panic(...) \ + { fprintf (stderr, __VA_ARGS__); exit (-1); } #define SIG_STACK_SIZE 0x100000 @@ -80,7 +82,7 @@ do_backtrace (void) if (ret < 0) { unw_get_reg (&cursor, UNW_REG_IP, &ip); - printf ("FAILURE: unw_step() returned %d for ip=%lx\n", ret, (long) ip); + printf ("FAILURE: unw_step() returned %d for ip=%#010lx\n", ret, (long) ip); ++num_errors; } @@ -121,7 +123,7 @@ do_backtrace (void) if (n == m) for (i = 1; i < n; ++i) /* Allow one in difference in comparison, trace returns adjusted addresses. */ - if (labs((unw_word_t) addresses[1][i] - (unw_word_t) addresses[2][i]) > 1) + if (labs (addresses[1][i] - addresses[2][i]) > 1) { printf ("FAILURE: backtrace() and unw_backtrace() addresses differ at %d: %p vs. %p\n", i, addresses[1][i], addresses[2][i]); @@ -131,7 +133,7 @@ do_backtrace (void) if (n == depth+1) for (i = 1; i < depth; ++i) /* Allow one in difference in comparison, trace returns adjusted addresses. */ - if (labs((unw_word_t) addresses[0][i] - (unw_word_t) addresses[1][i]) > 1) + if (labs (addresses[0][i] - addresses[1][i]) > 1) { printf ("FAILURE: unw_step() loop and backtrace() addresses differ at %d: %p vs. %p\n", i, addresses[0][i], addresses[1][i]); @@ -163,7 +165,7 @@ do_backtrace_with_context(void *context) if (ret < 0) { unw_get_reg (&cursor, UNW_REG_IP, &ip); - printf ("FAILURE: unw_step() returned %d for ip=%lx\n", ret, (long) ip); + printf ("FAILURE: unw_step() returned %d for ip=%#010lx\n", ret, (long) ip); ++num_errors; } @@ -189,9 +191,9 @@ do_backtrace_with_context(void *context) if (m == depth + 1) for (i = 0; i < depth; ++i) /* Allow one in difference in comparison, trace returns adjusted addresses. */ - if (labs((unw_word_t) addresses[0][i] - (unw_word_t) addresses[1][i]) > 1) + if ( labs(addresses[0][i] - addresses[1][i]) > 1) { - printf ("FAILURE: unw_step() loop and uwn_backtrace2() addresses differ at %d: %p vs. %p\n", + printf ("FAILURE: unw_step() loop and unw_backtrace2() addresses differ at %d: %p vs. %p\n", i, addresses[0][i], addresses[1][i]); ++num_errors; } @@ -206,8 +208,8 @@ foo (long val UNUSED) void bar (long v) { - extern long f (long); int arr[v]; + arr[0] = 0; /* This is a vain attempt to use up lots of registers to force the frame-chain info to be saved on the memory stack on ia64. @@ -235,7 +237,7 @@ bar (long v) } void -sighandler (int signal, void *siginfo UNUSED, void *context) +sighandler (int signal, siginfo_t *siginfo UNUSED, void *context) { ucontext_t *uc UNUSED; int sp; @@ -244,10 +246,10 @@ sighandler (int signal, void *siginfo UNUSED, void *context) if (verbose) { - printf ("sighandler: got signal %d, sp=%p", signal, &sp); + printf ("sighandler: got signal %d, sp=%p", signal, (void *)&sp); #if UNW_TARGET_IA64 # if defined(__linux__) - printf (" @ %lx", uc->uc_mcontext.sc_ip); + printf (" @ %#010lx", uc->uc_mcontext.sc_ip); # else { uint16_t reason; @@ -255,26 +257,26 @@ sighandler (int signal, void *siginfo UNUSED, void *context) __uc_get_reason (uc, &reason); __uc_get_ip (uc, &ip); - printf (" @ %lx (reason=%d)", ip, reason); + printf (" @ %#010lx (reason=%d)", ip, reason); } # endif #elif UNW_TARGET_X86 #if defined __linux__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); + printf (" @ %#010lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); #elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); + printf (" @ %#010lx", (unsigned long) uc->uc_mcontext.mc_eip); #endif #elif UNW_TARGET_X86_64 #if defined __linux__ || defined __sun - printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); + printf (" @ %#010lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); #elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); + printf (" @ %#010lx", (unsigned long) uc->uc_mcontext.mc_rip); #endif #elif defined UNW_TARGET_ARM #if defined __linux__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.arm_pc); + printf (" @ %#010lx", (unsigned long) uc->uc_mcontext.arm_pc); #elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.__gregs[_REG_PC]); + printf (" @ %#010lx", (unsigned long) uc->uc_mcontext.__gregs[_REG_PC]); #endif #endif printf ("\n"); @@ -299,7 +301,7 @@ main (int argc, char **argv UNUSED) bar (1); memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; + act.sa_sigaction = sighandler; act.sa_flags = SA_SIGINFO; if (sigaction (SIGTERM, &act, NULL) < 0) panic ("sigaction: %s\n", strerror (errno)); @@ -320,7 +322,7 @@ main (int argc, char **argv UNUSED) panic ("sigaltstack: %s\n", strerror (errno)); memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; + act.sa_sigaction = sighandler; act.sa_flags = SA_ONSTACK | SA_SIGINFO; if (sigaction (SIGTERM, &act, NULL) < 0) panic ("sigaction: %s\n", strerror (errno)); diff --git a/src/native/external/libunwind/tests/Gx64-test-dwarf-expressions.c b/src/native/external/libunwind/tests/Gx64-test-dwarf-expressions.c index 209f87131248da..486722d0047923 100644 --- a/src/native/external/libunwind/tests/Gx64-test-dwarf-expressions.c +++ b/src/native/external/libunwind/tests/Gx64-test-dwarf-expressions.c @@ -3,12 +3,13 @@ #include #include +#include "compiler.h" static int verbose; static int nerrors; -#define panic(args...) \ - do { printf (args); ++nerrors; } while (0) +#define panic(...) \ + do { printf (__VA_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 @@ -46,7 +47,7 @@ extern int64_t recover_register(int64_t regnum, int64_t height) } int -main (int argc, char **argv) +main (int argc, char **argv UNUSED) { if (argc > 1) verbose = 1; diff --git a/src/native/external/libunwind/tests/Lrs-race.c b/src/native/external/libunwind/tests/Lrs-race.c index 6fe4972020d022..ec9dcf990fae9a 100644 --- a/src/native/external/libunwind/tests/Lrs-race.c +++ b/src/native/external/libunwind/tests/Lrs-race.c @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ int verbose; -void +NOINLINE void foo_0 (void) { void *buf[20]; @@ -53,7 +53,7 @@ foo_0 (void) abort (); } -void +NOINLINE void foo_1 (void) { void *buf[20]; @@ -63,7 +63,7 @@ foo_1 (void) abort (); } -void +NOINLINE void foo_2 (void) { void *buf[20]; @@ -73,7 +73,7 @@ foo_2 (void) abort (); } -void +NOINLINE void foo_3 (void) { void *buf[20]; @@ -83,7 +83,7 @@ foo_3 (void) abort (); } -void +NOINLINE void foo_4 (void) { void *buf[20]; @@ -93,7 +93,7 @@ foo_4 (void) abort (); } -void +NOINLINE void foo_5 (void) { void *buf[20]; @@ -103,7 +103,7 @@ foo_5 (void) abort (); } -void +NOINLINE void foo_6 (void) { void *buf[20]; @@ -113,7 +113,7 @@ foo_6 (void) abort (); } -void +NOINLINE void foo_7 (void) { void *buf[20]; @@ -123,7 +123,7 @@ foo_7 (void) abort (); } -void +NOINLINE void foo_8 (void) { void *buf[20]; @@ -133,7 +133,7 @@ foo_8 (void) abort (); } -void +NOINLINE void foo_9 (void) { void *buf[20]; @@ -143,7 +143,7 @@ foo_9 (void) abort (); } -void +NOINLINE void foo_10 (void) { void *buf[20]; @@ -153,7 +153,7 @@ foo_10 (void) abort (); } -void +NOINLINE void foo_11 (void) { void *buf[20]; @@ -163,7 +163,7 @@ foo_11 (void) abort (); } -void +NOINLINE void foo_12 (void) { void *buf[20]; @@ -173,7 +173,7 @@ foo_12 (void) abort (); } -void +NOINLINE void foo_13 (void) { void *buf[20]; @@ -183,7 +183,7 @@ foo_13 (void) abort (); } -void +NOINLINE void foo_14 (void) { void *buf[20]; @@ -193,7 +193,7 @@ foo_14 (void) abort (); } -void +NOINLINE void foo_15 (void) { void *buf[20]; @@ -203,7 +203,7 @@ foo_15 (void) abort (); } -void +NOINLINE void foo_16 (void) { void *buf[20]; @@ -213,7 +213,7 @@ foo_16 (void) abort (); } -void +NOINLINE void foo_17 (void) { void *buf[20]; @@ -223,7 +223,7 @@ foo_17 (void) abort (); } -void +NOINLINE void foo_18 (void) { void *buf[20]; @@ -233,7 +233,7 @@ foo_18 (void) abort (); } -void +NOINLINE void foo_19 (void) { void *buf[20]; @@ -243,7 +243,7 @@ foo_19 (void) abort (); } -void +NOINLINE void foo_20 (void) { void *buf[20]; @@ -253,7 +253,7 @@ foo_20 (void) abort (); } -void +NOINLINE void foo_21 (void) { void *buf[20]; @@ -263,7 +263,7 @@ foo_21 (void) abort (); } -void +NOINLINE void foo_22 (void) { void *buf[20]; @@ -273,7 +273,7 @@ foo_22 (void) abort (); } -void +NOINLINE void foo_23 (void) { void *buf[20]; @@ -283,7 +283,7 @@ foo_23 (void) abort (); } -void +NOINLINE void foo_24 (void) { void *buf[20]; @@ -293,7 +293,7 @@ foo_24 (void) abort (); } -void +NOINLINE void foo_25 (void) { void *buf[20]; @@ -303,7 +303,7 @@ foo_25 (void) abort (); } -void +NOINLINE void foo_26 (void) { void *buf[20]; @@ -313,7 +313,7 @@ foo_26 (void) abort (); } -void +NOINLINE void foo_27 (void) { void *buf[20]; @@ -323,7 +323,7 @@ foo_27 (void) abort (); } -void +NOINLINE void foo_28 (void) { void *buf[20]; @@ -333,7 +333,7 @@ foo_28 (void) abort (); } -void +NOINLINE void foo_29 (void) { void *buf[20]; @@ -343,7 +343,7 @@ foo_29 (void) abort (); } -void +NOINLINE void foo_30 (void) { void *buf[20]; @@ -353,7 +353,7 @@ foo_30 (void) abort (); } -void +NOINLINE void foo_31 (void) { void *buf[20]; @@ -363,7 +363,7 @@ foo_31 (void) abort (); } -void +NOINLINE void foo_32 (void) { void *buf[20]; @@ -373,7 +373,7 @@ foo_32 (void) abort (); } -void +NOINLINE void foo_33 (void) { void *buf[20]; @@ -383,7 +383,7 @@ foo_33 (void) abort (); } -void +NOINLINE void foo_34 (void) { void *buf[20]; @@ -393,7 +393,7 @@ foo_34 (void) abort (); } -void +NOINLINE void foo_35 (void) { void *buf[20]; @@ -403,7 +403,7 @@ foo_35 (void) abort (); } -void +NOINLINE void foo_36 (void) { void *buf[20]; @@ -413,7 +413,7 @@ foo_36 (void) abort (); } -void +NOINLINE void foo_37 (void) { void *buf[20]; @@ -423,7 +423,7 @@ foo_37 (void) abort (); } -void +NOINLINE void foo_38 (void) { void *buf[20]; @@ -433,7 +433,7 @@ foo_38 (void) abort (); } -void +NOINLINE void foo_39 (void) { void *buf[20]; @@ -443,7 +443,7 @@ foo_39 (void) abort (); } -void +NOINLINE void foo_40 (void) { void *buf[20]; @@ -453,7 +453,7 @@ foo_40 (void) abort (); } -void +NOINLINE void foo_41 (void) { void *buf[20]; @@ -463,7 +463,7 @@ foo_41 (void) abort (); } -void +NOINLINE void foo_42 (void) { void *buf[20]; @@ -473,7 +473,7 @@ foo_42 (void) abort (); } -void +NOINLINE void foo_43 (void) { void *buf[20]; @@ -483,7 +483,7 @@ foo_43 (void) abort (); } -void +NOINLINE void foo_44 (void) { void *buf[20]; @@ -493,7 +493,7 @@ foo_44 (void) abort (); } -void +NOINLINE void foo_45 (void) { void *buf[20]; @@ -503,7 +503,7 @@ foo_45 (void) abort (); } -void +NOINLINE void foo_46 (void) { void *buf[20]; @@ -513,7 +513,7 @@ foo_46 (void) abort (); } -void +NOINLINE void foo_47 (void) { void *buf[20]; @@ -523,7 +523,7 @@ foo_47 (void) abort (); } -void +NOINLINE void foo_48 (void) { void *buf[20]; @@ -533,7 +533,7 @@ foo_48 (void) abort (); } -void +NOINLINE void foo_49 (void) { void *buf[20]; @@ -543,7 +543,7 @@ foo_49 (void) abort (); } -void +NOINLINE void foo_50 (void) { void *buf[20]; @@ -553,7 +553,7 @@ foo_50 (void) abort (); } -void +NOINLINE void foo_51 (void) { void *buf[20]; @@ -563,7 +563,7 @@ foo_51 (void) abort (); } -void +NOINLINE void foo_52 (void) { void *buf[20]; @@ -573,7 +573,7 @@ foo_52 (void) abort (); } -void +NOINLINE void foo_53 (void) { void *buf[20]; @@ -583,7 +583,7 @@ foo_53 (void) abort (); } -void +NOINLINE void foo_54 (void) { void *buf[20]; @@ -593,7 +593,7 @@ foo_54 (void) abort (); } -void +NOINLINE void foo_55 (void) { void *buf[20]; @@ -603,7 +603,7 @@ foo_55 (void) abort (); } -void +NOINLINE void foo_56 (void) { void *buf[20]; @@ -613,7 +613,7 @@ foo_56 (void) abort (); } -void +NOINLINE void foo_57 (void) { void *buf[20]; @@ -623,7 +623,7 @@ foo_57 (void) abort (); } -void +NOINLINE void foo_58 (void) { void *buf[20]; @@ -633,7 +633,7 @@ foo_58 (void) abort (); } -void +NOINLINE void foo_59 (void) { void *buf[20]; @@ -643,7 +643,7 @@ foo_59 (void) abort (); } -void +NOINLINE void foo_60 (void) { void *buf[20]; @@ -653,7 +653,7 @@ foo_60 (void) abort (); } -void +NOINLINE void foo_61 (void) { void *buf[20]; @@ -663,7 +663,7 @@ foo_61 (void) abort (); } -void +NOINLINE void foo_62 (void) { void *buf[20]; @@ -673,7 +673,7 @@ foo_62 (void) abort (); } -void +NOINLINE void foo_63 (void) { void *buf[20]; @@ -683,7 +683,7 @@ foo_63 (void) abort (); } -void +NOINLINE void foo_64 (void) { void *buf[20]; @@ -693,7 +693,7 @@ foo_64 (void) abort (); } -void +NOINLINE void foo_65 (void) { void *buf[20]; @@ -703,7 +703,7 @@ foo_65 (void) abort (); } -void +NOINLINE void foo_66 (void) { void *buf[20]; @@ -713,7 +713,7 @@ foo_66 (void) abort (); } -void +NOINLINE void foo_67 (void) { void *buf[20]; @@ -723,7 +723,7 @@ foo_67 (void) abort (); } -void +NOINLINE void foo_68 (void) { void *buf[20]; @@ -733,7 +733,7 @@ foo_68 (void) abort (); } -void +NOINLINE void foo_69 (void) { void *buf[20]; @@ -743,7 +743,7 @@ foo_69 (void) abort (); } -void +NOINLINE void foo_70 (void) { void *buf[20]; @@ -753,7 +753,7 @@ foo_70 (void) abort (); } -void +NOINLINE void foo_71 (void) { void *buf[20]; @@ -763,7 +763,7 @@ foo_71 (void) abort (); } -void +NOINLINE void foo_72 (void) { void *buf[20]; @@ -773,7 +773,7 @@ foo_72 (void) abort (); } -void +NOINLINE void foo_73 (void) { void *buf[20]; @@ -783,7 +783,7 @@ foo_73 (void) abort (); } -void +NOINLINE void foo_74 (void) { void *buf[20]; @@ -793,7 +793,7 @@ foo_74 (void) abort (); } -void +NOINLINE void foo_75 (void) { void *buf[20]; @@ -803,7 +803,7 @@ foo_75 (void) abort (); } -void +NOINLINE void foo_76 (void) { void *buf[20]; @@ -813,7 +813,7 @@ foo_76 (void) abort (); } -void +NOINLINE void foo_77 (void) { void *buf[20]; @@ -823,7 +823,7 @@ foo_77 (void) abort (); } -void +NOINLINE void foo_78 (void) { void *buf[20]; @@ -833,7 +833,7 @@ foo_78 (void) abort (); } -void +NOINLINE void foo_79 (void) { void *buf[20]; @@ -843,7 +843,7 @@ foo_79 (void) abort (); } -void +NOINLINE void foo_80 (void) { void *buf[20]; @@ -853,7 +853,7 @@ foo_80 (void) abort (); } -void +NOINLINE void foo_81 (void) { void *buf[20]; @@ -863,7 +863,7 @@ foo_81 (void) abort (); } -void +NOINLINE void foo_82 (void) { void *buf[20]; @@ -873,7 +873,7 @@ foo_82 (void) abort (); } -void +NOINLINE void foo_83 (void) { void *buf[20]; @@ -883,7 +883,7 @@ foo_83 (void) abort (); } -void +NOINLINE void foo_84 (void) { void *buf[20]; @@ -893,7 +893,7 @@ foo_84 (void) abort (); } -void +NOINLINE void foo_85 (void) { void *buf[20]; @@ -903,7 +903,7 @@ foo_85 (void) abort (); } -void +NOINLINE void foo_86 (void) { void *buf[20]; @@ -913,7 +913,7 @@ foo_86 (void) abort (); } -void +NOINLINE void foo_87 (void) { void *buf[20]; @@ -923,7 +923,7 @@ foo_87 (void) abort (); } -void +NOINLINE void foo_88 (void) { void *buf[20]; @@ -933,7 +933,7 @@ foo_88 (void) abort (); } -void +NOINLINE void foo_89 (void) { void *buf[20]; @@ -943,7 +943,7 @@ foo_89 (void) abort (); } -void +NOINLINE void foo_90 (void) { void *buf[20]; @@ -953,7 +953,7 @@ foo_90 (void) abort (); } -void +NOINLINE void foo_91 (void) { void *buf[20]; @@ -963,7 +963,7 @@ foo_91 (void) abort (); } -void +NOINLINE void foo_92 (void) { void *buf[20]; @@ -973,7 +973,7 @@ foo_92 (void) abort (); } -void +NOINLINE void foo_93 (void) { void *buf[20]; @@ -983,7 +983,7 @@ foo_93 (void) abort (); } -void +NOINLINE void foo_94 (void) { void *buf[20]; @@ -993,7 +993,7 @@ foo_94 (void) abort (); } -void +NOINLINE void foo_95 (void) { void *buf[20]; @@ -1003,7 +1003,7 @@ foo_95 (void) abort (); } -void +NOINLINE void foo_96 (void) { void *buf[20]; @@ -1013,7 +1013,7 @@ foo_96 (void) abort (); } -void +NOINLINE void foo_97 (void) { void *buf[20]; @@ -1023,7 +1023,7 @@ foo_97 (void) abort (); } -void +NOINLINE void foo_98 (void) { void *buf[20]; @@ -1033,7 +1033,7 @@ foo_98 (void) abort (); } -void +NOINLINE void foo_99 (void) { void *buf[20]; @@ -1043,7 +1043,7 @@ foo_99 (void) abort (); } -void +NOINLINE void foo_100 (void) { void *buf[20]; @@ -1053,7 +1053,7 @@ foo_100 (void) abort (); } -void +NOINLINE void foo_101 (void) { void *buf[20]; @@ -1063,7 +1063,7 @@ foo_101 (void) abort (); } -void +NOINLINE void foo_102 (void) { void *buf[20]; @@ -1073,7 +1073,7 @@ foo_102 (void) abort (); } -void +NOINLINE void foo_103 (void) { void *buf[20]; @@ -1083,7 +1083,7 @@ foo_103 (void) abort (); } -void +NOINLINE void foo_104 (void) { void *buf[20]; @@ -1093,7 +1093,7 @@ foo_104 (void) abort (); } -void +NOINLINE void foo_105 (void) { void *buf[20]; @@ -1103,7 +1103,7 @@ foo_105 (void) abort (); } -void +NOINLINE void foo_106 (void) { void *buf[20]; @@ -1113,7 +1113,7 @@ foo_106 (void) abort (); } -void +NOINLINE void foo_107 (void) { void *buf[20]; @@ -1123,7 +1123,7 @@ foo_107 (void) abort (); } -void +NOINLINE void foo_108 (void) { void *buf[20]; @@ -1133,7 +1133,7 @@ foo_108 (void) abort (); } -void +NOINLINE void foo_109 (void) { void *buf[20]; @@ -1143,7 +1143,7 @@ foo_109 (void) abort (); } -void +NOINLINE void foo_110 (void) { void *buf[20]; @@ -1153,7 +1153,7 @@ foo_110 (void) abort (); } -void +NOINLINE void foo_111 (void) { void *buf[20]; @@ -1163,7 +1163,7 @@ foo_111 (void) abort (); } -void +NOINLINE void foo_112 (void) { void *buf[20]; @@ -1173,7 +1173,7 @@ foo_112 (void) abort (); } -void +NOINLINE void foo_113 (void) { void *buf[20]; @@ -1183,7 +1183,7 @@ foo_113 (void) abort (); } -void +NOINLINE void foo_114 (void) { void *buf[20]; @@ -1193,7 +1193,7 @@ foo_114 (void) abort (); } -void +NOINLINE void foo_115 (void) { void *buf[20]; @@ -1203,7 +1203,7 @@ foo_115 (void) abort (); } -void +NOINLINE void foo_116 (void) { void *buf[20]; @@ -1213,7 +1213,7 @@ foo_116 (void) abort (); } -void +NOINLINE void foo_117 (void) { void *buf[20]; @@ -1223,7 +1223,7 @@ foo_117 (void) abort (); } -void +NOINLINE void foo_118 (void) { void *buf[20]; @@ -1233,7 +1233,7 @@ foo_118 (void) abort (); } -void +NOINLINE void foo_119 (void) { void *buf[20]; @@ -1243,7 +1243,7 @@ foo_119 (void) abort (); } -void +NOINLINE void foo_120 (void) { void *buf[20]; @@ -1253,7 +1253,7 @@ foo_120 (void) abort (); } -void +NOINLINE void foo_121 (void) { void *buf[20]; @@ -1263,7 +1263,7 @@ foo_121 (void) abort (); } -void +NOINLINE void foo_122 (void) { void *buf[20]; @@ -1273,7 +1273,7 @@ foo_122 (void) abort (); } -void +NOINLINE void foo_123 (void) { void *buf[20]; @@ -1283,7 +1283,7 @@ foo_123 (void) abort (); } -void +NOINLINE void foo_124 (void) { void *buf[20]; @@ -1293,7 +1293,7 @@ foo_124 (void) abort (); } -void +NOINLINE void foo_125 (void) { void *buf[20]; @@ -1303,7 +1303,7 @@ foo_125 (void) abort (); } -void +NOINLINE void foo_126 (void) { void *buf[20]; @@ -1313,7 +1313,7 @@ foo_126 (void) abort (); } -void +NOINLINE void foo_127 (void) { void *buf[20]; @@ -1323,7 +1323,7 @@ foo_127 (void) abort (); } -void +NOINLINE void foo_128 (void) { void *buf[20]; @@ -1333,7 +1333,7 @@ foo_128 (void) abort (); } -void * +NOINLINE void * bar(void *p UNUSED) { int i; diff --git a/src/native/external/libunwind/tests/Ltest-init-local-signal.c b/src/native/external/libunwind/tests/Ltest-init-local-signal.c index 4bde218f3bb2cf..052a421fd18101 100644 --- a/src/native/external/libunwind/tests/Ltest-init-local-signal.c +++ b/src/native/external/libunwind/tests/Ltest-init-local-signal.c @@ -1,4 +1,5 @@ #include "libunwind.h" +#include "compiler.h" #include #include #include @@ -9,6 +10,14 @@ #include #include +static const int max_steps = 10; + +#if defined __FreeBSD__ +#define TRAMPOLINE_DEPTH 4 +#else +#define TRAMPOLINE_DEPTH 2 +#endif + int stepper(unw_cursor_t* c) { int steps = 0; int ret = 1; @@ -19,6 +28,7 @@ int stepper(unw_cursor_t* c) { break; } steps++; + if (steps > max_steps) break; } return steps; } @@ -26,7 +36,7 @@ int stepper(unw_cursor_t* c) { /* Verify that we can step from both ucontext, and from getcontext() * roughly the same. This tests that the IP from ucontext is used * correctly (see impl of unw_init_local2) */ -void handler(int num, siginfo_t* info, void* ucontext) { +void handler(int num UNUSED, siginfo_t* info UNUSED, void* ucontext) { unw_cursor_t c; unw_context_t context; unw_getcontext(&context); @@ -38,11 +48,11 @@ void handler(int num, siginfo_t* info, void* ucontext) { (void)ret; assert(!ret); int getcontext_steps = stepper(&c); - if (ucontext_steps == getcontext_steps - 2) { + if (ucontext_steps == getcontext_steps - TRAMPOLINE_DEPTH) { exit(0); } printf("unw_getcontext steps was %i, ucontext steps was %i, should be %i\n", - getcontext_steps, ucontext_steps, getcontext_steps - 2); + getcontext_steps, ucontext_steps, getcontext_steps - TRAMPOLINE_DEPTH); exit(-1); } diff --git a/src/native/external/libunwind/tests/Ltest-mem-validate.c b/src/native/external/libunwind/tests/Ltest-mem-validate.c index 251c34ea76db4a..6db7958109f725 100644 --- a/src/native/external/libunwind/tests/Ltest-mem-validate.c +++ b/src/native/external/libunwind/tests/Ltest-mem-validate.c @@ -38,12 +38,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } +#define panic(...) \ + { fprintf (stderr, __VA_ARGS__); exit (-1); } void * stack_start; +long page_size; -#define PAGE_SIZE 4096 +#define STEPS 5 +#define STACK_SLICE (sizeof(unw_cursor_t) + sizeof(unw_context_t)) void do_backtrace (void) { @@ -52,8 +54,7 @@ void do_backtrace (void) (steps > 5) before touching the forbidden region in the stack, at which point the unwinding should stop gracefully. */ - mprotect((void*)((uintptr_t)stack_start & ~(PAGE_SIZE - 1)), - PAGE_SIZE, PROT_NONE); + mprotect(stack_start, page_size, PROT_NONE); unw_cursor_t cursor; unw_word_t ip, sp; @@ -71,7 +72,7 @@ void do_backtrace (void) unw_get_reg (&cursor, UNW_REG_SP, &sp); ret = unw_step (&cursor); - printf("ip=%lx, sp=%lx -> %d\n", ip, sp, ret); + printf("ip=%p, sp=%p -> %d\n", (void *)ip, (void *)sp, ret); if (ret < 0) { unw_get_reg (&cursor, UNW_REG_IP, &ip); @@ -80,24 +81,23 @@ void do_backtrace (void) } while (ret > 0); - if (steps < 5) + if (steps < STEPS) { - printf("not enough steps: %d, need 5\n", steps); + printf("not enough steps: %d, need %d\n", steps, STEPS); exit(-1); } printf("success, steps: %d\n", steps); - mprotect((void*)((uintptr_t)stack_start & ~(PAGE_SIZE - 1)), - PAGE_SIZE, PROT_READ|PROT_WRITE); + mprotect(stack_start, page_size, PROT_READ|PROT_WRITE); } void NOINLINE consume_and_run (int depth) { unw_cursor_t cursor; unw_context_t uc; - char string[1024]; + char string[64]; - sprintf (string, "hello %p %p\n", &cursor, &uc); + sprintf (string, "hello %p %p\n", (void *)&cursor, (void *)&uc); if (depth == 0) { do_backtrace(); } else { @@ -105,22 +105,39 @@ void NOINLINE consume_and_run (int depth) } } -int -main (int argc, char **argv UNUSED) +static int NOINLINE is_stack_downward (int *val) { int start; + + return val > &start; +} + +int +main (int argc UNUSED, char **argv UNUSED) +{ + int start, count; unw_context_t uc; unw_cursor_t cursor; - stack_start = &start; - /* - We need to make the frame at least the size protected by - the mprotect call so we are not forbidding access to - unrelated regions. - */ - char string[PAGE_SIZE]; - sprintf (string, "hello\n"); + * We need to make the frame at least the size protected by + * the mprotect call so we are not forbidding access to + * unrelated regions. + * mprotect consume_and_run stack area. + * Check whether stack grows downward or upward. + */ + page_size = sysconf(_SC_PAGESIZE); + if (is_stack_downward(&start)) + { + stack_start = (void *)(((uintptr_t)&start & ~(page_size - 1)) - page_size); + count = (uintptr_t)&start - (uintptr_t)stack_start; + } + else + { + stack_start = (void *)(((uintptr_t)&start & ~(page_size - 1)) + page_size); + count = (uintptr_t)stack_start - (uintptr_t)&start; + } + count = count / STACK_SLICE + STEPS; // Initialize pipe mem validate check, opens file descriptors unw_getcontext(&uc); @@ -149,7 +166,7 @@ main (int argc, char **argv UNUSED) } else { - consume_and_run (10); + consume_and_run (count); return 0; } diff --git a/src/native/external/libunwind/tests/Ltest-nocalloc.c b/src/native/external/libunwind/tests/Ltest-nocalloc.c index f5c31b2a3ee259..8cd365c490f9b0 100644 --- a/src/native/external/libunwind/tests/Ltest-nocalloc.c +++ b/src/native/external/libunwind/tests/Ltest-nocalloc.c @@ -56,10 +56,8 @@ calloc(size_t n, size_t s) if (in_unwind) { num_callocs++; - return NULL; - } else { - return func(n, s); } + return func(n, s); } void * @@ -72,10 +70,8 @@ malloc(size_t s) if (in_unwind) { num_mallocs++; - return NULL; - } else { - return func(s); } + return func(s); } static void diff --git a/src/native/external/libunwind/tests/Makefile.am b/src/native/external/libunwind/tests/Makefile.am index c074107008d7d7..ad28ec28701a0d 100644 --- a/src/native/external/libunwind/tests/Makefile.am +++ b/src/native/external/libunwind/tests/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I$(top_srcdir)/src AM_CFLAGS = -fno-optimize-sibling-calls LOG_DRIVER = $(SHELL) $(UNW_TESTDRIVER) @@ -21,6 +21,8 @@ check_SCRIPTS_arch = check_SCRIPTS_cdep = check_SCRIPTS_common = run-check-namespace +XFAIL_TESTS = + if REMOTE_ONLY perf: @@ -40,6 +42,7 @@ if ARCH_PPC64 if USE_ALTIVEC noinst_PROGRAMS_arch += ppc64-test-altivec endif #USE_ALTIVEC + check_PROGRAMS_arch += ppc64-test-plt else #!ARCH_PPC64 if ARCH_X86_64 check_PROGRAMS_arch += Gx64-test-dwarf-expressions Lx64-test-dwarf-expressions x64-unwind-badjmp-signal-frame @@ -48,14 +51,13 @@ endif #!ARCH_PPC64 endif #!ARCH_IA64 if ARCH_AARCH64 - check_PROGRAMS_arch += Garm64-test-sve-signal Larm64-test-sve-signal + check_PROGRAMS_arch += Garm64-test-sve-signal Larm64-test-sve-signal \ + aarch64-test-plt aarch64-test-frame-record endif - check_PROGRAMS_cdep += Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ + check_PROGRAMS_cdep += Gtest-bt Ltest-bt \ Gtest-init Ltest-init \ Gtest-concurrent Ltest-concurrent \ - Gtest-resume-sig Ltest-resume-sig \ - Gtest-resume-sig-rt Ltest-resume-sig-rt \ Gtest-trace Ltest-trace \ Ltest-mem-validate \ test-async-sig test-flush-cache test-init-remote \ @@ -69,10 +71,20 @@ if !ARCH_IA64 check_PROGRAMS_cdep += Ltest-init-local-signal endif +# Tests that exercise unw_resume, which is only unsupported on some targets +if ENABLE_UNW_RESUME_TESTS +check_PROGRAMS_cdep += Gtest-exc Ltest-exc \ + Gtest-resume-sig Ltest-resume-sig \ + Gtest-resume-sig-rt Ltest-resume-sig-rt +endif + if BUILD_PTRACE check_SCRIPTS_cdep += run-ptrace-mapper run-ptrace-misc check_PROGRAMS_cdep += test-ptrace noinst_PROGRAMS_cdep += mapper test-ptrace-misc +if ARCH_X86 + XFAIL_TESTS += test-ptrace +endif endif if BUILD_SETJMP @@ -82,6 +94,10 @@ endif if SUPPORT_CXX_EXCEPTIONS check_PROGRAMS_cdep += Ltest-cxx-exceptions endif +# Temporarily XFAIL this test for riscv64 until #519 is fixed +if ARCH_RISCV + XFAIL_TESTS += Ltest-cxx-exceptions +endif if OS_LINUX if BUILD_COREDUMP @@ -111,9 +127,10 @@ check_PROGRAMS = $(check_PROGRAMS_common) $(check_PROGRAMS_cdep) \ check_SCRIPTS = $(check_SCRIPTS_common) $(check_SCRIPTS_cdep) \ $(check_SCRIPTS_arch) - -TESTS = $(check_PROGRAMS) $(check_SCRIPTS) -XFAIL_TESTS = +TESTS = $(check_PROGRAMS) +if !CROSS_BUILD + TESTS += $(check_SCRIPTS) +endif if ARCH_IA64 check_PROGRAMS_cdep += Gtest-dyn1 Ltest-dyn1 @@ -143,12 +160,13 @@ endif # This is meant for multilib binaries, -m32. # ptrace gives EBADREG when testing, # but generally everything else works. -if NO_PTRACE_TEST - XFAIL_TESTS += run-ptrace-mapper test-ptrace Ltest-init-local-signal +if XFAIL_PTRACE_TEST + XFAIL_TESTS += run-ptrace-mapper endif noinst_PROGRAMS = $(noinst_PROGRAMS_common) $(noinst_PROGRAMS_cdep) \ $(noinst_PROGRAMS_arch) +noinst_HEADERS = ident.h Lia64_test_readonly_SOURCES = Lia64-test-readonly.c ia64-test-readonly-asm.S Gia64_test_readonly_SOURCES = Gia64-test-readonly.c ia64-test-readonly-asm.S @@ -163,6 +181,7 @@ 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 +ppc64_test_plt_SOURCES = ppc64-test-plt.c Gx64_test_dwarf_expressions_SOURCES = Gx64-test-dwarf-expressions.c \ @@ -172,8 +191,14 @@ Lx64_test_dwarf_expressions_SOURCES = Lx64-test-dwarf-expressions.c \ Garm64_test_sve_signal_SOURCES = Garm64-test-sve-signal.c Larm64_test_sve_signal_SOURCES = Larm64-test-sve-signal.c -Garm64_test_sve_signal_CFLAGS = -fno-inline -march=native -Larm64_test_sve_signal_CFLAGS = -fno-inline -march=native +aarch64_test_plt_SOURCES = aarch64-test-plt.c +aarch64_test_frame_record_SOURCES = aarch64-test-frame-record.c + +if COMPILER_SUPPORTS_MARCH_ARMV8_A_SVE + Garm64_test_sve_signal_CFLAGS = -fno-inline -march=armv8-a+sve + Larm64_test_sve_signal_CFLAGS = -fno-inline -march=armv8-a+sve +endif +XFAIL_TESTS += Garm64-test-sve-signal Larm64-test-sve-signal Gtest_init_SOURCES = Gtest-init.cxx Ltest_init_SOURCES = Ltest-init.cxx @@ -213,7 +238,7 @@ endif LIBUNWIND_setjmp = $(top_builddir)/src/libunwind-setjmp.la \ $(LIBUNWIND_ELF) $(LIBUNWIND) -test_async_sig_LDADD = $(LIBUNWIND_local) -lpthread +test_async_sig_LDADD = $(LIBUNWIND_local) $(PTHREADS_LIB) test_flush_cache_LDADD = $(LIBUNWIND_local) test_init_remote_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) test_mem_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @@ -222,16 +247,16 @@ test_ptrace_LDADD = $(LIBUNWIND_ptrace) $(LIBUNWIND) test_proc_info_LDADD = $(LIBUNWIND) test_static_link_LDADD = $(LIBUNWIND) test_strerror_LDADD = $(LIBUNWIND) -Lrs_race_LDADD = $(LIBUNWIND_local) -lpthread +Lrs_race_LDADD = $(LIBUNWIND_local) $(PTHREADS_LIB) Ltest_varargs_LDADD = $(LIBUNWIND_local) Ltest_init_local_signal_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_bt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gtest_concurrent_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -lpthread +Gtest_concurrent_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) $(PTHREADS_LIB) 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@ +Gtest_init_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) $(BACKTRACELIB) Gtest_resume_sig_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_resume_sig_rt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gperf_simple_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @@ -239,13 +264,13 @@ Gtest_trace_LDADD=$(LIBUNWIND) $(LIBUNWIND_local) Gperf_trace_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Ltest_bt_LDADD = $(LIBUNWIND_local) -Ltest_concurrent_LDADD = $(LIBUNWIND_local) -lpthread +Ltest_concurrent_LDADD = $(LIBUNWIND_local) $(PTHREADS_LIB) Ltest_cxx_exceptions_LDADD = $(LIBUNWIND_local) Ltest_dyn1_LDADD = $(LIBUNWIND_local) Ltest_exc_LDADD = $(LIBUNWIND_local) Ltest_init_LDADD = $(LIBUNWIND_local) -Ltest_nomalloc_LDADD = $(LIBUNWIND_local) @DLLIB@ -Ltest_nocalloc_LDADD = $(LIBUNWIND_local) @DLLIB@ -lpthread +Ltest_nomalloc_LDADD = $(LIBUNWIND_local) $(DLLIB) +Ltest_nocalloc_LDADD = $(LIBUNWIND_local) $(DLLIB) $(PTHREADS_LIB) Ltest_resume_sig_LDADD = $(LIBUNWIND_local) Ltest_resume_sig_rt_LDADD = $(LIBUNWIND_local) Lperf_simple_LDADD = $(LIBUNWIND_local) @@ -257,7 +282,7 @@ test_setjmp_LDADD = $(LIBUNWIND_setjmp) ia64_test_setjmp_LDADD = $(LIBUNWIND_setjmp) if BUILD_COREDUMP -test_coredump_unwind_LDADD = $(LIBUNWIND_coredump) $(LIBUNWIND) @BACKTRACELIB@ +test_coredump_unwind_LDADD = $(LIBUNWIND_coredump) $(LIBUNWIND) $(BACKTRACELIB) endif Gia64_test_nat_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @@ -271,9 +296,12 @@ Lia64_test_readonly_LDADD = $(LIBUNWIND_local) ia64_test_dyn1_LDADD = $(LIBUNWIND) ia64_test_sig_LDADD = $(LIBUNWIND) ppc64_test_altivec_LDADD = $(LIBUNWIND) +ppc64_test_plt_LDADD = $(LIBUNWIND) Gx64_test_dwarf_expressions_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Lx64_test_dwarf_expressions_LDADD = $(LIBUNWIND_local) Garm64_test_sve_signal_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Larm64_test_sve_signal_LDADD = $(LIBUNWIND_local) +aarch64_test_plt_LDADD = $(LIBUNWIND) +aarch64_test_frame_record_LDADD = $(LIBUNWIND) diff --git a/src/native/external/libunwind/tests/aarch64-test-frame-record.c b/src/native/external/libunwind/tests/aarch64-test-frame-record.c new file mode 100644 index 00000000000000..c2c2c2dde79ab5 --- /dev/null +++ b/src/native/external/libunwind/tests/aarch64-test-frame-record.c @@ -0,0 +1,390 @@ +/* + * Unittest AArch64 get_frame_state function by inspecting output at + * different points in example address spaces (from python2.7) + */ + +#include "dwarf.h" +#include "libunwind_i.h" + +int unw_is_signal_frame (unw_cursor_t *cursor) { return 0; } +int dwarf_step (struct dwarf_cursor *c) { return 0; } +#include "aarch64/Gstep.c" + +static int procedure_size; + +/* Mock access_mem implementation */ +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write != 0) + return -1; + + const size_t mem_size = procedure_size * sizeof(uint32_t); + const void *mem_start = arg; + const void *mem_end = (const char*) arg + mem_size; + const unw_word_t *paddr = (const unw_word_t*) addr; + + if ((void*) paddr < mem_start || (void*) paddr > mem_end) + { + return -1; + } + + *val = *paddr; + return 0; +} + +//! Stub implementation of get_proc_name - returns offset to start of procedure +static int +get_proc_name (unw_addr_space_t as, unw_word_t ip, char *buf, size_t len, unw_word_t *offp, + void *arg) +{ + *offp = ip - (unw_word_t) arg; + return 0; +} + +int +main () +{ + struct unw_addr_space mock_address_space; + mock_address_space.acc.access_mem = &access_mem; + mock_address_space.acc.get_proc_name = &get_proc_name; + + frame_state_t fs; + unw_cursor_t cursor; + struct cursor *c = (struct cursor *) &cursor; + c->dwarf.as = &mock_address_space; + + /* STP_MOV_start procedure */ + { + int IpStp = 0; + int IpMov = 1; + int IpLdp1 = 4; + int IpLdp2 = 7; + + // 0000000000418254 : + unsigned int instructions[9] = { + 0xa9be7bfd, // stp x29, x30, [sp,#-32]! <= FP+LR stored + 0x910003fd, // mov x29, sp <= FP updated + 0xa90153f3, // stp x19, x20, [sp,#16] + // some instructions skipped + 0xa94153f3, // ldp x19, x20, [sp,#16] + 0xa8c27bfd, // ldp x29, x30, [sp],#32 <= FP+LR retrieved + 0x17ffff33, // b 417f50 + // some instructions skipped + 0xa94153f3, // ldp x19, x20, [sp,#16] + 0xa8c27bfd, // ldp x29, x30, [sp],#32 <= FP+LR retrieved + 0x1400de12, // b 44fb08 + }; + procedure_size = 9; + + c->dwarf.as_arg = &instructions; + + /* IP is pointing to instruction that stores FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpStp); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction that updates the FP */ + c->dwarf.ip = (unw_word_t) (instructions+IpMov); + fs = get_frame_state(&cursor); + if (fs.loc != AT_SP_OFFSET || fs.offset != 0) return -1; + + /* IP is pointing to instruction after FP was updated */ + c->dwarf.ip = (unw_word_t) (instructions+IpMov+1); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to first instruction that retrieves FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp1); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction after first retrieval of FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp1+1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to second instruction that retrieves FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp2); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction after second retrieval of FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp2+1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + } + + /* STP_start_MOV_later procedure */ + { + int IpStp = 0; + int IpMov = 2; + int IpLdp = 5; + + // 00000000004181b4 : + unsigned int instructions[7] = { + 0xa9bd7bfd, // stp x29, x30, [sp,#-48]! <= FP+LR stored + 0xf0001740, // adrp x0, 703000 + 0x910003fd, // mov x29, sp <= FP updated + 0xf943cc00, // ldr x0, [x0,#1944] + // some instructions skipped + 0xf9400bf3, // ldr x19, [sp,#16] + 0xa8c37bfd, // ldp x29, x30, [sp],#48 <= FP+LR retrieved + 0xd65f03c0, // ret + }; + procedure_size = 7; + + c->dwarf.as_arg = &instructions; + + /* IP is pointing to instruction that stores FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpStp); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction after FP and LR are stored */ + c->dwarf.ip = (unw_word_t) (instructions+IpStp+1); + fs = get_frame_state(&cursor); + if (fs.loc != AT_SP_OFFSET || fs.offset != 0) return -1; + + /* IP is pointing to instruction that updates the FP */ + c->dwarf.ip = (unw_word_t) (instructions+IpMov); + fs = get_frame_state(&cursor); + if (fs.loc != AT_SP_OFFSET || fs.offset != 0) return -1; + + /* IP is pointing to instruction after FP was updated */ + c->dwarf.ip = (unw_word_t) (instructions+IpMov+1); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction that retrieves FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction after retrieval of FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp+1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + } + + /* STP_MOV_later procedure */ + { + int IpStp = 3; + int IpMov = 4; + int IpLdp = 7; + + // 0000000000418370 : + uint32_t instructions[9] = { + 0xb941fc01, // ldr w1, [x0,#508] + // some instructions skipped + 0xd65f03c0, // ret + // some instructions skipped + 0x34ffffa4, // cbz w4, 41838c + 0xa9be7bfd, // stp x29, x30, [sp,#-32] <= FP+LR stored + 0x910003fd, // mov x29, sp <= FP updated + 0xf9000bf3, // str x19, [sp,#16] + 0xf9400bf3, // ldr x19, [sp,#16] + 0xa8c27bfd, // ldp x29, x30, [sp],#32 <= FP+LR retrieved + 0xd65f03c0, // ret + }; + procedure_size = 9; + + c->dwarf.as_arg = &instructions; + + /* IP is pointing to start of procedure */ + c->dwarf.ip = (unw_word_t) (instructions); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction that stores FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpStp); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction that updates the FP */ + c->dwarf.ip = (unw_word_t) (instructions+IpMov); + fs = get_frame_state(&cursor); + if (fs.loc != AT_SP_OFFSET || fs.offset != 0) return -1; + + /* IP is pointing to instruction after FP was updated */ + c->dwarf.ip = (unw_word_t) (instructions+IpMov+1); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction that retrieves FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction after FP and LR are retrieved */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp+1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + } + + /* STP_POS_OFFSET procedure */ + { + int IpStp = 3; + int IpAdd = 4; + int IpLdp = 7; + + // 000000000046d1d8 : + unsigned int instructions[9] = { + 0xd10083ff, // sub sp, sp, #0x20 + 0xd2800007, // mov x7, #0x0 // #0 + // some instructions skipped + 0xd2800003, // mov x3, #0x0 // #0 + 0xa9017bfd, // stp x29, x30, [sp,#16] + 0x910043fd, // add x29, sp, #0x10 + 0xb90003ff, // str wzr, [sp] + // some instructions skipped + 0x910003bf, // mov sp, x29 + 0xa8c17bfd, // ldp x29, x30, [sp],#16 + 0xd65f03c0, // ret + }; + procedure_size = 9; + + c->dwarf.as_arg = &instructions; + + /* IP is pointing to start of procedure */ + c->dwarf.ip = (unw_word_t) (instructions); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction that stores FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpStp); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction that updates the FP */ + c->dwarf.ip = (unw_word_t) (instructions+IpAdd); + fs = get_frame_state(&cursor); + if (fs.loc != AT_SP_OFFSET || fs.offset != 16) return -1; + + /* IP is pointing to instruction after FP was updated */ + c->dwarf.ip = (unw_word_t) (instructions+IpAdd+1); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction that retrieves FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction after FP and LR are retrieved */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp+1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + } + + /* STP_NEG_OFFSET procedure */ + { + int IpStp = 3; + int IpAdd = 4; + int IpLdp = 7; + + // Artificial example based on PyEval_EvalCode with negative offset STP + unsigned int instructions[9] = { + 0xd10083ff, // sub sp, sp, #0x20 + 0xd2800007, // mov x7, #0x0 // #0 + // some instructions skipped + 0xd2800003, // mov x3, #0x0 // #0 + 0xa9217bfd, // stp x29, x30, [sp,#-16] + 0x910043fd, // add x29, sp, #0x10 + 0xb90003ff, // str wzr, [sp] + // some instructions skipped + 0x910003bf, // mov sp, x29 + 0xa8c17bfd, // ldp x29, x30, [sp],#16 + 0xd65f03c0, // ret + }; + procedure_size = 9; + + c->dwarf.as_arg = &instructions; + + /* IP is pointing to start of procedure */ + c->dwarf.ip = (unw_word_t) (instructions); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction that stores FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpStp); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to instruction that updates the FP */ + c->dwarf.ip = (unw_word_t) (instructions+IpAdd); + fs = get_frame_state(&cursor); + if (fs.loc != AT_SP_OFFSET || fs.offset != -16) return -1; + + /* IP is pointing to instruction after FP was updated */ + c->dwarf.ip = (unw_word_t) (instructions+IpAdd+1); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction that retrieves FP and LR */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp); + fs = get_frame_state(&cursor); + if (fs.loc != AT_FP || fs.offset != 0) return -1; + + /* IP is pointing to instruction after FP and LR are retrieved */ + c->dwarf.ip = (unw_word_t) (instructions+IpLdp+1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + } + + /* PLT_entry procedure */ + { + // 0000000000417760 : + unsigned int instructions[4] = { + 0x900013d0, // adrp x16, 68f000 + 0xf942a211, // ldr x17, [x16,#1344] + 0x91150210, // add x16, x16, #0x540 + 0xd61f0220, // br x17 + }; + procedure_size = 4; + + c->dwarf.as_arg = &instructions; + + /* IP is pointing to start of procedure */ + c->dwarf.ip = (unw_word_t) (instructions); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to end of procedure */ + c->dwarf.ip = (unw_word_t) (instructions+procedure_size-1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + } + + /* no_STP_MOV procedure */ + { + // 000000000041ddf0 : + uint32_t instructions[9] = { + 0xb0001641, // adrp x1, 6e6000 + 0x90000d00, // adrp x0, 5bd000 <_PyImport_StandardFiletab+0x1468> + 0x913d4023, // add x3, x1, #0xf50 + 0x911b4000, // add x0, x0, #0x6d0 + 0x91330062, // add x2, x3, #0xcc0 + 0x91374061, // add x1, x3, #0xdd0 + 0x52807ea4, // mov w4, #0x3f5 + 0xd2800003, // mov x3, #0x0 + 0x1400bccc, // b 44d140 + }; + procedure_size = 9; + + c->dwarf.as_arg = &instructions; + + /* IP is pointing to start of procedure */ + c->dwarf.ip = (unw_word_t) (instructions); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + + /* IP is pointing to end of procedure */ + c->dwarf.ip = (unw_word_t) (instructions+procedure_size-1); + fs = get_frame_state(&cursor); + if (fs.loc != NONE || fs.offset != 0) return -1; + } + + return 0; +} diff --git a/src/native/external/libunwind/tests/aarch64-test-plt.c b/src/native/external/libunwind/tests/aarch64-test-plt.c new file mode 100644 index 00000000000000..943b155bf22fc5 --- /dev/null +++ b/src/native/external/libunwind/tests/aarch64-test-plt.c @@ -0,0 +1,175 @@ +/* + * Unittest AArch64 is_plt_entry function by inspecting output at + * different points in a mock PLT address space. + */ + +#include "dwarf.h" +#include "libunwind_i.h" + +int unw_is_signal_frame (unw_cursor_t *cursor) { return 0; } +int dwarf_step (struct dwarf_cursor *c) { return 0; } +#include "aarch64/Gstep.c" + +enum +{ + ip_guard0, + ip_adrp, + ip_ldr, + ip_add, + ip_br, + ip_guard1, + + ip_program_end +}; + +/* Mock access_mem implementation */ +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write != 0) + return -1; + + const size_t mem_size = ip_program_end * sizeof(uint32_t); + const void *mem_start = arg; + const void *mem_end = (const char*) arg + mem_size; + const unw_word_t *paddr = (const unw_word_t*) addr; + + if ((void*) paddr < mem_start || (void*) paddr > mem_end) + { + return -1; + } + + *val = *paddr; + return 0; +} + +int +main () +{ + if (target_is_big_endian()) + return 77; + + const uint32_t plt_instructions[ip_program_end] = { + 0xDEADBEEF, + 0xf0000990, // adrp x16, 540000 + 0xf9400a11, // ldr x17, [x16,#16] + 0x91004210, // add x16, x16, #0x10 + 0xd61f0220, // br x17 + 0xDEADBEEF, + }; + + uint32_t test_instructions[ip_program_end]; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + struct unw_addr_space mock_address_space; + mock_address_space.big_endian = 0; + mock_address_space.acc.access_mem = &access_mem; + + struct dwarf_cursor c; + c.as = &mock_address_space; + c.as_arg = &test_instructions; + + /* ip at adrp */ + c.ip = (unw_word_t) (test_instructions + ip_adrp); + if (is_plt_entry(&c) == 0) return -1; + + /* adrp uses different offset */ + test_instructions[ip_adrp] = 0x90272990; + if (is_plt_entry(&c) == 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ldr uses different offset */ + test_instructions[ip_ldr] = 0xf948be11; + if (is_plt_entry(&c) == 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* add uses different offset */ + test_instructions[ip_add] = 0x91726210; + if (is_plt_entry(&c) == 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_ldr is not a ldr instruction */ + test_instructions[ip_ldr] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_add is not an add instruction */ + test_instructions[ip_add] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_br is not a br instruction */ + test_instructions[ip_br] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at ldr */ + c.ip = (unw_word_t) (test_instructions + ip_ldr); + if (is_plt_entry(&c) == 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_adrp is not an adrp instruction */ + test_instructions[ip_adrp] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_add is not an add instruction */ + test_instructions[ip_add] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_br is not a br instruction */ + test_instructions[ip_br] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at add */ + c.ip = (unw_word_t) (test_instructions + ip_add); + if (is_plt_entry(&c) == 0) return -1; + + /* ip_adrp is not an adrp instruction */ + test_instructions[ip_adrp] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_ldr is not a ldr instruction */ + test_instructions[ip_ldr] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_br is not a br instruction */ + test_instructions[ip_br] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at br */ + c.ip = (unw_word_t) (test_instructions + ip_br); + if (is_plt_entry(&c) == 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_adrp is not an adrp instruction */ + test_instructions[ip_adrp] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_ldr is not a ldr instruction */ + test_instructions[ip_ldr] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_add is not an add instruction */ + test_instructions[ip_add] = 0xf154f00d; + if (is_plt_entry(&c) != 0) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at non-PLT instruction */ + c.ip = (unw_word_t) (test_instructions + ip_guard0); + if (is_plt_entry(&c)) return -1; + + /* ip at another non-PLT instruction */ + c.ip = (unw_word_t) (test_instructions + ip_guard1); + if (is_plt_entry(&c)) return -1; + + return 0; +} diff --git a/src/native/external/libunwind/tests/check-namespace.sh.in b/src/native/external/libunwind/tests/check-namespace.sh.in index a1b28a7ba37b04..c2c1bf1009e790 100644 --- a/src/native/external/libunwind/tests/check-namespace.sh.in +++ b/src/native/external/libunwind/tests/check-namespace.sh.in @@ -72,31 +72,36 @@ filter_misc () { # Ignore symbols generated by the ARM Linux default linker script. # For details see the binutils sources (src/ld/emulparams/armelf_linux.sh). - if [ ${plat} = "arm" ]; then - ignore __bss_start__ - ignore __bss_end__ - ignore __end__ - ignore _bss_end__ - fi - - if [ ${plat} = "mips" ]; then - ignore _fbss - ignore _fdata - ignore _ftext - ignore _gp - fi - - if [ ${plat} = "loongarch64" ]; then - ignore _fbss - ignore _fdata - ignore _ftext - ignore _gp - fi + case "$plat}" in + arm*|aarch64*) + ignore __bss_start__ + ignore __bss_end__ + ignore __end__ + ignore _bss_end__ + ;; + mips*) + ignore _fbss + ignore _fdata + ignore _ftext + ignore _gp + ;; + loongarch64) + ignore _fbss + ignore _fdata + ignore _ftext + ignore _gp + ;; + esac - if [ ${os} = "solaris2.11" ]; then - ignore _PROCEDURE_LINKAGE_TABLE_ - ignore _etext - fi + case "${os}" in + solaris2.11) + ignore _PROCEDURE_LINKAGE_TABLE_ + ignore _etext + ;; + nto*) + ignore _btext + ;; + esac } check_local_unw_abi () { @@ -110,6 +115,8 @@ check_local_unw_abi () { match _UL${plat}_get_proc_info_in_range match _UL${plat}_get_proc_name match _UL${plat}_get_proc_name_by_ip + match _UL${plat}_get_elf_filename + match _UL${plat}_get_elf_filename_by_ip match _UL${plat}_get_reg match _UL${plat}_get_save_loc match _UL${plat}_init_local @@ -118,6 +125,7 @@ check_local_unw_abi () { match _UL${plat}_is_signal_frame match _UL${plat}_local_addr_space match _UL${plat}_resume + match _UL${plat}_set_iterate_phdr_function match _UL${plat}_set_caching_policy match _UL${plat}_set_cache_size match _UL${plat}_set_reg @@ -177,14 +185,6 @@ check_local_unw_abi () { match _UL${plat}_dwarf_search_unwind_table match _UL${plat}_dwarf_find_unwind_table ;; - tilegx) - match _U${plat}_getcontext - match _U${plat}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - match _UL${plat}_local_addr_space_init - match ${plat}_lock - ;; s390x) match _U${plat}_getcontext match _U${plat}_is_fpreg @@ -231,6 +231,8 @@ check_generic_unw_abi () { match _U${plat}_get_proc_info_in_range match _U${plat}_get_proc_name match _U${plat}_get_proc_name_by_ip + match _U${plat}_get_elf_filename + match _U${plat}_get_elf_filename_by_ip match _U${plat}_get_reg match _U${plat}_get_save_loc match _U${plat}_init_local @@ -240,6 +242,7 @@ check_generic_unw_abi () { match _U${plat}_local_addr_space match _U${plat}_regname match _U${plat}_resume + match _U${plat}_set_iterate_phdr_function match _U${plat}_set_caching_policy match _U${plat}_set_cache_size match _U${plat}_set_fpreg @@ -248,6 +251,13 @@ check_generic_unw_abi () { match _U${plat}_strerror case ${plat} in + aarch64) + 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 + ;; arm) match _U${plat}_is_fpreg match _U${plat}_get_elf_image @@ -297,15 +307,6 @@ check_generic_unw_abi () { match _U${plat}_dwarf_search_unwind_table match _U${plat}_dwarf_find_unwind_table ;; - tilegx) - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _U${plat}_local_addr_space_init - match ${plat}_lock - ;; s390x) match _U${plat}_is_fpreg match _U${plat}_get_elf_image diff --git a/src/native/external/libunwind/tests/flush-cache.S b/src/native/external/libunwind/tests/flush-cache.S index 3ee47269e18264..6e3a82b97ab7fa 100644 --- a/src/native/external/libunwind/tests/flush-cache.S +++ b/src/native/external/libunwind/tests/flush-cache.S @@ -77,22 +77,6 @@ flush_cache: .globl flush_cache flush_cache: bx lr -#elif defined(__tilegx__) - .text - .globl flush_cache -flush_cache: - - andi r0, r0, -64 -1: { - flush r0 ; - addi r0, r0, 64 - } - { - bgtz r1, 1b ; - addi r1, r1, -64 - } - jrp lr -#else # error Need flush_cache code for this architecture. #endif diff --git a/src/native/external/libunwind/tests/ident.c b/src/native/external/libunwind/tests/ident.c index 9024e292f5a542..082b40547f5cba 100644 --- a/src/native/external/libunwind/tests/ident.c +++ b/src/native/external/libunwind/tests/ident.c @@ -1,3 +1,27 @@ +/* libunwind - a platform-independent unwind library + * + * 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 "ident.h" + long f (long val) { diff --git a/src/native/external/libunwind/tests/ident.h b/src/native/external/libunwind/tests/ident.h new file mode 100644 index 00000000000000..fea6b041516c82 --- /dev/null +++ b/src/native/external/libunwind/tests/ident.h @@ -0,0 +1,28 @@ +/* libunwind - a platform-independent unwind library + * + * 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_TESTS_IDENT_H +#define LIBUNWIND_TESTS_IDENT_H + +extern long f (long val); + +#endif /* LIBUNWIND_TESTS_IDENT_H */ diff --git a/src/native/external/libunwind/tests/mapper.c b/src/native/external/libunwind/tests/mapper.c index b47ae780f8ede8..fcfb080792602b 100644 --- a/src/native/external/libunwind/tests/mapper.c +++ b/src/native/external/libunwind/tests/mapper.c @@ -43,6 +43,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # define MAP_NORESERVE 0 #endif +void __attribute__((noinline)) push_some_stacks(int n) +{ + if (n >= 1) + { + push_some_stacks(n - 1); + push_some_stacks(n - 1); + } +} + int main (void) { @@ -71,7 +80,7 @@ main (void) printf ("Turning on single-stepping...\n"); kill (getpid (), SIGUSR1); /* tell test-ptrace to start single-stepping */ - printf ("Va bene?\n"); + push_some_stacks (4); kill (getpid (), SIGUSR2); /* tell test-ptrace to stop single-stepping */ printf ("Turned single-stepping off...\n"); return 0; diff --git a/src/native/external/libunwind/tests/ppc64-test-plt.c b/src/native/external/libunwind/tests/ppc64-test-plt.c new file mode 100644 index 00000000000000..a8d4f3c0aa8fae --- /dev/null +++ b/src/native/external/libunwind/tests/ppc64-test-plt.c @@ -0,0 +1,164 @@ +/* + * Unittest PPC64 is_plt_entry function by inspecting output at + * different points in a mock PLT address space. + */ + +#include "dwarf.h" +#include "libunwind_i.h" + +#undef unw_get_accessors_int +unw_accessors_t *unw_get_accessors_int (unw_addr_space_t) { return NULL; } +int dwarf_step (struct dwarf_cursor*) { return 0; } +#include "ppc64/Gstep.c" + +enum +{ + ip_guard0, + ip_std, + ip_ld, + ip_mtctr, + ip_bctr, + ip_guard1, + + ip_program_end +}; + +/* Mock access_mem implementation */ +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write != 0) + return -1; + + const size_t mem_size = ip_program_end * sizeof(uint32_t); + const void *mem_start = arg; + const void *mem_end = (const char*) arg + mem_size; + const unw_word_t *paddr = (const unw_word_t*) addr; + + if ((void*) paddr < mem_start || (void*) paddr > mem_end) + { + return -1; + } + + *val = *paddr; + return 0; +} + +int +main () +{ + if (target_is_big_endian()) + return 77; + + const uint32_t plt_instructions[ip_program_end] = + { + 0xdeadbeef, + 0xf8410018, // std r2,24(r1) + 0xe9828730, // ld r12,-30928(r2) + 0x7d8903a6, // mtctr r12 + 0x4e800420, // bctr + 0xdeadbeef, + }; + uint32_t test_instructions[ip_program_end]; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + struct unw_addr_space mock_address_space; + mock_address_space.big_endian = 0; + mock_address_space.acc.access_mem = &access_mem; + + struct dwarf_cursor c; + c.as = &mock_address_space; + c.as_arg = &test_instructions; + + /* ip at std r2,24(r1) */ + c.ip = (unw_word_t) (test_instructions + ip_std); + if (!is_plt_entry(&c)) return -1; + + /* ld uses a different offset */ + test_instructions[ip_ld] = 0xe9820000; + if (!is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_ld is not a ld instruction */ + test_instructions[ip_ld] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_mtctr is not a mtctr instruction */ + test_instructions[ip_mtctr] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_bctr is not a bctr instruction */ + test_instructions[ip_bctr] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at ld r12,-30928(r2) */ + c.ip = (unw_word_t) (test_instructions + ip_ld); + if (!is_plt_entry(&c)) return -1; + + /* ip_std is not a std instruction */ + test_instructions[ip_std] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_mtctr is not a mtctr instruction */ + test_instructions[ip_mtctr] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_bctr is not a bctr instruction */ + test_instructions[ip_bctr] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at mtctr r12 */ + c.ip = (unw_word_t) (test_instructions + ip_mtctr); + if (!is_plt_entry(&c)) return -1; + + /* ip_std is not a std instruction */ + test_instructions[ip_std] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_ld is not a ld instruction */ + test_instructions[ip_ld] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_bctr is not a bctr instruction */ + test_instructions[ip_bctr] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at bctr */ + c.ip = (unw_word_t) (test_instructions + ip_bctr); + if (!is_plt_entry(&c)) return -1; + + /* ip_std is not a std instruction */ + test_instructions[ip_std] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_ld is not a ld instruction */ + test_instructions[ip_ld] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip_mtctr is not a mtctr instruction */ + test_instructions[ip_mtctr] = 0xf154f00d; + if (is_plt_entry(&c)) return -1; + memcpy(test_instructions, plt_instructions, sizeof(test_instructions)); + + /* ip at non-PLT instruction */ + c.ip = (unw_word_t) (test_instructions + ip_guard0); + if (is_plt_entry(&c)) return -1; + + /* ip at another non-PLT instruction */ + c.ip = (unw_word_t) (test_instructions + ip_guard1); + if (is_plt_entry(&c)) return -1; + + return 0; +} diff --git a/src/native/external/libunwind/tests/run-coredump-unwind b/src/native/external/libunwind/tests/run-coredump-unwind index 690362bdae4667..c5dc51d60ca5d3 100755 --- a/src/native/external/libunwind/tests/run-coredump-unwind +++ b/src/native/external/libunwind/tests/run-coredump-unwind @@ -20,7 +20,7 @@ add_minidebug() nm "$debuginfo" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > "$funcsyms" # Keep all the function symbols not already in the dynamic symbol table comm -13 "$dynsyms" "$funcsyms" > "$keep_symbols" - # Copy the full debuginfo, keeping only a minumal set of symbols and removing some unnecessary sections + # Copy the full debuginfo, keeping only a minimal set of symbols and removing some unnecessary sections objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols="$keep_symbols" "$debuginfo" "$mini_debuginfo" &> /dev/null wait #Inject the compressed data into the .gnu_debugdata section of the original binary diff --git a/src/native/external/libunwind/tests/test-async-sig.c b/src/native/external/libunwind/tests/test-async-sig.c index 2ce8b4bb711d03..d025c915106573 100644 --- a/src/native/external/libunwind/tests/test-async-sig.c +++ b/src/native/external/libunwind/tests/test-async-sig.c @@ -60,8 +60,8 @@ int sigcount; int recurcount; #endif -#define panic(args...) \ - { ++nerrors; fprintf (stderr, args); return; } +#define panic(...) \ + { ++nerrors; fprintf (stderr, __VA_ARGS__); return; } static void do_backtrace (int may_print, int get_proc_name) @@ -157,7 +157,7 @@ sighandler (int signal) printf ("SUCCESS.\n"); exit (0); } - setitimer (ITIMER_VIRTUAL, &interval, NULL); + setitimer (ITIMER_REAL, &interval, NULL); } int @@ -174,13 +174,13 @@ main (int argc, char **argv UNUSED) memset (&act, 0, sizeof (act)); act.sa_handler = sighandler; act.sa_flags = SA_SIGINFO; - sigaction (SIGVTALRM, &act, NULL); + sigaction (SIGALRM, &act, NULL); - setitimer (ITIMER_VIRTUAL, &interval, NULL); + setitimer (ITIMER_REAL, &interval, NULL); while (1) { - if (0 && verbose) + if (verbose) printf ("%s: starting backtrace\n", __FUNCTION__); do_backtrace (0, (i++ % 100) == 0); if (nerrors > nerrors_max) diff --git a/src/native/external/libunwind/tests/test-coredump-unwind.c b/src/native/external/libunwind/tests/test-coredump-unwind.c index 5c29600492d18e..6f0672a75a0882 100644 --- a/src/native/external/libunwind/tests/test-coredump-unwind.c +++ b/src/native/external/libunwind/tests/test-coredump-unwind.c @@ -326,16 +326,23 @@ main(int argc UNUSED, char **argv) if (ret < 0) error_msg_and_die("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); - if (!testcase) { - char proc_name[128]; - unw_word_t off; - unw_get_proc_name(&c, proc_name, sizeof(proc_name), &off); - - printf("\tip=0x%08lx proc=%08lx-%08lx handler=0x%08lx lsda=0x%08lx %s\n", - (long) ip, - (long) pi.start_ip, (long) pi.end_ip, - (long) pi.handler, (long) pi.lsda, proc_name); - } + if (!testcase) + { + char proc_name[128]; + unw_word_t off; + unw_get_proc_name(&c, proc_name, sizeof(proc_name), &off); + + printf("\tip=0x%08lx proc=%08lx-%08lx handler=0x%08lx lsda=0x%08lx %s\n", + (long) ip, + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda, proc_name); + + char filename[PATH_MAX]; + unw_word_t file_offset; + ret = unw_get_elf_filename (&c, filename, sizeof (filename), &file_offset); + if (ret == UNW_ESUCCESS) + printf ("\t[%s+0x%lx]\n", filename, (long) file_offset); + } if (testcase && test_cur < TEST_FRAMES) { diff --git a/src/native/external/libunwind/tests/test-init-remote.c b/src/native/external/libunwind/tests/test-init-remote.c index 66f2d6a1e0c2bf..c5f0df40e7e9dd 100644 --- a/src/native/external/libunwind/tests/test-init-remote.c +++ b/src/native/external/libunwind/tests/test-init-remote.c @@ -39,8 +39,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } +#define panic(...) \ + { fprintf (stderr, __VA_ARGS__); exit (-1); } int verbose; @@ -63,14 +63,19 @@ do_backtrace (void) unw_get_reg (&cursor, UNW_REG_SP, &sp); buf[0] = '\0'; if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) - { - if (off) - snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); - else - snprintf (buf, sizeof (buf), "<%s>", name); - } + { + if (off) + snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); + else + snprintf (buf, sizeof (buf), "<%s>", name); + } if (verbose) - printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); + printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); + + char filename[128]; + unw_word_t file_offset; + if (unw_get_elf_filename (&cursor,filename, sizeof (filename), &file_offset) == UNW_ESUCCESS) + printf (" [%s+0x%lx]\n", filename, (long) file_offset); ret = unw_step (&cursor); if (ret < 0) diff --git a/src/native/external/libunwind/tests/test-mem.c b/src/native/external/libunwind/tests/test-mem.c index 52c977488ac324..74089115a352b1 100644 --- a/src/native/external/libunwind/tests/test-mem.c +++ b/src/native/external/libunwind/tests/test-mem.c @@ -35,8 +35,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } +#define panic(...) \ + { fprintf (stderr, __VA_ARGS__); exit (-1); } int verbose; @@ -80,23 +80,25 @@ consume_some_stack_space (void) memset (&cursor, 0, sizeof (cursor)); memset (&uc, 0, sizeof (uc)); - return sprintf (string, "hello %p %p\n", &cursor, &uc); + return sprintf (string, "hello %p %p\n", (void *)&cursor, (void *)&uc); } int main (int argc, char **argv UNUSED) { - struct rlimit rlim; + struct rlimit rlim UNUSED; verbose = argc > 1; if (consume_some_stack_space () > 9999) exit (-1); /* can't happen, but don't let the compiler know... */ +#if !defined(__QNX__) rlim.rlim_cur = 0; rlim.rlim_max = RLIM_INFINITY; setrlimit (RLIMIT_DATA, &rlim); setrlimit (RLIMIT_AS, &rlim); +#endif /* !defined(__QNX__) */ do_backtrace (); return 0; diff --git a/src/native/external/libunwind/tests/test-proc-info.c b/src/native/external/libunwind/tests/test-proc-info.c index c4145bc374ec38..408d80e25fa92c 100644 --- a/src/native/external/libunwind/tests/test-proc-info.c +++ b/src/native/external/libunwind/tests/test-proc-info.c @@ -40,8 +40,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ int errors; -#define panic(args...) \ - { ++errors; fprintf (stderr, args); return -1; } +#define panic(...) \ + { ++errors; fprintf (stderr, __VA_ARGS__); return -1; } static int find_proc_info (unw_addr_space_t as UNUSED, diff --git a/src/native/external/libunwind/tests/test-ptrace-misc.c b/src/native/external/libunwind/tests/test-ptrace-misc.c index 374059dc44a972..cbb9557ee5c431 100644 --- a/src/native/external/libunwind/tests/test-ptrace-misc.c +++ b/src/native/external/libunwind/tests/test-ptrace-misc.c @@ -33,6 +33,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#include "ident.h" + pid_t self; int global[64]; @@ -68,7 +70,6 @@ func (int arg) int bar (int v) { - extern long f (long); int arr[1] = { v }; uintptr_t r; diff --git a/src/native/external/libunwind/tests/test-ptrace.c b/src/native/external/libunwind/tests/test-ptrace.c index 846bcd80079b40..bfd45bf9aafb98 100644 --- a/src/native/external/libunwind/tests/test-ptrace.c +++ b/src/native/external/libunwind/tests/test-ptrace.c @@ -55,6 +55,7 @@ static const int nerrors_max = 100; int nerrors; int verbose; int print_names = 1; +int print_elf_filename; enum { @@ -64,8 +65,8 @@ enum } trace_mode = SYSCALL; -#define panic(args...) \ - do { fprintf (stderr, args); ++nerrors; } while (0) +#define panic(...) \ + do { fprintf (stderr, __VA_ARGS__); ++nerrors; } while (0) static unw_addr_space_t as; static struct UPT_info *ui; @@ -111,7 +112,7 @@ do_backtrace (void) printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); } - if ((ret = unw_get_proc_info (&c, &pi)) < 0) + if ((ret = unw_get_proc_info (&c, &pi)) < 0 && ret != -UNW_ENOINFO) /* It's possible unw_get_proc_info don't return information */ panic ("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); else if (verbose) printf ("\tproc=%016lx-%016lx\n\thandler=%lx lsda=%lx", @@ -131,6 +132,14 @@ do_backtrace (void) if (verbose) printf ("\n"); + if (print_elf_filename) + { + if ((ret = unw_get_elf_filename(&c, buf, sizeof (buf), &off)) != UNW_ESUCCESS) + panic ("unw_get_elf_filename(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); + else if (verbose) + printf ("\t[%s+0x%lx]\n", buf, (long) off); + } + ret = unw_step (&c); if (ret < 0) { @@ -178,8 +187,11 @@ main (int argc, char **argv) if (argc == 1) { +#ifdef HAVE_EXECVPE static char *args[] = { "self", "ls", "/", NULL }; - +#else + static char *args[] = { "self", "/bin/ls", "/", NULL }; +#endif /* automated test case */ argv = args; @@ -207,6 +219,9 @@ main (int argc, char **argv) else if (strcmp (argv[optind], "-n") == 0) /* Don't look-up and print symbol names. */ ++optind, print_names = 0; + else if (strcmp (argv[optind], "-f") == 0) + /* Print elf filenames. */ + ++optind, print_elf_filename = 1; else fprintf(stderr, "unrecognized option: %s\n", argv[optind++]); if (optind >= argc) @@ -222,21 +237,29 @@ main (int argc, char **argv) dup2 (open ("/dev/null", O_WRONLY), 1); #if HAVE_DECL_PTRACE_TRACEME - ptrace (PTRACE_TRACEME, 0, 0, 0); + long stat = ptrace (PTRACE_TRACEME, 0, 0, 0); #elif HAVE_DECL_PT_TRACE_ME - ptrace (PT_TRACE_ME, 0, 0, 0); + int stat = ptrace (PT_TRACE_ME, 0, 0, 0); #else #error Trace me #endif + if (stat == -1) + { + if (verbose) + { + fprintf(stderr, "ptrace() returned %ld errno=%d (%s)\n", (long)stat, errno, strerror(errno)); + } + _exit(77); + } if ((argc > 1) && (optind == argc)) { fprintf(stderr, "Need to specify a command line for the child\n"); exit (-1); } -#ifdef __FreeBSD__ - execve (argv[optind], argv + optind, environ); -#else +#ifdef HAVE_EXECVPE execvpe (argv[optind], argv + optind, environ); +#else + execve (argv[optind], argv + optind, environ); #endif _exit (-1); } @@ -262,6 +285,8 @@ main (int argc, char **argv) { if (WEXITSTATUS (status) != 0) panic ("child's exit status %d\n", WEXITSTATUS (status)); + if (WEXITSTATUS (status) == 77) + _exit(77); break; } else if (WIFSIGNALED (status)) @@ -333,10 +358,10 @@ main (int argc, char **argv) if (!state) do_backtrace (); state ^= 1; -#if HAVE_DECL_PTRACE_SYSCALL - ptrace (PTRACE_SYSCALL, target_pid, 0, pending_sig); -#elif HAVE_DECL_PT_SYSCALL +#if HAVE_DECL_PT_SYSCALL ptrace (PT_SYSCALL, target_pid, (caddr_t)1, pending_sig); +#elif HAVE_DECL_PTRACE_SYSCALL + ptrace (PTRACE_SYSCALL, target_pid, 0, pending_sig); #else #error Syscall me #endif diff --git a/src/native/external/libunwind/tests/test-reg-state.c b/src/native/external/libunwind/tests/test-reg-state.c index ac713ea68ad721..4406acb955a2f7 100644 --- a/src/native/external/libunwind/tests/test-reg-state.c +++ b/src/native/external/libunwind/tests/test-reg-state.c @@ -36,8 +36,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } +#define panic(...) \ + { fprintf (stderr, __VA_ARGS__); exit (-1); } int verbose; @@ -111,7 +111,7 @@ consume_some_stack_space (void) memset (&cursor, 0, sizeof (cursor)); memset (&uc, 0, sizeof (uc)); - return sprintf (string, "hello %p %p\n", &cursor, &uc); + return sprintf (string, "hello %p %p\n", (void *)&cursor, (void *)&uc); } int @@ -124,9 +124,11 @@ main (int argc, char **argv UNUSED) if (consume_some_stack_space () > 9999) exit (-1); /* can't happen, but don't let the compiler know... */ +#if !defined(__QNX__) rlim.rlim_cur = 0; rlim.rlim_max = RLIM_INFINITY; setrlimit (RLIMIT_DATA, &rlim); +#endif /* !defined(__QNX__) */ do_backtrace (); return 0; diff --git a/src/native/external/libunwind/tests/test-setjmp.c b/src/native/external/libunwind/tests/test-setjmp.c index 59d1c5a083b309..d2468ff05f6c87 100644 --- a/src/native/external/libunwind/tests/test-setjmp.c +++ b/src/native/external/libunwind/tests/test-setjmp.c @@ -1,6 +1,6 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Contributed by David Mosberger-Tang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -39,7 +39,7 @@ static jmp_buf jbuf; static sigjmp_buf sigjbuf; static sigset_t sigset4; -void +NORETURN void raise_longjmp (jmp_buf jbuf, int i, int n) { while (i < n) @@ -58,32 +58,32 @@ test_setjmp (void) for (i = 0; i < 10; ++i) { if ((ret = setjmp (jbuf))) - { - if (verbose) - printf ("%s: secondary setjmp () return, ret=%d\n", - __FUNCTION__, ret); - if (ret != i + 1) - { - fprintf (stderr, "%s: setjmp() returned %d, expected %d\n", - __FUNCTION__, ret, i + 1); - ++nerrors; - } - continue; - } + { + if (verbose) + printf ("%s: secondary setjmp () return, ret=%d\n", + __FUNCTION__, ret); + if (ret != i + 1) + { + fprintf (stderr, "%s: setjmp() returned %d, expected %d\n", + __FUNCTION__, ret, i + 1); + ++nerrors; + } + continue; + } if (verbose) - printf ("%s.%d: done with setjmp(); calling children\n", - __FUNCTION__, i + 1); + printf ("%s.%d: done with setjmp(); calling children\n", + __FUNCTION__, i + 1); raise_longjmp (jbuf, 0, i + 1); fprintf (stderr, "%s: raise_longjmp() returned unexpectedly\n", - __FUNCTION__); + __FUNCTION__); ++nerrors; } } -void +NORETURN void raise_siglongjmp (sigjmp_buf jbuf, int i, int n) { while (i < n) @@ -102,26 +102,26 @@ test_sigsetjmp (void) for (i = 0; i < 10; ++i) { if ((ret = sigsetjmp (jbuf, 1))) - { - if (verbose) - printf ("%s: secondary sigsetjmp () return, ret=%d\n", - __FUNCTION__, ret); - if (ret != i + 1) - { - fprintf (stderr, "%s: sigsetjmp() returned %d, expected %d\n", - __FUNCTION__, ret, i + 1); - ++nerrors; - } - continue; - } + { + if (verbose) + printf ("%s: secondary sigsetjmp () return, ret=%d\n", + __FUNCTION__, ret); + if (ret != i + 1) + { + fprintf (stderr, "%s: sigsetjmp() returned %d, expected %d\n", + __FUNCTION__, ret, i + 1); + ++nerrors; + } + continue; + } if (verbose) - printf ("%s.%d: done with sigsetjmp(); calling children\n", - __FUNCTION__, i + 1); + printf ("%s.%d: done with sigsetjmp(); calling children\n", + __FUNCTION__, i + 1); raise_siglongjmp (jbuf, 0, i + 1); fprintf (stderr, "%s: raise_siglongjmp() returned unexpectedly\n", - __FUNCTION__); + __FUNCTION__); ++nerrors; } } @@ -143,7 +143,7 @@ sighandler (int signal) int main (int argc, char **argv UNUSED) { - volatile sigset_t sigset1, sigset2, sigset3; + sigset_t sigset1, sigset2, sigset3; volatile struct sigaction act; if (argc > 1) @@ -172,13 +172,13 @@ main (int argc, char **argv UNUSED) sigemptyset ((sigset_t *) &sigset3); sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, "FAILURE: _longjmp() manipulated signal mask!\n"); - ++nerrors; - } + sizeof (sigset_t)) != 0) + { + fprintf (stderr, "FAILURE: _longjmp() manipulated signal mask!\n"); + ++nerrors; + } else if (verbose) - printf ("OK: _longjmp() seems not to change signal mask\n"); + printf ("OK: _longjmp() seems not to change signal mask\n"); } else { @@ -193,14 +193,14 @@ main (int argc, char **argv UNUSED) sigemptyset ((sigset_t *) &sigset3); sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() didn't restore signal mask!\n"); - ++nerrors; - } + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() didn't restore signal mask!\n"); + ++nerrors; + } else if (verbose) - printf ("OK: siglongjmp() restores signal mask when asked to\n"); + printf ("OK: siglongjmp() restores signal mask when asked to\n"); } else { @@ -215,14 +215,14 @@ main (int argc, char **argv UNUSED) sigemptyset ((sigset_t *) &sigset3); sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() changed signal mask!\n"); - ++nerrors; - } + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() changed signal mask!\n"); + ++nerrors; + } else if (verbose) - printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); + printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); } else { @@ -237,14 +237,14 @@ main (int argc, char **argv UNUSED) sigemptyset ((sigset_t *) &sigset3); sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() didn't restore signal mask!\n"); - ++nerrors; - } + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() didn't restore signal mask!\n"); + ++nerrors; + } else if (verbose) - printf ("OK: siglongjmp() restores signal mask when asked to\n"); + printf ("OK: siglongjmp() restores signal mask when asked to\n"); } else { @@ -261,14 +261,14 @@ main (int argc, char **argv UNUSED) sigemptyset ((sigset_t *) &sigset3); sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset4, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() changed signal mask!\n"); - ++nerrors; - } + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() changed signal mask!\n"); + ++nerrors; + } else if (verbose) - printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); + printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); } else { diff --git a/src/native/external/libunwind/tests/x64-test-dwarf-expressions.S b/src/native/external/libunwind/tests/x64-test-dwarf-expressions.S index 19ebc9d438d990..c6409b7c7928d1 100644 --- a/src/native/external/libunwind/tests/x64-test-dwarf-expressions.S +++ b/src/native/external/libunwind/tests/x64-test-dwarf-expressions.S @@ -76,3 +76,6 @@ DW_CFA_expression_inner: ret .cfi_endproc .size DW_CFA_expression_inner,.-DW_CFA_expression_inner + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/native/external/libunwind/tests/x64-unwind-badjmp-signal-frame.c b/src/native/external/libunwind/tests/x64-unwind-badjmp-signal-frame.c index c7b7cf7335a8bd..1c3f8f3653968b 100644 --- a/src/native/external/libunwind/tests/x64-unwind-badjmp-signal-frame.c +++ b/src/native/external/libunwind/tests/x64-unwind-badjmp-signal-frame.c @@ -26,9 +26,8 @@ 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 @@ -37,12 +36,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UNW_LOCAL_ONLY #include +#include "compiler.h" /* * unwind in the signal handler checking the backtrace is correct * after a bad jump. */ -void handle_sigsegv(int signal, siginfo_t *info, void *ucontext) +void handle_sigsegv(int signal UNUSED, siginfo_t *info UNUSED, void *ucontext UNUSED) { /* * 0 = success @@ -57,6 +57,9 @@ void handle_sigsegv(int signal, siginfo_t *info, void *ucontext) int found_signal_frame = 0; int i = 0; char *names[] = { +#if defined __FreeBSD__ + "", +#endif "", "main", }; @@ -105,7 +108,7 @@ void handle_sigsegv(int signal, siginfo_t *info, void *ucontext) void (*invalid_function)() = (void*)1; -int main(int argc, char *argv[]) +int main(int argc UNUSED, char *argv[] UNUSED) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); diff --git a/src/native/external/libunwind_extras/CMakeLists.txt b/src/native/external/libunwind_extras/CMakeLists.txt index d40b920e0b135e..07a4bb64db940d 100644 --- a/src/native/external/libunwind_extras/CMakeLists.txt +++ b/src/native/external/libunwind_extras/CMakeLists.txt @@ -9,6 +9,7 @@ add_definitions(-DHAVE___THREAD=0) add_definitions(-D_GNU_SOURCE) add_definitions(-DPACKAGE_STRING="") add_definitions(-DPACKAGE_BUGREPORT="") +add_definitions(-DHAVE_DL_ITERATE_PHDR=1) if(CLR_CMAKE_HOST_UNIX) if (CLR_CMAKE_HOST_ARCH_AMD64) diff --git a/src/native/external/libunwind_extras/config.h.in b/src/native/external/libunwind_extras/config.h.in index 4c06e69879688c..35b44b11d80726 100644 --- a/src/native/external/libunwind_extras/config.h.in +++ b/src/native/external/libunwind_extras/config.h.in @@ -20,6 +20,8 @@ #cmakedefine HAVE_STDALIGN_H #cmakedefine HAVE_STDALIGN_ALIGNAS +#cmakedefine HAVE_PIPE2 + #if defined(_MSC_VER) && defined(HAVE_STDALIGN_H) && !defined(HAVE_STDALIGN_ALIGNAS) // alignment is a performance optimization for the cross compile libunwind // Simply ignore it if it is not supported by the compiler diff --git a/src/native/external/libunwind_extras/configure.cmake b/src/native/external/libunwind_extras/configure.cmake index deb2bd5fe14114..711f64f040bce3 100644 --- a/src/native/external/libunwind_extras/configure.cmake +++ b/src/native/external/libunwind_extras/configure.cmake @@ -1,5 +1,6 @@ include(CheckCSourceCompiles) include(CheckIncludeFiles) +include(CheckFunctionExists) if(CLR_CMAKE_HOST_WIN32) # Our posix abstraction layer will provide these headers @@ -37,6 +38,8 @@ check_include_files(sys/link.h HAVE_SYS_LINK_H) check_include_files(atomic_ops.h HAVE_ATOMIC_OPS_H) +check_function_exists(pipe2 HAVE_PIPE2) + check_c_source_compiles(" int main(int argc, char **argv) {