From 4f1c96d8809a2ccbfd7d54bbca9a3a0c1e5f2796 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 4 Jan 2014 14:24:58 +0100 Subject: tests: Simplify backtrace-dwarf (gcc cleanup-13.c) testcase. The testcase originally came from GCC which was testing the runtime unwinder using _Unwind_ForcedUnwind. Since we are using our own external unwinder we can just abort at the right place and unwind from there. Signed-off-by: Mark Wielaard --- tests/ChangeLog | 6 ++++++ tests/cleanup-13.c | 24 +++--------------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/tests/ChangeLog b/tests/ChangeLog index c68ae26c..63692e3d 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2014-01-04 Mark Wielaard + + * cleanup-13.c (force_unwind_stop): Removed. + (force_unwind): Just call abort. Don't setup _Unwind_Exception and + don't call _Unwind_ForcedUnwind. + 2014-01-03 Mark Wielaard * run-addrcfi.sh: Add case for EM_AARCH64. diff --git a/tests/cleanup-13.c b/tests/cleanup-13.c index b87c6965..3919b91a 100644 --- a/tests/cleanup-13.c +++ b/tests/cleanup-13.c @@ -283,30 +283,12 @@ extern char verify_it[sizeof (cfi_arch_program) - 0x80 < 0x3f80 ? 1 : -1]; : : "i" (sizeof (cfi_arch_program))) #endif #endif -static _Unwind_Reason_Code -force_unwind_stop (int version, _Unwind_Action actions, - _Unwind_Exception_Class exc_class, - struct _Unwind_Exception *exc_obj, - struct _Unwind_Context *context, - void *stop_parameter) -{ - if (actions & _UA_END_OF_STACK) - abort (); - return _URC_NO_REASON; -} + +/* The original GCC testcase tests the runtime unwinder using + _Unwind_ForcedUnwind, we just inspect the child when it aborts. */ static void force_unwind () { - struct _Unwind_Exception *exc = malloc (sizeof (*exc)); - memset (&exc->exception_class, 0, sizeof (exc->exception_class)); - exc->exception_cleanup = 0; - -#ifndef __USING_SJLJ_EXCEPTIONS__ - _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); -#else - _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); -#endif - abort (); } -- cgit v1.2.1 From 1051a0c8ad8b69725384de20647a982b283701f0 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 4 Jan 2014 15:41:04 +0100 Subject: tests: backtrace-subr.sh skip check_native_core test if core ulimit fails. Signed-off-by: Mark Wielaard --- tests/ChangeLog | 5 +++++ tests/backtrace-subr.sh | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/ChangeLog b/tests/ChangeLog index 63692e3d..0c112cf2 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2014-01-04 Mark Wielaard + + * backtrace-subr.sh (check_native_core): Skip, exit 77, the test + if we cannot adjust core ulimit. + 2014-01-04 Mark Wielaard * cleanup-13.c (force_unwind_stop): Removed. diff --git a/tests/backtrace-subr.sh b/tests/backtrace-subr.sh index 580a1cea..e7ece91c 100644 --- a/tests/backtrace-subr.sh +++ b/tests/backtrace-subr.sh @@ -109,7 +109,8 @@ check_native_core() SAVED_VALGRIND_CMD="$VALGRIND_CMD" unset VALGRIND_CMD - core="core.`ulimit -c unlimited; set +ex; testrun ${abs_builddir}/$child --gencore; true`" + # Skip the test if we cannot adjust core ulimit. + core="core.`ulimit -c unlimited || exit 77; set +ex; testrun ${abs_builddir}/$child --gencore; true`" if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then VALGRIND_CMD="$SAVED_VALGRIND_CMD" -- cgit v1.2.1 From 0c4a868fa4c3e2a45663a78cc6d1e31089c3b0dc Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 4 Jan 2014 19:19:16 +0100 Subject: backends: Add PPC64 machine_flag_check. To distinguish between the current PPC64 ELF ABI and the revised ELFv2 ABI that will not use function descriptors binutils started to emit the version (currently 1) in the ehdr e_flags. Recognize all valid versions (0, 1 or 2) in elflint by adding the hook ppc64_machine_flag_check. Signed-off-by: Mark Wielaard --- backends/ChangeLog | 5 +++++ backends/ppc64_init.c | 3 ++- backends/ppc64_symbol.c | 12 +++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/backends/ChangeLog b/backends/ChangeLog index 2074cff3..4ea1acd2 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,8 @@ +2014-01-04 Mark Wielaard + + * ppc64_symbol.c (ppc64_machine_flag_check): New function. + * ppc64_init.c (ppc64_init): Hook machine_flag_check. + 2014-01-03 Mark Wielaard * Makefile.am (aarch64_SRCS): Add aarch64_cfi.c. diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c index d8f1417e..e52231c9 100644 --- a/backends/ppc64_init.c +++ b/backends/ppc64_init.c @@ -1,5 +1,5 @@ /* Initialization of PPC64 specific backend library. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Red Hat, Inc. + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2004. @@ -58,6 +58,7 @@ ppc64_init (elf, machine, eh, ehlen) HOOK (eh, reloc_simple_type); HOOK (eh, dynamic_tag_name); HOOK (eh, dynamic_tag_check); + HOOK (eh, machine_flag_check); HOOK (eh, copy_reloc_p); HOOK (eh, check_special_symbol); HOOK (eh, bss_plt_p); diff --git a/backends/ppc64_symbol.c b/backends/ppc64_symbol.c index 244e40f8..212d4145 100644 --- a/backends/ppc64_symbol.c +++ b/backends/ppc64_symbol.c @@ -1,5 +1,5 @@ /* PPC64 specific symbolic name handling. - Copyright (C) 2004, 2005 Red Hat, Inc. + Copyright (C) 2004, 2005, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2004. @@ -110,3 +110,13 @@ ppc64_bss_plt_p (Elf *elf __attribute__ ((unused)), { return true; } + +/* Check whether machine flags are valid. PPC64 has three possible values: + 0 - for unspecified ABI, or not using any specific ABI features. + 1 - for the original ELF PPC64 ABI using function descriptors. + 2 - for the revised ELFv2 PPC64 ABI without function descriptors. */ +bool +ppc64_machine_flag_check (GElf_Word flags) +{ + return flags == 0 || flags == 1 || flags == 2; +} -- cgit v1.2.1 From 70c3a53baa06b6cdee6e92bd673c1cf977066bc1 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 4 Jan 2014 23:28:33 +0100 Subject: tests: Don't use ptrace detach stopped trick. Raise can return. On older kernels the ptrace detach stop trick doesn't work reliably. Just keep the child processes attached and stopped during the tests, dwfl_linux_proc_attach will handle that fine now. Also on older kernels raise would sometimes return anyway and cause a spurious assert. Just ignore it. Signed-off-by: Mark Wielaard --- tests/ChangeLog | 12 ++++++++++++ tests/backtrace-data.c | 2 +- tests/backtrace-dwarf.c | 13 +------------ tests/backtrace.c | 13 +------------ 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/tests/ChangeLog b/tests/ChangeLog index 0c112cf2..63b7bed7 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,15 @@ +2014-01-04 Mark Wielaard + + * backtrace-data.c (main): Don't assert if raise returns. + * backtrace-dwarf.c (report_pid): Call dwfl_linux_proc_attach with + assume_ptrace_attached true. + (ptrace_detach_stopped): Removed function. + (main): Don't call ptrace_detach_stopped. + * backtrace.c (ptrace_detach_stopped): Removed function. + (report_pid): Call dwfl_linux_proc_attach with assume_ptrace_attached + true. + (exec_dump): Don't call ptrace_detach_stopped. + 2014-01-04 Mark Wielaard * backtrace-subr.sh (check_native_core): Skip, exit 77, the test diff --git a/tests/backtrace-data.c b/tests/backtrace-data.c index 9fa3c4a9..dd74160a 100644 --- a/tests/backtrace-data.c +++ b/tests/backtrace-data.c @@ -278,7 +278,7 @@ main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused))) assert_perror (errno); assert (l == 0); raise (SIGUSR1); - assert (0); + return 0; default: break; } diff --git a/tests/backtrace-dwarf.c b/tests/backtrace-dwarf.c index 3a3e7632..f75e1202 100644 --- a/tests/backtrace-dwarf.c +++ b/tests/backtrace-dwarf.c @@ -42,7 +42,7 @@ report_pid (Dwfl *dwfl, pid_t pid) if (dwfl_report_end (dwfl, NULL, NULL) != 0) error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1)); - result = dwfl_linux_proc_attach (dwfl, pid, false); + result = dwfl_linux_proc_attach (dwfl, pid, true); if (result < 0) error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1)); else if (result > 0) @@ -106,15 +106,6 @@ thread_callback (Dwfl_Thread *thread, void *thread_arg) error (1, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1)); } -static void -ptrace_detach_stopped (pid_t pid) -{ - errno = 0; - long l = ptrace (PTRACE_DETACH, pid, NULL, (void *) (intptr_t) SIGSTOP); - assert_perror (errno); - assert (l == 0); -} - int main (int argc __attribute__ ((unused)), char **argv) { @@ -151,8 +142,6 @@ main (int argc __attribute__ ((unused)), char **argv) assert (WIFSTOPPED (status)); assert (WSTOPSIG (status) == SIGABRT); - ptrace_detach_stopped (pid); - Dwfl *dwfl = pid_to_dwfl (pid); dwfl_getthreads (dwfl, thread_callback, NULL); diff --git a/tests/backtrace.c b/tests/backtrace.c index 64f90c43..758dfed6 100644 --- a/tests/backtrace.c +++ b/tests/backtrace.c @@ -259,15 +259,6 @@ prepare_thread (pid_t pid2 __attribute__ ((unused)), #include #define tgkill(pid, tid, sig) syscall (__NR_tgkill, (pid), (tid), (sig)) -static void -ptrace_detach_stopped (pid_t pid) -{ - errno = 0; - long l = ptrace (PTRACE_DETACH, pid, NULL, (void *) (intptr_t) SIGSTOP); - assert_perror (errno); - assert (l == 0); -} - static void report_pid (Dwfl *dwfl, pid_t pid) { @@ -280,7 +271,7 @@ report_pid (Dwfl *dwfl, pid_t pid) if (dwfl_report_end (dwfl, NULL, NULL) != 0) error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1)); - result = dwfl_linux_proc_attach (dwfl, pid, false); + result = dwfl_linux_proc_attach (dwfl, pid, true); if (result < 0) error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1)); else if (result > 0) @@ -397,8 +388,6 @@ exec_dump (const char *exec) prepare_thread (pid2, jmp); } dwfl_end (dwfl); - ptrace_detach_stopped (pid); - ptrace_detach_stopped (pid2); check_tid = pid2; dwfl = pid_to_dwfl (pid); dump (dwfl); -- cgit v1.2.1 From 27aae18ce872409b70afef8503941c7e75c8d93d Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 5 Jan 2014 20:37:30 +0100 Subject: libdwfl: Only skip reset of return register for non-CIE-return regno (ppc64). For PPC64 we skip resetting the return register if it is already set. This is because on PPC64 there are two DWARF registers numbers that can represent the same register. Setting the return address again confuses the unwinder. But we do want to reset it if the register number (non-translated by the ppc64 ebl) is equal to the actual register number as set in the CIE as return address. This happens on older toolchains in .debug_frame where the return address is set to 108, but the ebl abi_cfi also sets register number 65. Signed-off-by: Mark Wielaard --- libdwfl/ChangeLog | 5 +++++ libdwfl/frame_unwind.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 766fb18a..55980a57 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,8 @@ +2014-01-05 Mark Wielaard + + * frame_unwind.c (handle_cfi): Only skip resetting return register + if the regno is not the actual CIE return address register. + 2014-01-02 Mark Wielaard * linux-pid-attach.c (dwfl_linux_proc_attach): Use strtol, not atoi. diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c index 3ce45479..dc99e40b 100644 --- a/libdwfl/frame_unwind.c +++ b/libdwfl/frame_unwind.c @@ -585,8 +585,9 @@ handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias) /* This is another strange PPC[64] case. There are two registers numbers that can represent the same DWARF return register number. We only want one to actually set the return - register value. */ - if (ra_set) + register value. But we always want to override the value if + the register is the actual CIE return address register. */ + if (ra_set && regno != frame->fde->cie->return_address_register) { unsigned r = regno; if (ebl_dwarf_to_regno (ebl, &r) && r == ra) -- cgit v1.2.1