From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13543 invoked by alias); 25 Apr 2017 12:50:03 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 13036 invoked by uid 89); 25 Apr 2017 12:49:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.2 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.3 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=ESP X-Spam-Status: No, score=-24.3 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: gnu.wildebeest.org From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Ulf Hermann , Mark Wielaard Subject: [PATCH 4/5] Add i386 frame pointer unwinder. Date: Tue, 25 Apr 2017 12:56:00 -0000 Message-Id: <1493124579-21017-4-git-send-email-mark@klomp.org> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1493124579-21017-1-git-send-email-mark@klomp.org> References: <1493124006.31726.33.camel@klomp.org> <1493124579-21017-1-git-send-email-mark@klomp.org> X-SW-Source: 2017-q2/txt/msg00084.txt.bz2 Add a simple i386_unwind.c frame pointer unwinder as fallback if DWARF/CFI unwinding fails. Signed-off-by: Mark Wielaard --- backends/ChangeLog | 6 +++ backends/Makefile.am | 2 +- backends/i386_init.c | 3 +- backends/i386_unwind.c | 84 ++++++++++++++++++++++++++++++++++++ tests/ChangeLog | 9 ++++ tests/Makefile.am | 5 ++- tests/backtrace.i386.fp.core.bz2 | Bin 0 -> 8532 bytes tests/backtrace.i386.fp.exec.bz2 | Bin 0 -> 357436 bytes tests/run-backtrace-fp-core-i386.sh | 29 +++++++++++++ 9 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 backends/i386_unwind.c create mode 100644 tests/backtrace.i386.fp.core.bz2 create mode 100755 tests/backtrace.i386.fp.exec.bz2 create mode 100755 tests/run-backtrace-fp-core-i386.sh diff --git a/backends/ChangeLog b/backends/ChangeLog index eec9923..733e72c 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,9 @@ +2017-04-06 Mark Wielaard + + * i386_unwind.c: New file. + * i386_init.c: Hook i386_unwind. + * Makefile.am (i386_SRCS): Add i386_unwind.c + 2017-02-09 Ulf Hermann * x86_64_unwind.c: New file diff --git a/backends/Makefile.am b/backends/Makefile.am index 60917b9..22eb6ac 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -48,7 +48,7 @@ libdw = ../libdw/libdw.so i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \ i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c \ - i386_initreg.c + i386_initreg.c i386_unwind.c cpu_i386 = ../libcpu/libcpu_i386.a libebl_i386_pic_a_SOURCES = $(i386_SRCS) am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os) diff --git a/backends/i386_init.c b/backends/i386_init.c index 515d5ac..fc1587a 100644 --- a/backends/i386_init.c +++ b/backends/i386_init.c @@ -1,5 +1,5 @@ /* Initialization of i386 specific backend library. - Copyright (C) 2000-2009, 2013 Red Hat, Inc. + Copyright (C) 2000-2009, 2013, 2017 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2000. @@ -65,6 +65,7 @@ i386_init (Elf *elf __attribute__ ((unused)), /* gcc/config/ #define DWARF_FRAME_REGISTERS. For i386 it is 17, why? */ eh->frame_nregs = 9; HOOK (eh, set_initial_registers_tid); + HOOK (eh, unwind); return MODVERSION; } diff --git a/backends/i386_unwind.c b/backends/i386_unwind.c new file mode 100644 index 0000000..5c9a5de --- /dev/null +++ b/backends/i386_unwind.c @@ -0,0 +1,84 @@ +/* Get previous frame state for an existing frame state using frame pointers. + Copyright (C) 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + +/* Register numbers for frame and stack pointers. We take advantage of + them being next to each other when calling getfunc and setfunc. */ +#define ESP 4 +#define EBP (ESP + 1) + +/* Most basic frame pointer chasing with EBP as frame pointer. + PC = *(FP + 4), SP = FP + 8, FP = *FP. */ +bool +i386_unwind (Ebl *ebl __attribute__ ((unused)), + Dwarf_Addr pc __attribute__ ((unused)), + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep __attribute__ ((unused))) +{ + /* sp = 0, fp = 1 */ + Dwarf_Word regs[2]; + + /* Get current stack and frame pointers. */ + if (! getfunc (ESP, 2, regs, arg)) + return false; + + Dwarf_Word sp = regs[0]; + Dwarf_Word fp = regs[1]; + + /* Sanity check. We only support traditional stack frames. */ + if (fp == 0 || sp == 0 || fp < sp) + return false; + + /* Get the return address from the stack, it is our new pc. */ + Dwarf_Word ret_addr; + if (! readfunc (fp + 4, &ret_addr, arg) || ret_addr == 0) + return false; + + /* Get new sp and fp. Sanity check again. */ + sp = fp + 8; + if (! readfunc (fp, &fp, arg) || fp == 0 || sp >= fp) + return false; + + /* Set new sp, fp and pc. */ + regs[0] = sp; + regs[1] = fp; + if (! setfunc (ESP, 2, regs, arg) || ! setfunc (-1, 1, &ret_addr, arg)) + return false; + + return true; +} diff --git a/tests/ChangeLog b/tests/ChangeLog index 49b6a3f..67a44f7 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,12 @@ +2017-04-06 Mark Wielaard + + * run-backtrace-fp-core-i386.sh: New test. + * backtrace.i386.fp.core.bz2: New test file. + * backtrace.i386.fp.exec.bz2: New testfile. + * Makefile.am (TESTS): Add run-backtrace-fp-core-i386.sh. + (EXTRA_DIST): Add run-backtrace-fp-core-i386.sh, + backtrace.i386.fp.core.bz2 and backtrace.i386.fp.exec.bz2. + 2017-02-09 Ulf Hermann * Makefile.am: Add test for unwinding with frame pointers on x86_64 diff --git a/tests/Makefile.am b/tests/Makefile.am index b0db19f..2c82bfd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -117,7 +117,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \ run-backtrace-fp-core-x86_64.sh \ run-backtrace-core-x32.sh \ - run-backtrace-core-i386.sh run-backtrace-core-ppc.sh \ + run-backtrace-core-i386.sh run-backtrace-fp-core-i386.sh \ + run-backtrace-core-ppc.sh \ run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \ run-backtrace-core-aarch64.sh run-backtrace-core-sparc.sh \ run-backtrace-demangle.sh run-stack-d-test.sh run-stack-i-test.sh \ @@ -297,6 +298,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-backtrace-fp-core-x86_64.sh \ run-backtrace-core-x32.sh \ backtrace-subr.sh backtrace.i386.core.bz2 backtrace.i386.exec.bz2 \ + run-backtrace-fp-core-i386.sh \ + backtrace.i386.fp.core.bz2 backtrace.i386.fp.exec.bz2 \ backtrace.x86_64.core.bz2 backtrace.x86_64.exec.bz2 \ backtrace.x86_64.fp.core.bz2 backtrace.x86_64.fp.exec.bz2 \ backtrace.ppc.core.bz2 backtrace.ppc.exec.bz2 \ diff --git a/tests/run-backtrace-fp-core-i386.sh b/tests/run-backtrace-fp-core-i386.sh new file mode 100755 index 0000000..c58ff53 --- /dev/null +++ b/tests/run-backtrace-fp-core-i386.sh @@ -0,0 +1,29 @@ +#! /bin/bash +# Copyright (C) 2017 Red Hat, Inc. +# This file is part of elfutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. $srcdir/backtrace-subr.sh + +# The binary is generated by compiling backtrace-child without unwind +# information, but with -fno-omit-frame-pointer. +# +# gcc -static -O2 -fno-omit-frame-pointer -fno-asynchronous-unwind-tables \ +# -D_GNU_SOURCE -pthread -o tests/backtrace.i386.fp.exec -I. -Ilib \ +# tests/backtrace-child.c +# +# The core is generated by calling tests/backtrace.i386.fp.exec --gencore + +check_core i386.fp -- 1.8.3.1