summaryrefslogtreecommitdiff
path: root/gcc/ada/init.c
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2015-11-13 12:14:34 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2015-11-13 12:14:34 +0100
commit7dae9ca0a92cd1c1d03f9a37271e47a84c6c79ef (patch)
tree64490512a4d76256ca385ffe7e6abe4cc2894a04 /gcc/ada/init.c
parent9babab64280b4e2c86be70896ba73b11e1908663 (diff)
downloadgcc-7dae9ca0a92cd1c1d03f9a37271e47a84c6c79ef.tar.gz
[multiple changes]
2015-11-13 Eric Botcazou <ebotcazou@adacore.com> * init.c [Darwin/arm64] (__gnat_sigtramp): Do not increment PC, fix CFI and add return sequence. 2015-11-13 Ed Schonberg <schonberg@adacore.com> * exp_fixd.adb (Expand_Convert_Float_To_Fixed): If the conversion comes from an attribute reference 'Round, the operation must round and not truncate. * sem_res.adb, sem_ch6.adb: Minor editing. From-SVN: r230302
Diffstat (limited to 'gcc/ada/init.c')
-rw-r--r--gcc/ada/init.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 4acf1a29015..65761b01873 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -2301,8 +2301,8 @@ char __gnat_alternate_stack[32 * 1024]; /* 1 * MINSIGSTKSZ */
#include <sys/ucontext.h>
/* Trampoline inserted before raising the exception. It modifies the
- stack so that PROC (D, M) looks to be called from the fault point. Note
- that LR may be incorrectly set. */
+ stack so that it looks to be called directly from the fault point.
+ Note that LR may be incorrectly restored by unwinding. */
void __gnat_sigtramp (struct Exception_Data *d, const char *m,
mcontext_t ctxt,
void (*proc)(struct Exception_Data *, const char *));
@@ -2323,17 +2323,19 @@ asm("\n"
" ldp q12, q13, [x2, #480]\n"
" ldp q14, q15, [x2, #512]\n"
/* Read FP from mcontext. */
-" ldp fp, lr, [x2, #248]\n"
+" ldr fp, [x2, #248]\n"
/* Read SP and PC from mcontext. */
-" ldp x6, x7, [x2, #264]\n"
-" add lr, x7, #1\n"
+" ldp x6, lr, [x2, #264]\n"
" mov sp, x6\n"
- /* Create a standard frame. */
+ /* Create a minimal frame. */
" stp fp, lr, [sp, #-16]!\n"
-" .cfi_def_cfa w29, 16\n"
-" .cfi_offset w30, -8\n"
-" .cfi_offset w29, -16\n"
-" br x3\n"
+" .cfi_def_cfa_offset 16\n"
+" .cfi_offset 30, -8\n"
+" .cfi_offset 29, -16\n"
+" blr x3\n"
+ /* Release our frame and return (should never get here!). */
+" ldp fp, lr, [sp, #16]\n"
+" ret\n"
" .cfi_endproc\n"
);
#endif
@@ -2416,6 +2418,9 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
uc->uc_mcontext->__ss.__rbx = uc->uc_mcontext->__ss.__rdx;
uc->uc_mcontext->__ss.__rdx = t;
}
+#elif defined(__arm64__)
+ ucontext_t *uc = (ucontext_t *)ucontext;
+ uc->uc_mcontext->__ss.__pc++;
#endif
}
@@ -2447,6 +2452,16 @@ __gnat_error_handler (int sig, siginfo_t *si, void *ucontext)
syscall (SYS_sigreturn, NULL, UC_RESET_ALT_STACK);
#ifdef __arm64__
+ /* ??? Temporary kludge to make stack checking work. The problem is
+ that the trampoline doesn't restore LR and, consequently, doesn't
+ make it possible to unwind past an interrupted frame which hasn"t
+ saved LR on the stack yet. */
+ if (__gnat_is_stack_guard ((unsigned long)si->si_addr))
+ {
+ ucontext_t *uc = (ucontext_t *)ucontext;
+ uc->uc_mcontext->__ss.__pc = uc->uc_mcontext->__ss.__lr;
+ }
+
/* On arm64, use a trampoline so that the unwinder won't see the
signal frame. */
__gnat_sigtramp (exception, msg,