summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormyfreeweb <greg@unrelenting.technology>2018-08-07 18:05:44 +0300
committerDave Watson <davejwatson@fb.com>2018-08-07 08:05:44 -0700
commitfe2e9438e8089828965d1d0e28028d7eb35a55d5 (patch)
treeca57966a960a489dd8279b594520ad21fa8148fd
parent55ef85c50e4184c98c03e0c52ffb1c39b5201fab (diff)
downloadlibunwind-fe2e9438e8089828965d1d0e28028d7eb35a55d5.tar.gz
aarch64: fix freebsd support
implement _UPT_access_fpreg, _UCD_access_reg_freebsd for aarch64, and add a unw_fpsimd_context_t instead of using the one from the linux headers.
-rw-r--r--include/libunwind-aarch64.h11
-rw-r--r--src/aarch64/unwind_i.h2
-rw-r--r--src/coredump/_UCD_access_reg_freebsd.c20
-rw-r--r--src/ptrace/_UPT_access_fpreg.c7
4 files changed, 39 insertions, 1 deletions
diff --git a/include/libunwind-aarch64.h b/include/libunwind-aarch64.h
index 11e2a9c1..c97be5d5 100644
--- a/include/libunwind-aarch64.h
+++ b/include/libunwind-aarch64.h
@@ -196,6 +196,17 @@ typedef struct
struct unw_sigcontext uc_mcontext;
} unw_tdep_context_t;
+typedef struct
+ {
+ uint32_t _ctx_magic;
+ uint32_t _ctx_size;
+ uint32_t fpsr;
+ uint32_t fpcr;
+ uint64_t vregs[64];
+ } unw_fpsimd_context_t;
+
+
+
#include "libunwind-common.h"
#include "libunwind-dynamic.h"
diff --git a/src/aarch64/unwind_i.h b/src/aarch64/unwind_i.h
index 3d324c2b..db7e29dd 100644
--- a/src/aarch64/unwind_i.h
+++ b/src/aarch64/unwind_i.h
@@ -59,6 +59,6 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
} while (0)
#endif
-#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved))
+#define GET_FPCTX(uc) ((unw_fpsimd_context_t *)(&uc->uc_mcontext.__reserved))
#endif /* unwind_i_h */
diff --git a/src/coredump/_UCD_access_reg_freebsd.c b/src/coredump/_UCD_access_reg_freebsd.c
index 0e3a83bd..930a1148 100644
--- a/src/coredump/_UCD_access_reg_freebsd.c
+++ b/src/coredump/_UCD_access_reg_freebsd.c
@@ -129,6 +129,26 @@ _UCD_access_reg (unw_addr_space_t as,
return -UNW_EINVAL;
}
}
+#elif defined(UNW_TARGET_AARCH64)
+ if (regnum >= UNW_AARCH64_X0 && regnum < UNW_AARCH64_X30) {
+ *valp = ui->prstatus->pr_reg.x[regnum];
+ } else {
+ switch (regnum) {
+ case UNW_AARCH64_SP:
+ *valp = ui->prstatus->pr_reg.sp;
+ break;
+ case UNW_AARCH64_X30:
+ *valp = ui->prstatus->pr_reg.lr;
+ break;
+ case UNW_AARCH64_PC:
+ *valp = ui->prstatus->pr_reg.elr;
+ break;
+ default:
+ Debug(0, "bad regnum:%d\n", regnum);
+ return -UNW_EINVAL;
+ }
+ }
+
#else
#error Port me
#endif
diff --git a/src/ptrace/_UPT_access_fpreg.c b/src/ptrace/_UPT_access_fpreg.c
index 2b92462f..37cd4ffe 100644
--- a/src/ptrace/_UPT_access_fpreg.c
+++ b/src/ptrace/_UPT_access_fpreg.c
@@ -84,6 +84,9 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
#elif defined(__arm__)
if ((unsigned) reg < UNW_ARM_F0 || (unsigned) reg > UNW_ARM_F7)
return -UNW_EBADREG;
+#elif defined(__aarch64__)
+ if ((unsigned) reg < UNW_AARCH64_V0 || (unsigned) reg > UNW_AARCH64_V31)
+ return -UNW_EBADREG;
#else
#error Fix me
#endif
@@ -99,6 +102,8 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t));
#elif defined(__arm__)
memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t));
+#elif defined(__aarch64__)
+ memcpy(&fpreg.fp_q[reg], val, sizeof(unw_fpreg_t));
#else
#error Fix me
#endif
@@ -111,6 +116,8 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t));
#elif defined(__arm__)
memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t));
+#elif defined(__aarch64__)
+ memcpy(val, &fpreg.fp_q[reg], sizeof(unw_fpreg_t));
#else
#error Fix me
#endif