Re: [PATCH] Add -D_FORTIFY_SOURCE=2 to CFLAGS if possible.

2017-02-15 Thread Mark Wielaard
On Tue, 2017-02-14 at 21:58 -0500, Mike Frysinger wrote:
> On 09 Feb 2017 21:13, Mark Wielaard wrote:
> > +# See if we can add -D_FORTIFY_SOURCE=2. Don't do it if it is already
> > +# (differently) defined or if it generates warnings/errors because we
> > +# don't use the right optimisation level (string.h will warn about that).
> > +AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CFLAGS])
> 
> -D flags should be in CPPFLAGS ...

Normally yes, but _FORTIFY_SOURCE is "special". It depends on CFLAGS
optimization settings. If the user has given CFLAGS="-O0" for example,
or set _FORTIFY_SOURCE to 1 in CFLAGS already adding -D_FORTIFY_SOURCE=2
to CPPFLAGS won't work as intended.

> > +case "$CFLAGS" in
> > +  *-D_FORTIFY_SOURCE=2*)
> > +AC_MSG_RESULT([no, already there])
> > +;;
> > +  *)
> > +save_CFLAGS="$CFLAGS"
> > +CFLAGS="-D_FORTIFY_SOURCE=2 -Werror $CFLAGS"
> > +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
> > +  #include 
> > +  int main() { return 0; }
> > +]])], [ AC_MSG_RESULT([yes])
> > +CFLAGS="-D_FORTIFY_SOURCE=2 $save_CFLAGS" ],
> > +  [ AC_MSG_RESULT([no])
> > +CFLAGS="$save_CFLAGS"])
> > +  ;;
> 
> why not AC_PREPROC_IFELSE and check if _FORTIFY_SOURCE is defined ?

Same reason. We need to test whether the combination of
-D_FORTIFY_SOURCE=2 and any other CFLAG/CPPFLAGS flags work or not. Just
scanning preprocessor flags won't show issues exposed by actually
compiling with a C header (string.h) to see if that errors out.

Cheers,

Mark


[PATCH] backends: Add support for EM_PPC64 GNU_ATTRIBUTES.

2017-02-15 Thread Mark Wielaard
ppc64 and ppc64le ELF files can also contain a power specific
.gnu.attributes section. Add support for those and recognize the new
GNU_Power_ABI_FP Single-precision hard float value.

Signed-off-by: Mark Wielaard 
---
 backends/ChangeLog |   6 ++
 backends/ppc64_init.c  |   1 +
 backends/ppc_attrs.c   |   1 +
 tests/ChangeLog|   5 +
 tests/Makefile.am  |   4 ++--
 tests/run-readelf-A.sh |  16 +++-
 tests/testfileppc64attrs.o.bz2 | Bin 0 -> 222 bytes
 7 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 tests/testfileppc64attrs.o.bz2

diff --git a/backends/ChangeLog b/backends/ChangeLog
index 1c561b5..39390cb 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,9 @@
+2017-02-15  Mark Wielaard  
+
+   * ppc64_init.c (ppc64_init): Add check_object_attribute HOOK.
+   * ppc_attrs.c (ppc_check_object_attribute): Add Single-precision hard
+   float.
+
 2016-11-02  Mark Wielaard  
 
* i386_regs.c (i386_register_info): Add fallthrough comment.
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c
index 2ba8232..11d3a77 100644
--- a/backends/ppc64_init.c
+++ b/backends/ppc64_init.c
@@ -67,6 +67,7 @@ ppc64_init (Elf *elf __attribute__ ((unused)),
   HOOK (eh, syscall_abi);
   HOOK (eh, core_note);
   HOOK (eh, auxv_info);
+  HOOK (eh, check_object_attribute);
   HOOK (eh, abi_cfi);
   /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
   eh->frame_nregs = (114 - 1) + 32;
diff --git a/backends/ppc_attrs.c b/backends/ppc_attrs.c
index 612c576..48d7129 100644
--- a/backends/ppc_attrs.c
+++ b/backends/ppc_attrs.c
@@ -51,6 +51,7 @@ ppc_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
"Hard or soft float",
"Hard float",
"Soft float",
+   "Single-precision hard float",
  };
