Hello,

Recently, I tried to print unwind info of a testcase on AARCH64 ILP32 (big 
endian) using libunwind.
By default, the support for AARCH64 ILP32 is not present in libunwind, the 
attached patch adds support
to print unwind info for AARCH64 ILP32 and enables to load .debug_frame for 
both AARCH64 and AARCH64 ILP32 inorder to display unwind info of __start 
procedure.

testcase: unwind.c

#define UNW_LOCAL_ONLY
#include<libunwind.h>
#include<stdio.h>
void show_backtrace (void) {
  unw_cursor_t cursor; unw_context_t uc;
  unw_word_t ip, sp, offt;
  char name [20];

  unw_getcontext(&uc);
  unw_init_local(&cursor, &uc);
  while (unw_step(&cursor) > 0) {
    unw_get_reg(&cursor, UNW_REG_IP, &ip);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);
    unw_get_proc_name(&cursor, name, 20, &offt);
    printf ("ip = %lx, sp = %lx", (long) ip, (long) sp);
    printf (", procedure = %s\n", name);
  }
}

void call_backtrace(void) {
  show_backtrace();
}

int main()
{
call_backtrace();
}

compile and excute commands on AARCH64:
gcc -mbig-endian -g -funwind-tables -I /usr/include/ -L /usr/lib64/ -lunwind 
-lunwind-aarch64 unwind.c -o unwind
./unwind

output:
ip = 400a5c, sp = 7fe06eea30, procedure = call_backtrace
ip = 400a70, sp = 7fe06eea40, procedure = main
ip = 7faa5d1788, sp = 7fe06eea50, procedure = __libc_start_main
ip = 40082c, sp = 7fe06eeb90, procedure = _start

Please let me know if any changes required.

Regards,
Jagadeesh

diff -Naurp libunwind_org/configure.ac libunwind/configure.ac
--- libunwind_org/configure.ac	2013-09-25 11:14:13.185065707 +0530
+++ libunwind/configure.ac	2013-09-25 11:15:10.389065985 +0530
@@ -157,8 +157,8 @@ AM_CONDITIONAL(OS_QNX, expr x$target_os
 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)    use_elf64=yes; AC_MSG_RESULT([64]);;
-(mips)                 use_elfxx=yes; AC_MSG_RESULT([xx]);;
+(ia64|ppc64|x86_64)    use_elf64=yes; AC_MSG_RESULT([64]);;
+(aarch64|mips)         use_elfxx=yes; AC_MSG_RESULT([xx]);;
 *)                     AC_MSG_ERROR([Unknown ELF target: ${target_arch}])
 esac
 AM_CONDITIONAL(USE_ELF32, [test x$use_elf32 = xyes])
@@ -221,6 +221,7 @@ AC_ARG_ENABLE(debug_frame,
 AS_HELP_STRING([--enable-debug-frame],[Load the ".debug_frame" section if available]),, [
 case "${target_arch}" in
   (arm) enable_debug_frame=yes;;
+  (aarch64*) enable_debug_frame=yes;;
   (*)   enable_debug_frame=no;;
 esac])
 if test x$enable_debug_frame = xyes; then
diff -Naurp libunwind_org/include/tdep-aarch64/dwarf-config.h libunwind/include/tdep-aarch64/dwarf-config.h
--- libunwind_org/include/tdep-aarch64/dwarf-config.h	2013-09-25 11:14:13.193065707 +0530
+++ libunwind/include/tdep-aarch64/dwarf-config.h	2013-09-25 11:15:10.389065985 +0530
@@ -35,6 +35,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
 #define dwarf_is_big_endian(addr_space)	0
 
 #define dwarf_to_unw_regnum(reg) (((reg) <= UNW_AARCH64_V31) ? (reg) : 0)
+#define dwarf_addr_size(addr_space) ((addr_space)->addr_size)
 
 /* Convert a pointer to a dwarf_cursor structure to a pointer to
    unw_cursor_t.  */
diff -Naurp libunwind_org/include/tdep-aarch64/libunwind_i.h libunwind/include/tdep-aarch64/libunwind_i.h
--- libunwind_org/include/tdep-aarch64/libunwind_i.h	2013-09-25 11:14:13.193065707 +0530
+++ libunwind/include/tdep-aarch64/libunwind_i.h	2013-09-25 11:15:10.389065985 +0530
@@ -33,7 +33,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
 #include <stdlib.h>
 #include <libunwind.h>
 
+#ifdef __LP64__
 #include "elf64.h"
+#else
+#include "elf32.h"
+#endif
 #include "mempool.h"
 #include "dwarf.h"
 
@@ -61,6 +65,7 @@ struct unw_addr_space
   {
     struct unw_accessors acc;
     int big_endian;
+    unsigned int addr_size;
     unw_caching_policy_t caching_policy;
 #ifdef HAVE_ATOMIC_OPS_H
     AO_t cache_generation;
diff -Naurp libunwind_org/src/aarch64/Ginit.c libunwind/src/aarch64/Ginit.c
--- libunwind_org/src/aarch64/Ginit.c	2013-09-25 11:14:13.181065707 +0530
+++ libunwind/src/aarch64/Ginit.c	2013-09-25 11:17:21.481066620 +0530
@@ -165,13 +165,18 @@ get_static_proc_name (unw_addr_space_t a
 		      char *buf, size_t buf_len, unw_word_t *offp,
 		      void *arg)
 {
+#ifdef __LP64__
   return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
+#else
+  return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
+#endif
 }
 
 HIDDEN void
 aarch64_local_addr_space_init (void)
 {
   memset (&local_addr_space, 0, sizeof (local_addr_space));
+  local_addr_space.addr_size = sizeof (void *);
   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;
diff -Naurp libunwind_org/src/Makefile.am libunwind/src/Makefile.am
--- libunwind_org/src/Makefile.am	2013-09-25 11:14:13.185065707 +0530
+++ libunwind/src/Makefile.am	2013-09-25 11:15:10.389065985 +0530
@@ -463,7 +463,7 @@ if ARCH_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
+ libunwind_aarch64_la_LIBADD += libunwind-elfxx.la
 if !REMOTE_ONLY
  libunwind_aarch64_la_LIBADD += libunwind.la -lc
 endif
_______________________________________________
Libunwind-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/libunwind-devel

Reply via email to