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