if (value < sizeof fp_kinds / sizeof fp_kinds[0])
  *value_name = fp_kinds[value];
diff --git a/tests/ChangeLog b/tests/ChangeLog
index bca47be..994ff1f 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2017-02-15  Ulf Hermann  
+
+   * Makefile.am (EXTRA_DIST): Add testfileppc64attrs.o.bz2.
+   * run-readelf-A.sh: Add testfileppc64.o test.
+
 2017-02-09  Ulf Hermann  
 
* backtrace.c: Add an option to allow unknown symbols in the trace
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d4659cd..a27e868 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 1996-2016 Red Hat, Inc.
+## Copyright (C) 1996-2017 Red Hat, Inc.
 ## This file is part of elfutils.
 ##
 ## This file is free software; you can redistribute it and/or modify
@@ -317,7 +317,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
 run-aggregate-size.sh testfile-sizes1.o.bz2 testfile-sizes2.o.bz2 \
 testfile-sizes3.o.bz2 \
 run-readelf-A.sh testfileppc32attrs.o.bz2 \
-testfilesparc64attrs.o.bz2 \
+testfilesparc64attrs.o.bz2 testfileppc64attrs.o.bz2 \
 testfile-debug-types.bz2 \
 run-getsrc-die.sh run-strptr.sh \
 testfile-x32-core.bz2 testfile-x32.bz2 \
diff --git a/tests/run-readelf-A.sh b/tests/run-readelf-A.sh
index 03d511c..b7432be 100755
--- a/tests/run-readelf-A.sh
+++ b/tests/run-readelf-A.sh
@@ -32,7 +32,12 @@
 #
 # gcc -c testfilesparc64attrs.s
 
-testfiles testfilearm testfileppc32attrs.o testfilesparc64attrs.o
+# = testfileppc64attrs.s =
+# .gnu_attribute 4,3
+#
+# gcc -c testfileppc64attrs.s
+
+testfiles testfilearm testfileppc32attrs.o testfilesparc64attrs.o 
testfileppc64attrs.o
 
 testrun_compare ${abs_top_builddir}/src/readelf -A testfilearm <<\EOF
 
@@ -79,4 +84,13 @@ Object attributes section [ 4] '.gnu.attributes' of 21 bytes 
at offset 0x40:
   GNU_Sparc_HWCAPS2: fjathplus,adp,mwait,xmont
 EOF
 
+testrun_compare ${abs_top_builddir}/src/readelf -A testfileppc64attrs.o <<\EOF
+
+Object attributes section [ 4] '.gnu.attributes' of 16 bytes at offset 0x40:
+  Owner  Size
+  gnu  15
+File:   7
+  GNU_Power_ABI_FP: Single-precision hard float
+EOF
+
 exit 0
diff --git a/tests/testfileppc64attrs.o.bz2 b/tests/testfileppc64attrs.o.bz2
new file mode 100644
index 
..5af2ab6f1cb99e3a7e9bd7cdcb872da218a8f9b1
GIT binary patch
literal 222
zcmV<403rWET4*^jL0KkKS)xBPg#ZAve}w<+>PR4k00d(MKma!5o?w7r0syc8wqVgD
z@=rvuCEOfMvj55gxRJ23rB0S@lG;hTU@51^4zN{Con@-$wr%I$5dThoR>K?K)EO
Y!nF@|

[PATCH] Always use the same method to query the system page size

2017-02-15 Thread Ulf Hermann

This makes it easier to write a replacement for it on systems where
sysconf(3) doesn't exist.
---
 lib/ChangeLog  | 4 
 lib/crc32_file.c   | 2 +-
 libdwfl/ChangeLog  | 5 +
 libdwfl/linux-kernel-modules.c | 2 +-
 libdwfl/linux-proc-maps.c  | 2 +-
 5 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 5ccf4d6..6578ddb 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-15  Ulf Hermann  
