diff options
author | myfreeweb <greg@unrelenting.technology> | 2018-08-07 18:05:44 +0300 |
---|---|---|
committer | Dave Watson <davejwatson@fb.com> | 2018-08-07 08:05:44 -0700 |
commit | fe2e9438e8089828965d1d0e28028d7eb35a55d5 (patch) | |
tree | ca57966a960a489dd8279b594520ad21fa8148fd | |
parent | 55ef85c50e4184c98c03e0c52ffb1c39b5201fab (diff) | |
download | libunwind-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.h | 11 | ||||
-rw-r--r-- | src/aarch64/unwind_i.h | 2 | ||||
-rw-r--r-- | src/coredump/_UCD_access_reg_freebsd.c | 20 | ||||
-rw-r--r-- | src/ptrace/_UPT_access_fpreg.c | 7 |
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 |