From 67fb02721cbd846c8cc13a18e071cbf9c4dd1c1c Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Fri, 5 Aug 2022 12:41:07 +0300 Subject: Fix __SOFTFP__ case for arm getcontext --- include/libunwind-arm.h | 41 ++++++++++++++++++++++++----------------- src/dwarf/Gfind_proc_info-lsb.c | 2 +- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/include/libunwind-arm.h b/include/libunwind-arm.h index c4b90fdd..4ac1fd38 100644 --- a/include/libunwind-arm.h +++ b/include/libunwind-arm.h @@ -46,7 +46,7 @@ extern "C" { require recompiling all users of this library. Stack allocation is relatively cheap and unwind-state copying is relatively rare, so we want to err on making it rather too big than too small. */ - + /* FIXME for ARM. Too big? What do other things use for similar tasks? */ #define UNW_TDEP_CURSOR_LEN 4096 @@ -73,7 +73,7 @@ typedef enum UNW_ARM_R13, UNW_ARM_R14, UNW_ARM_R15, - + /* VFPv2 s0-s31 (obsolescent numberings). */ UNW_ARM_S0 = 64, UNW_ARM_S1, @@ -107,7 +107,7 @@ typedef enum UNW_ARM_S29, UNW_ARM_S30, UNW_ARM_S31, - + /* FPA register numberings. */ UNW_ARM_F0 = 96, UNW_ARM_F1, @@ -117,7 +117,7 @@ typedef enum UNW_ARM_F5, UNW_ARM_F6, UNW_ARM_F7, - + /* iWMMXt GR register numberings. */ UNW_ARM_wCGR0 = 104, UNW_ARM_wCGR1, @@ -127,7 +127,7 @@ typedef enum UNW_ARM_wCGR5, UNW_ARM_wCGR6, UNW_ARM_wCGR7, - + /* iWMMXt register numberings. */ UNW_ARM_wR0 = 112, UNW_ARM_wR1, @@ -145,9 +145,9 @@ typedef enum UNW_ARM_wR13, UNW_ARM_wR14, UNW_ARM_wR15, - + /* Two-byte encodings from here on. */ - + /* SPSR. */ UNW_ARM_SPSR = 128, UNW_ARM_SPSR_FIQ, @@ -155,7 +155,7 @@ typedef enum UNW_ARM_SPSR_ABT, UNW_ARM_SPSR_UND, UNW_ARM_SPSR_SVC, - + /* User mode registers. */ UNW_ARM_R8_USR = 144, UNW_ARM_R9_USR, @@ -164,7 +164,7 @@ typedef enum UNW_ARM_R12_USR, UNW_ARM_R13_USR, UNW_ARM_R14_USR, - + /* FIQ registers. */ UNW_ARM_R8_FIQ = 151, UNW_ARM_R9_FIQ, @@ -173,23 +173,23 @@ typedef enum UNW_ARM_R12_FIQ, UNW_ARM_R13_FIQ, UNW_ARM_R14_FIQ, - + /* IRQ registers. */ UNW_ARM_R13_IRQ = 158, UNW_ARM_R14_IRQ, - + /* ABT registers. */ UNW_ARM_R13_ABT = 160, UNW_ARM_R14_ABT, - + /* UND registers. */ UNW_ARM_R13_UND = 162, UNW_ARM_R14_UND, - + /* SVC registers. */ UNW_ARM_R13_SVC = 164, UNW_ARM_R14_SVC, - + /* iWMMXt control registers. */ UNW_ARM_wC0 = 192, UNW_ARM_wC1, @@ -269,6 +269,13 @@ unw_tdep_context_t; may be sufficient for all libunwind use cases. In thumb mode, we return directly back to thumb mode on return (with bx), to avoid altering any registers after unw_resume. */ + +#ifdef __SOFTFP__ +#define VSTMIA "nop\n" /* align return address to value stored by stmia */ +#else +#define VSTMIA "vstmia %[base], {d0-d15}\n" /* this also aligns return address to value stored by stmia */ +#endif + #ifndef __thumb__ #define unw_tdep_getcontext(uc) ({ \ unw_tdep_context_t *unw_ctx = (uc); \ @@ -277,7 +284,7 @@ unw_tdep_context_t; __asm__ __volatile__ ( \ "mov r0, #0\n" \ "stmia %[base]!, {r0-r15}\n" \ - "vstmia %[base], {d0-d15}\n" /* this also aligns return address to value stored by stmia */ \ + VSTMIA \ : [r0] "=r" (r0) : [base] "r" (unw_base) : "memory"); \ (int)r0; }) #else /* __thumb__ */ @@ -294,13 +301,13 @@ unw_tdep_context_t; "stmia %[base], {r0-r14}\n" \ "adr r0, ret%=+1\n" \ "stmia %[base]!, {r0}\n" \ - "vstmia %[base], {d0-d15}\n" \ + VSTMIA \ "orr r0, pc, #1\n" \ "bx r0\n" \ ".code 16\n" \ "mov r0, #0\n" \ "ret%=:\n" \ - : [r0] "=r" (r0), [base] "+r" (unw_base) : : "memory", "cc"); \ + : [r0] "=r" (r0), [base] "+r" (unw_base) : : "memory", "cc"); \ (int)r0; }) #endif diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c index 196cfca3..8ead48f0 100644 --- a/src/dwarf/Gfind_proc_info-lsb.c +++ b/src/dwarf/Gfind_proc_info-lsb.c @@ -135,9 +135,9 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, #if defined(SHF_COMPRESSED) if (shdr->sh_flags & SHF_COMPRESSED) { - unsigned long destSize; Elf_W (Chdr) *chdr = (shdr->sh_offset + ei.image); #ifdef HAVE_ZLIB + unsigned long destSize; if (chdr->ch_type == ELFCOMPRESS_ZLIB) { *bufsize = destSize = chdr->ch_size; -- cgit v1.2.1