+
+   * crc32_file.c: Use _SC_PAGESIZE rather than _SC_PAGE_SIZE.
+
 2017-02-14  Ulf Hermann  
 
 	* color.h: New file.

diff --git a/lib/crc32_file.c b/lib/crc32_file.c
index 57e4298..f7607d0 100644
--- a/lib/crc32_file.c
+++ b/lib/crc32_file.c
@@ -53,7 +53,7 @@ crc32_file (int fd, uint32_t *resp)
   void *mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
   if (mapped == MAP_FAILED && errno == ENOMEM)
{
- const size_t pagesize = sysconf (_SC_PAGE_SIZE);
+ const size_t pagesize = sysconf (_SC_PAGESIZE);
  mapsize = ((mapsize / 2) + pagesize - 1) & -pagesize;
  while (mapsize >= pagesize
 && (mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE,
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 57671ea..52466cc 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2017-02-15  Ulf Hermann  
+
+   * linux-kernel-modules.c: Use sysconf(_SC_PAGESIZE) to get page size.
+   * linux-proc-maps.c: Likewise.
+
 2016-12-29  Luiz Angelo Daros de Luca  
 
 	* dwfl_build_id_find_elf.c: Include system.h.

diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c
index 9cd8ea9..a7ac19d 100644
--- a/libdwfl/linux-kernel-modules.c
+++ b/libdwfl/linux-kernel-modules.c
@@ -500,7 +500,7 @@ intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, 
Dwarf_Addr *notes)
if (*notes == 0 && !strcmp (state.p, "__start_notes\n"))
  *notes = *end;
 
-  Dwarf_Addr round_kernel = sysconf (_SC_PAGE_SIZE);

+  Dwarf_Addr round_kernel = sysconf (_SC_PAGESIZE);
   *start &= -(Dwarf_Addr) round_kernel;
   *end += round_kernel - 1;
   *end &= -(Dwarf_Addr) round_kernel;
diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c
index 4ae1e74..094dd53 100644
--- a/libdwfl/linux-proc-maps.c
+++ b/libdwfl/linux-proc-maps.c
@@ -418,7 +418,7 @@ dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ 
((unused)),
   if (fd < 0)
goto detach;
 
-  *elfp = elf_from_remote_memory (base, getpagesize (), NULL,

+  *elfp = elf_from_remote_memory (base, sysconf (_SC_PAGESIZE), NULL,
  &read_proc_memory, &fd);
 
   close (fd);

--
2.1.4



[PATCH v2] Always use the same method to query the system page size

2017-02-15 Thread Ulf Hermann

This makes it easier to write a replacement for it on systems where
sysconf(3) doesn't exist.

Signed-off-by: Ulf Hermann 
---
 lib/ChangeLog  | 4 
 lib/crc32_file.c   | 2 +-
 libdwfl/ChangeLog  | 5 +
 libdwfl/linux-kernel-modules.c | 2 +-
 libdwfl/linux-proc-maps.c  | 2 +-
 5 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 5ccf4d6..6578ddb 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-15  Ulf Hermann  
+
+   * crc32_file.c: Use _SC_PAGESIZE rather than _SC_PAGE_SIZE.
+
 2017-02-14  Ulf Hermann  
 
 	* color.h: New file.

diff --git a/lib/crc32_file.c b/lib/crc32_file.c
index 57e4298..f7607d0 100644
--- a/lib/crc32_file.c
+++ b/lib/crc32_file.c
@@ -53,7 +53,7 @@ crc32_file (int fd, uint32_t *resp)
   void *mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
   if (mapped == MAP_FAILED && errno == ENOMEM)
{
- const size_t pagesize = sysconf (_SC_PAGE_SIZE);
+ const size_t pagesize = sysconf (_SC_PAGESIZE);
  mapsize = ((mapsize / 2) + pagesize - 1) & -pagesize;
  while (mapsize >= pagesize
 && (mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE,
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 57671ea..52466cc 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2017-02-15  Ulf Hermann  
+
+   * linux-kernel-modules.c: Use sysconf(_SC_PAGESIZE) to get page size.
+   * linux-proc-maps.c: Likewise.
+
 2016-12-29  Luiz Angelo Daros de Luca  
 
 	* dwfl_build_id_find_elf.c: Include system.h.

diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c
index 9cd8ea9..a7ac19d 100644
--- a/libdwfl/linux-kernel-modules.c
+++ b/libdwfl/linux-kernel-modules.c
@@ -500,7 +500,7 @@ intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, 
Dwarf_Addr *notes)
if (*notes == 0 && !strcmp (state.p, "__start_notes\n"))
  *notes = *end;
 
-  Dwarf_Addr round_kernel = sysconf (_SC_PAGE_SIZE);

+  Dwarf_Addr round_kernel = sysconf (_SC_PAGESIZE);
   *start &= -(Dwarf_Addr) round_kernel;
   *end += round_kernel - 1;
   *end &= -(Dwarf_Addr) round_kernel;
diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c
index 4ae1e74..094dd53 100644
--- a/libdwfl/linux-proc-maps.c
+++ b/libdwfl/linux-proc-maps.c
@@ -418,7 +418,7 @@ dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ 
((unused)),
   if (fd < 0)
goto detach;
 
-  *elfp = elf_from_remote_memory (base, getpagesize (), NULL,

+  *elfp = elf_from_remote_memory (base, sysconf (_SC_PAGESIZE), NULL,
  &read_proc_memory, &fd);
 
   close (fd);

--
2.1.4



Re: [PATCH] Move color handling into a separate header

2017-02-15 Thread Mark Wielaard
On Tue, 2017-02-14 at 14:30 +0100, Ulf Hermann wrote:
> We only need it in nm.c and objdump.c, but it pulls in argp as
> dependency. By dropping it from libeu.h, the libraries can be
> compiled without argp.

Looks fine. Applied.

Note that elfutils configure already checks for a separate argp library
in case your libc doesn't include support directly. See configure.ac.

Also there is still something odd with the patches. They seem to contain
a doubling of spaces at the start of the line. They apply fine if I
first do %s/^  / / though. Strange. I dunno where/what adds the extra
space.

Cheers,

Mark


Re: [PATCH v2] Always use the same method to query the system page size

2017-02-15 Thread Mark Wielaard
On Wed, 2017-02-15 at 15:28 +0100, Ulf Hermann wrote:
> This makes it easier to write a replacement for it on systems where
> sysconf(3) doesn't exist.

To be honest I don't know if it makes sense to port elfutils to a
platform where sysconf doesn't even exist. But the patch is OK. The
correct spelling is indeed _SC_PAGESIZE and getpagesize () really is
just sysconf (_SC_PAGESIZE). Applied.

Thanks,

Mark


frame unwinding patches

2017-02-15 Thread Mark Wielaard
Hi,

I put all three frame pointer unwinding fallback patches on
the mjw/fp-unwind branch. I'll also sent them to the list using
git send-mail --annotate taking out the binary file patches.
Hopefully that will make them appear on the list, bypassing the
spam filters.

[PATCH 1/3] Add frame pointer unwinding as fallback on x86_64
[PATCH 2/3] Add frame pointer unwinding as fallback on arm
[PATCH 3/3] Add frame pointer unwinding for aarch64

I had to hand apply a few things because of whitespace adjustments.
Hopefully I did it right and this is how Ulf intended the patches.
If not, my apologies, and please let me know what changes you did
intend.

Cheers,

Mark


[PATCH 1/3] Add frame pointer unwinding as fallback on x86_64

2017-02-15 Thread Mark Wielaard
From: Ulf Hermann 

If we don't find any debug information for a given frame, we usually
cannot unwind any further. However, the binary in question might have
been compiled with frame pointers, in which case we can look up the
well known frame pointer locations in the stack snapshot and use them
to bridge the frames without debug information.

The "unwind" hook is the right place for this as it is so far only
used on s390 and called only after trying to unwind with debug
information.

Signed-off-by: Ulf Hermann 
---
 backends/ChangeLog|   6 +++
 backends/Makefile.am  |   2 +-
 backends/x86_64_init.c|   1 +
 backends/x86_64_unwind.c  |  86 ++
 tests/ChangeLog   |   7 +++
 tests/Makefile.am |   3 ++
 tests/backtrace.x86_64.fp.core.bz2| Bin 0 -> 9861 bytes
 tests/backtrace.x86_64.fp.exec.bz2| Bin 0 -> 309484 bytes
 tests/run-backtrace-fp-core-x86_64.sh |  33 +
 9 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 backends/x86_64_unwind.c
 create mode 100644 tests/backtrace.x86_64.fp.core.bz2
 create mode 100755 tests/backtrace.x86_64.fp.exec.bz2
 create mode 100755 tests/run-backtrace-fp-core-x86_64.sh

diff --git a/backends/ChangeLog b/backends/ChangeLog
index 1c561b5..371f071 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,9 @@
+2017-02-09  Ulf Hermann  
+
+   * x86_64_unwind.c: New file
+   * Makefile.am (x86_64_SRCS): Add x86_64_unwind.c
+   * x86_64_init.c (x86_64_init): Hook x86_64_unwind
+
 2016-11-02  Mark Wielaard  
 
* i386_regs.c (i386_register_info): Add fallthrough comment.
diff --git a/backends/Makefile.am b/backends/Makefile.am
index b553ec3..60917b9 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -59,7 +59,7 @@ am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
 
 x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \
  x86_64_retval.c x86_64_regs.c i386_auxv.c x86_64_syscall.c \
- x86_64_initreg.c x32_corenote.c
+ x86_64_initreg.c x86_64_unwind.c x32_corenote.c
 cpu_x86_64 = ../libcpu/libcpu_x86_64.a
 libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
 am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
diff --git a/backends/x86_64_init.c b/backends/x86_64_init.c
index cfd0158..adfa479 100644
--- a/backends/x86_64_init.c
+++ b/backends/x86_64_init.c
@@ -68,6 +68,7 @@ x86_64_init (Elf *elf __attribute__ ((unused)),
   /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
   eh->frame_nregs = 17;
   HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, unwind);
 
   return MODVERSION;
 }
diff --git a/backends/x86_64_unwind.c b/backends/x86_64_unwind.c
new file mode 100644
index 000..ade64c0
--- /dev/null
+++ b/backends/x86_64_unwind.c
@@ -0,0 +1,86 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2016 The Qt Company Ltd.
+   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 x86_64_
+#include "libebl_CPU.h"
+
+/* There was no CFI. Maybe we happen to have a frame pointer and can unwind 
from that?  */
+
+bool
+x86_64_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)))
+{
+  // Register 6 is supposed to be rbp, thus the conventional frame pointer
+  const int fpReg = 6;
+  const int spReg = 7;
+
+  Dwarf_Word fp;
+  if (!getfunc(fpReg, 1, &fp, arg) || fp == 0)
+return false;
+
+  // Try to read old sp, so that we can avoid infinite loops below
+  Dwarf_Word sp;
+  if (!getfunc(spReg, 1, &sp, arg))
+sp = 0;
+
+  Dwarf_Word prev_fp;
+  if (!readfunc(fp, &prev_fp, arg))
+prev_fp = 0;
+
+  Dwarf_Word ret;
+  if (!readfunc(fp + 8, &ret, arg))
+

[PATCH 2/3] Add frame pointer unwinding as fallback on arm

2017-02-15 Thread Mark Wielaard
From: Ulf Hermann 

If we don't find any debug information for a given frame, we usually
cannot unwind any further. However, the binary in question might have
been compiled with frame pointers, in which case we can look up the
well known frame pointer locations in the stack snapshot and use them
to bridge the frames without debug information.

At the moment this works only for ARM code. THUMB code uses a
different mechanism for unwinding. Also, in order to figure out if
a function was compiled in ARM or in THUMB mode we need a symbol
table which might not be available (e.g. with JIT-compiled code).

Signed-off-by: Ulf Hermann 
---
 backends/ChangeLog |   6 +++
 backends/Makefile.am   |   3 +-
 backends/arm_init.c|   1 +
 backends/arm_unwind.c  |  88 +
 tests/ChangeLog|   7 +++
 tests/Makefile.am  |   3 ++
 tests/backtrace.arm.fp.core.bz2| Bin 0 -> 10997 bytes
 tests/backtrace.arm.fp.exec.bz2| Bin 0 -> 245414 bytes
 tests/run-backtrace-fp-core-arm.sh |  37 
 9 files changed, 144 insertions(+), 1 deletion(-)
 create mode 100644 backends/arm_unwind.c
 create mode 100644 tests/backtrace.arm.fp.core.bz2
 create mode 100755 tests/backtrace.arm.fp.exec.bz2
 create mode 100755 tests/run-backtrace-fp-core-arm.sh

diff --git a/backends/ChangeLog b/backends/ChangeLog
index 371f071..6837a49 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,5 +1,11 @@
 2017-02-09  Ulf Hermann  
 
+   * arm_unwind.c: New file
+   * Makefile.am (arm_SRCS): Add arm_unwind.c
+   * arm_init.c (arm_init): Hook arm_unwind
+
+2017-02-09  Ulf Hermann  
+
* x86_64_unwind.c: New file
* Makefile.am (x86_64_SRCS): Add x86_64_unwind.c
* x86_64_init.c (x86_64_init): Hook x86_64_unwind
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 60917b9..14cbf04 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -74,7 +74,8 @@ libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
 am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
 
 arm_SRCS = arm_init.c arm_symbol.c arm_regs.c arm_corenote.c \
-  arm_auxv.c arm_attrs.c arm_retval.c arm_cfi.c arm_initreg.c
+  arm_auxv.c arm_attrs.c arm_retval.c arm_cfi.c arm_initreg.c \
+  arm_unwind.c
 libebl_arm_pic_a_SOURCES = $(arm_SRCS)
 am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
 
diff --git a/backends/arm_init.c b/backends/arm_init.c
index caadac6..4fa0601 100644
--- a/backends/arm_init.c
+++ b/backends/arm_init.c
@@ -68,6 +68,7 @@ arm_init (Elf *elf __attribute__ ((unused)),
   /* We only unwind the core integer registers.  */
   eh->frame_nregs = 16;
   HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, unwind);
 
   /* Bit zero encodes whether an function address is THUMB or ARM. */
   eh->func_addr_mask = ~(GElf_Addr)1;
diff --git a/backends/arm_unwind.c b/backends/arm_unwind.c
new file mode 100644
index 000..c20ebc2
--- /dev/null
+++ b/backends/arm_unwind.c
@@ -0,0 +1,88 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2016 The Qt Company Ltd.
+   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 
+
+#ifndef BACKEND
+#define BACKEND arm_
+#define FP_REG 11
+#define LR_REG 14
+#define SP_REG 13
+#define FP_OFFSET 4
+#define LR_OFFSET 0
+#define SP_OFFSET 8
+#endif
+
+#include "libebl_CPU.h"
+
+/* There was no CFI. Maybe we happen to have a frame pointer and can unwind 
from that?  */
+
+bool
+EBLHOOK(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)))
+{
+  Dwarf_Word fp, lr, sp;
+
+  if (!getfunc(LR_REG, 1, &lr, arg))
+return false;
+
+  if (!setfunc(-1, 1, &lr, arg))
+return false;
+
+  if (!getfunc(FP_REG, 1, &fp, 

[PATCH 3/3] Add frame pointer unwinding for aarch64

2017-02-15 Thread Mark Wielaard
From: Ulf Hermann 

If we don't find any debug information for a given frame, we usually
cannot unwind any further. However, the binary in question might have
been compiled with frame pointers, in which case we can look up the
well known frame pointer locations in the stack snapshot and use them
to bridge the frames without debug information.

The unwinding on aarch64 is pretty similar to the one on arm, the
difference is in the offsets of LR and FP on the stack.

Signed-off-by: Ulf Hermann 
---
 backends/ChangeLog |   6 +
 backends/Makefile.am   |   2 +-
 backends/aarch64_init.c|   1 +
 backends/aarch64_unwind.c  |  41 +
 tests/ChangeLog|   7 ++
 tests/Makefile.am  |   5 ++--
 tests/backtrace.aarch64.fp.core.bz2| Bin 0 -> 7302 bytes
 tests/backtrace.aarch64.fp.exec.bz2| Bin 0 -> 272102 bytes
 tests/run-backtrace-fp-core-aarch64.sh |  33 ++
 9 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 backends/aarch64_unwind.c
 create mode 100644 tests/backtrace.aarch64.fp.core.bz2
 create mode 100755 tests/backtrace.aarch64.fp.exec.bz2
 create mode 100755 tests/run-backtrace-fp-core-aarch64.sh

diff --git a/backends/ChangeLog b/backends/ChangeLog
index 6837a49..02efb00 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,5 +1,11 @@
 2017-02-09  Ulf Hermann  
 
+   * aarch64_unwind.c: New file
+   * Makefile.am (aarch64_SRCS): Add aarch64_unwind.c
+   * aarch64_init.c (aarch64_init): Hook aarch64_unwind
+
+2017-02-09  Ulf Hermann  
+
* arm_unwind.c: New file
* Makefile.am (arm_SRCS): Add arm_unwind.c
* arm_init.c (arm_init): Hook arm_unwind
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 14cbf04..bfb6b84 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -81,7 +81,7 @@ am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
 
 aarch64_SRCS = aarch64_init.c aarch64_regs.c aarch64_symbol.c  \
   aarch64_corenote.c aarch64_retval.c aarch64_cfi.c \
-  aarch64_initreg.c
+  aarch64_initreg.c aarch64_unwind.c
 libebl_aarch64_pic_a_SOURCES = $(aarch64_SRCS)
 am_libebl_aarch64_pic_a_OBJECTS = $(aarch64_SRCS:.c=.os)
 
diff --git a/backends/aarch64_init.c b/backends/aarch64_init.c
index 6395f11..0866494 100644
--- a/backends/aarch64_init.c
+++ b/backends/aarch64_init.c
@@ -63,6 +63,7 @@ aarch64_init (Elf *elf __attribute__ ((unused)),
  + ALT_FRAME_RETURN_COLUMN (used when LR isn't used) = 97 DWARF regs. */
   eh->frame_nregs = 97;
   HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, unwind);
 
   return MODVERSION;
 }
diff --git a/backends/aarch64_unwind.c b/backends/aarch64_unwind.c
new file mode 100644
index 000..bd95878
--- /dev/null
+++ b/backends/aarch64_unwind.c
@@ -0,0 +1,41 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2016 The Qt Company Ltd.
+   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
+
+#define BACKEND aarch64_
+#define FP_REG 29
+#define LR_REG 30
+#define SP_REG 31
+#define FP_OFFSET 0
+#define LR_OFFSET 8
+#define SP_OFFSET 16
+
+#include "arm_unwind.c"
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 2c210ea..71dba42 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,10 @@
+2017-02-13  Ulf Hermann  
+
+   * Makefile.am: Add test for unwinding with frame pointers on aarch64
+   * backtrace.aarch64.fp.core.bz2: New file
+   * backtrace.aarch64.fp.exec.bz2: New file
+   * run-backtrace-fp-core-aarch64.sh: New file
+
 2017-02-09  Ulf Hermann  
 
* Makefile.am: Add test for unwinding with frame pointers on arm
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b72befc..d120ed9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -114,7 +114,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile 
test-nlist \
run-backtrace-native-biarch.sh run-backtrace-nati