From 6672e402095eb9df8517918c58929c145b9c1bc2 Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Fri, 13 Nov 2015 14:11:30 +0100 Subject: [PATCH] [multiple changes] 2015-11-13 Bob Duff * sem_ch6.adb (Check_Private_Overriding): Change name of Parent_Is_Private to be Overrides_Private_Part_Op, and use Unit_Declaration_Node. 2015-11-13 Bob Duff * sinfo.ads: Minor comment fix. * sem_ch6.adb: Minor reformatting. 2015-11-13 Jerome Lambourg * tracebak.c: Do not use the GCC Unwinder to retrieve traceback for x86_64-vx7. 2015-11-13 Eric Botcazou * init.c [Darwin/arm64]: Fix typo. * sigtramp-armios.c: Remove. * sigtramp-ios.c: New file. 2015-11-13 Doug Rupp * s-stchop-vxworks.adb (Set_Stack_Limit_For_Current_Task): Set stack limit to 12000 decimal vice 12000 hexadecimal. From-SVN: r230315 --- gcc/ada/ChangeLog | 27 ++++ gcc/ada/init.c | 28 +++-- gcc/ada/s-stchop-vxworks.adb | 4 +- gcc/ada/sem_ch6.adb | 45 ++++--- gcc/ada/sigtramp-armios.c | 98 --------------- gcc/ada/sigtramp-ios.c | 233 +++++++++++++++++++++++++++++++++++ gcc/ada/sinfo.ads | 2 +- gcc/ada/tracebak.c | 2 +- 8 files changed, 309 insertions(+), 130 deletions(-) delete mode 100644 gcc/ada/sigtramp-armios.c create mode 100644 gcc/ada/sigtramp-ios.c diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d34ba295968..1fa08b96111 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,30 @@ +2015-11-13 Bob Duff + + * sem_ch6.adb (Check_Private_Overriding): Change + name of Parent_Is_Private to be Overrides_Private_Part_Op, + and use Unit_Declaration_Node. + +2015-11-13 Bob Duff + + * sinfo.ads: Minor comment fix. + * sem_ch6.adb: Minor reformatting. + +2015-11-13 Jerome Lambourg + + * tracebak.c: Do not use the GCC Unwinder to retrieve traceback + for x86_64-vx7. + +2015-11-13 Eric Botcazou + + * init.c [Darwin/arm64]: Fix typo. + * sigtramp-armios.c: Remove. + * sigtramp-ios.c: New file. + +2015-11-13 Doug Rupp + + * s-stchop-vxworks.adb (Set_Stack_Limit_For_Current_Task): Set stack + limit to 12000 decimal vice 12000 hexadecimal. + 2015-11-13 Hristian Kirtchev * exp_ch9.adb, exp_fixd.adb, exp_util.adb, g-debpoo.adb, diff --git a/gcc/ada/init.c b/gcc/ada/init.c index dcd5c3d0642..4e95614a2f5 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -2381,13 +2381,14 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, uc->uc_mcontext->__ss.__rdx = t; } #elif defined(__arm64__) + /* Even though the CFI is marked as a signal frame, we need this. */ ucontext_t *uc = (ucontext_t *)ucontext; uc->uc_mcontext->__ss.__pc++; #endif } static void -__gnat_map_signal (int sig, siginfo_t *si, void *ucontext ATTRIBUTE_UNUSED) +__gnat_map_signal (int sig, siginfo_t *si, void *mcontext ATTRIBUTE_UNUSED) { struct Exception_Data *exception; const char *msg; @@ -2398,6 +2399,17 @@ __gnat_map_signal (int sig, siginfo_t *si, void *ucontext ATTRIBUTE_UNUSED) case SIGBUS: if (__gnat_is_stack_guard ((unsigned long)si->si_addr)) { +#ifdef __arm64__ + /* ??? This is a 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. Therefore, for probes in the prologue + (32-bit probes as opposed to standard 64-bit probes), we make the + unwinder skip the not-yet-established frame altogether. */ + mcontext_t mc = (mcontext_t)mcontext; + if (!(*(unsigned int *)(mc->__ss.__pc-1) & ((unsigned int)1 << 30))) + mc->__ss.__pc = mc->__ss.__lr; +#endif exception = &storage_error; msg = "stack overflow"; } @@ -2409,7 +2421,7 @@ __gnat_map_signal (int sig, siginfo_t *si, void *ucontext ATTRIBUTE_UNUSED) /* Reset the use of alt stack, so that the alt stack will be used for the next signal delivery. - The stack can't be used in case of stack checking. */ + The stack can't be used in case of stack checking. */ syscall (SYS_sigreturn, NULL, UC_RESET_ALT_STACK); break; @@ -2432,17 +2444,7 @@ __gnat_error_handler (int sig, siginfo_t *si, void *ucontext) __gnat_adjust_context_for_raise (sig, ucontext); #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; - } - - /* Use a trampoline so that the unwinder won't see the signal frame. */ + /* Use a trampoline so that the unwinder won't see the signal frame. */ __gnat_sigtramp (sig, (void *)si, ucontext, (__sigtramphandler_t *)&__gnat_map_signal); #else diff --git a/gcc/ada/s-stchop-vxworks.adb b/gcc/ada/s-stchop-vxworks.adb index 8afa535a643..24de94d91af 100644 --- a/gcc/ada/s-stchop-vxworks.adb +++ b/gcc/ada/s-stchop-vxworks.adb @@ -133,11 +133,11 @@ package body System.Stack_Checking.Operations is if Stack_Grows_Down then Limit := Stack_Info.Base - Storage_Offset (Stack_Info.Size) + - Storage_Offset'(16#12_000#); + Storage_Offset'(12_000); else Limit := Stack_Info.Base + Storage_Offset (Stack_Info.Size) - - Storage_Offset'(16#12_000#); + Storage_Offset'(12_000); end if; Stack_Limit := Limit; diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index abc125680a7..3eb22f67ee5 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -8753,16 +8753,38 @@ package body Sem_Ch6 is ------------------------------ procedure Check_Private_Overriding (T : Entity_Id) is + function Overrides_Private_Part_Op return Boolean; + -- This detects the special case where the overriding subprogram + -- is overriding a subprogram that was declared in the same + -- private part. That case is illegal by 3.9.3(10). function Overrides_Visible_Function (Partial_View : Entity_Id) return Boolean; -- True if S overrides a function in the visible part. The -- overridden function could be explicitly or implicitly declared. - function Parent_Is_Private return Boolean; - -- This detects the special case where the overriding subprogram - -- is overriding a subprogram that was declared in the same - -- private part. That case is illegal by 3.9.3(10). + ------------------------------- + -- Overrides_Private_Part_Op -- + ------------------------------- + + function Overrides_Private_Part_Op return Boolean is + Over_Decl : constant Node_Id := + Unit_Declaration_Node (Overridden_Operation (S)); + Subp_Decl : constant Node_Id := Unit_Declaration_Node (S); + + begin + pragma Assert (Is_Overriding); + pragma Assert + (Nkind (Over_Decl) = N_Abstract_Subprogram_Declaration); + pragma Assert + (Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration); + + return In_Same_List (Over_Decl, Subp_Decl); + end Overrides_Private_Part_Op; + + -------------------------------- + -- Overrides_Visible_Function -- + -------------------------------- function Overrides_Visible_Function (Partial_View : Entity_Id) return Boolean @@ -8802,14 +8824,6 @@ package body Sem_Ch6 is return False; end Overrides_Visible_Function; - function Parent_Is_Private return Boolean is - S_Decl : constant Node_Id := Parent (Parent (S)); - Overridden_Decl : constant Node_Id := - Parent (Parent (Overridden_Operation (S))); - begin - return In_Same_List (Overridden_Decl, S_Decl); - end Parent_Is_Private; - -- Start of processing for Check_Private_Overriding begin @@ -8822,10 +8836,11 @@ package body Sem_Ch6 is and then Is_Abstract_Subprogram (S) and then (not Is_Overriding or else not Is_Abstract_Subprogram (E) - or else Parent_Is_Private) + or else Overrides_Private_Part_Op) then - Error_Msg_N ("abstract subprograms must be visible " - & "(RM 3.9.3(10))!", S); + Error_Msg_N + ("abstract subprograms must be visible (RM 3.9.3(10))!", + S); elsif Ekind (S) = E_Function then declare diff --git a/gcc/ada/sigtramp-armios.c b/gcc/ada/sigtramp-armios.c deleted file mode 100644 index 3206256ac59..00000000000 --- a/gcc/ada/sigtramp-armios.c +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - * * - * GNAT COMPILER COMPONENTS * - * * - * S I G T R A M P * - * * - * Asm Implementation File * - * * - * Copyright (C) 2015, Free Software Foundation, Inc. * - * * - * GNAT is free software; you can redistribute it and/or modify it under * - * terms of the GNU General Public License as published by the Free Soft- * - * ware Foundation; either version 3, or (at your option) any later ver- * - * sion. GNAT is distributed in the hope that it will be useful, but WITH- * - * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * - * or FITNESS FOR A PARTICULAR PURPOSE. * - * * - * As a special exception under Section 7 of GPL version 3, you are granted * - * additional permissions described in the GCC Runtime Library Exception, * - * version 3.1, as published by the Free Software Foundation. * - * * - * In particular, you can freely distribute your programs built with the * - * GNAT Pro compiler, including any required library run-time units, using * - * any licensing terms of your choosing. See the AdaCore Software License * - * for full details. * - * * - * GNAT was originally developed by the GNAT team at New York University. * - * Extensive contributions were provided by Ada Core Technologies Inc. * - * * - ****************************************************************************/ - -/************************************************** - * ARM-IOS version of the __gnat_sigtramp service * - **************************************************/ - -#include - -#include "sigtramp.h" -/* See sigtramp.h for a general explanation of functionality. */ - -/* ----------------------------------------- - -- Protypes for our internal asm stubs -- - ----------------------------------------- - - The registers are expected to be at SIGCONTEXT + OFFSET (reference to the - machine context structure). Even though our symbols will remain local, the - prototype claims "extern" and not "static" to prevent compiler complaints - about a symbol used but never defined. */ - -/* sigtramp stub providing unwind info for common registers. */ - -extern void __gnat_sigtramp_common - (int signo, void *siginfo, void *sigcontext, - __sigtramphandler_t * handler); - -void __gnat_sigtramp (int signo, void *si, void *ucontext, - __sigtramphandler_t * handler) - __attribute__((optimize(2))); - -void __gnat_sigtramp (int signo, void *si, void *ucontext, - __sigtramphandler_t * handler) -{ - mcontext_t mcontext = ((ucontext_t *) ucontext)->uc_mcontext; - - __gnat_sigtramp_common (signo, si, mcontext, handler); -} - -asm("\n" -" .section __TEXT,__text,regular,pure_instructions\n" -" .align 2\n" -"___gnat_sigtramp_common:\n" -" .cfi_startproc\n" - /* Restore callee saved registers. */ -" ldp x19, x20, [x2, #168]\n" -" ldp x21, x22, [x2, #184]\n" -" ldp x23, x24, [x2, #200]\n" -" ldp x25, x26, [x2, #216]\n" -" ldp x27, x28, [x2, #232]\n" -" ldp q8, q9, [x2, #416]\n" -" ldp q10, q11, [x2, #448]\n" -" ldp q12, q13, [x2, #480]\n" -" ldp q14, q15, [x2, #512]\n" - /* Read FP from mcontext. */ -" ldr fp, [x2, #248]\n" - /* Read SP and PC from mcontext. */ -" ldp x6, lr, [x2, #264]\n" -" mov sp, x6\n" - /* Create a minimal frame. */ -" stp fp, lr, [sp, #-16]!\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" -); diff --git a/gcc/ada/sigtramp-ios.c b/gcc/ada/sigtramp-ios.c new file mode 100644 index 00000000000..36c4f871791 --- /dev/null +++ b/gcc/ada/sigtramp-ios.c @@ -0,0 +1,233 @@ +/**************************************************************************** + * * + * GNAT COMPILER COMPONENTS * + * * + * S I G T R A M P * + * * + * Asm Implementation File * + * * + * Copyright (C) 2015, Free Software Foundation, Inc. * + * * + * GNAT is free software; you can redistribute it and/or modify it under * + * terms of the GNU General Public License as published by the Free Soft- * + * ware Foundation; either version 3, or (at your option) any later ver- * + * sion. GNAT is distributed in the hope that it will be useful, but WITH- * + * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. * + * * + * As a special exception under Section 7 of GPL version 3, you are granted * + * additional permissions described in the GCC Runtime Library Exception, * + * version 3.1, as published by the Free Software Foundation. * + * * + * In particular, you can freely distribute your programs built with the * + * GNAT Pro compiler, including any required library run-time units, using * + * any licensing terms of your choosing. See the AdaCore Software License * + * for full details. * + * * + * GNAT was originally developed by the GNAT team at New York University. * + * Extensive contributions were provided by Ada Core Technologies Inc. * + * * + ****************************************************************************/ + +/**************************************************** + * ARM64/IOS version of the __gnat_sigtramp service * + ****************************************************/ + +#include + +#include "sigtramp.h" +/* See sigtramp.h for a general explanation of functionality. */ + +/* ---------------------- + -- General comments -- + ---------------------- + + Unfortunately the libunwind library used on this platform comes with severe + limitations that make the implementation convoluted: + + 1. At each step, the stack pointer register SP is restored with the CFA. + This makes it impossible to set the CFA to an arbitrary value, for + example to the address of the context saved on the stack, which means + that the simple CFI directives cannot be used for the registers. + + 2. For the ARM64 architecture (and only it), DWARF expressions are not + supported to compute the CFA. Only DW_CFA_def_cfa is supported, which + means that the CFA (modulo offset) must be loaded into a register. + + 3. The return column cannot be changed (30 for the ARM64 architecture). + Since column 30 is that of the LR register, this makes it impossible + to restore both the LR register and the PC. + + Therefore we need 2 distinct call-saved registers in the trampoline and + we resort to manual encoding of CFI byte sequences. */ + +/* ----------------------------------------- + -- Protypes for our internal asm stubs -- + ----------------------------------------- + + Even though our symbols will remain local, the prototype claims "extern" + and not "static" to prevent compiler complaints about a symbol used but + never defined. */ + +/* sigtramp stub providing unwind info for common registers. */ + +extern void __gnat_sigtramp_common + (int signo, void *siginfo, void *sigcontext, + __sigtramphandler_t * handler); + +void __gnat_sigtramp (int signo, void *si, void *ucontext, + __sigtramphandler_t * handler) + __attribute__((optimize(2))); + +void __gnat_sigtramp (int signo, void *si, void *ucontext, + __sigtramphandler_t * handler) +{ + mcontext_t mcontext = ((ucontext_t *) ucontext)->uc_mcontext; + + __gnat_sigtramp_common (signo, si, mcontext, handler); +} + +/* asm string construction helpers. */ + +#define STR(TEXT) #TEXT +/* stringify expanded TEXT, surrounding it with double quotes. */ + +#define S(E) STR(E) +/* stringify E, which will resolve as text but may contain macros + still to be expanded. */ + +/* asm (TEXT) outputs TEXT. These facilitate the output of + multiline contents: */ +#define TAB(S) "\t" S +#define CR(S) S "\n" + +#undef TCR +#define TCR(S) TAB(CR(S)) + +/* Offset in uc_mcontext of the __ss structure containing the registers. */ +#define UC_MCONTEXT_SS 16 + +#define CFA_REG 19 +#define BASE_REG 20 + +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_expression 0x10 + +#define DW_OP_breg(n) 0x70+(n) + +#define REG_REGNO_GR(n) n +#define REG_REGNO_PC 30 + +/* The first byte of the SLEB128 value of the offset. */ +#define REG_OFFSET_GR(n) (UC_MCONTEXT_SS + n * 8) +#define REG_OFFSET_LONG_GR(n) (UC_MCONTEXT_SS + n * 8 + 128) +#define REG_OFFSET_LONG128_GR(n) (UC_MCONTEXT_SS + (n - 16) * 8 + 128) +#define REG_OFFSET_LONG256_GR(n) (UC_MCONTEXT_SS + (n - 32) * 8 + 128) + +#define REG_OFFSET_LONG256_PC REG_OFFSET_LONG256_GR(32) + +#define CFI_DEF_CFA \ + TCR(".cfi_def_cfa " S(CFA_REG) ", 0") + +/* We need 4 variants depending on the offset: 0+, 64+, 128+, 256+. */ +#define COMMON_CFI(REG) \ + ".cfi_escape " S(DW_CFA_expression) "," S(REG_REGNO_##REG) ",2," \ + S(DW_OP_breg(BASE_REG)) "," S(REG_OFFSET_##REG) + +#define COMMON_LONG_CFI(REG) \ + ".cfi_escape " S(DW_CFA_expression) "," S(REG_REGNO_##REG) ",3," \ + S(DW_OP_breg(BASE_REG)) "," S(REG_OFFSET_LONG_##REG) ",0" + +#define COMMON_LONG128_CFI(REG) \ + ".cfi_escape " S(DW_CFA_expression) "," S(REG_REGNO_##REG) ",3," \ + S(DW_OP_breg(BASE_REG)) "," S(REG_OFFSET_LONG128_##REG) ",1" + +#define COMMON_LONG256_CFI(REG) \ + ".cfi_escape " S(DW_CFA_expression) "," S(REG_REGNO_##REG) ",3," \ + S(DW_OP_breg(BASE_REG)) "," S(REG_OFFSET_LONG256_##REG) ",2" + +#define CFI_COMMON_REGS \ + CR("# CFI for common registers\n") \ + TCR(COMMON_CFI(GR(0))) \ + TCR(COMMON_CFI(GR(1))) \ + TCR(COMMON_CFI(GR(2))) \ + TCR(COMMON_CFI(GR(3))) \ + TCR(COMMON_CFI(GR(4))) \ + TCR(COMMON_CFI(GR(5))) \ + TCR(COMMON_LONG_CFI(GR(6))) \ + TCR(COMMON_LONG_CFI(GR(7))) \ + TCR(COMMON_LONG_CFI(GR(8))) \ + TCR(COMMON_LONG_CFI(GR(9))) \ + TCR(COMMON_LONG_CFI(GR(10))) \ + TCR(COMMON_LONG_CFI(GR(11))) \ + TCR(COMMON_LONG_CFI(GR(12))) \ + TCR(COMMON_LONG_CFI(GR(13))) \ + TCR(COMMON_LONG128_CFI(GR(14))) \ + TCR(COMMON_LONG128_CFI(GR(15))) \ + TCR(COMMON_LONG128_CFI(GR(16))) \ + TCR(COMMON_LONG128_CFI(GR(17))) \ + TCR(COMMON_LONG128_CFI(GR(18))) \ + TCR(COMMON_LONG128_CFI(GR(19))) \ + TCR(COMMON_LONG128_CFI(GR(20))) \ + TCR(COMMON_LONG128_CFI(GR(21))) \ + TCR(COMMON_LONG128_CFI(GR(22))) \ + TCR(COMMON_LONG128_CFI(GR(23))) \ + TCR(COMMON_LONG128_CFI(GR(24))) \ + TCR(COMMON_LONG128_CFI(GR(25))) \ + TCR(COMMON_LONG128_CFI(GR(26))) \ + TCR(COMMON_LONG128_CFI(GR(27))) \ + TCR(COMMON_LONG128_CFI(GR(28))) \ + TCR(COMMON_LONG128_CFI(GR(29))) \ + TCR(COMMON_LONG256_CFI(PC)) \ + +/* Trampoline body block + --------------------- */ + +#define SIGTRAMP_BODY \ + TCR("stp fp, lr, [sp, #-32]!") \ + TCR("stp x" S(CFA_REG) ", x" S(BASE_REG) ", [sp, #16]") \ + TCR("mov fp, sp") \ + TCR("# Load the saved value of the stack pointer as CFA") \ + TCR("ldr x" S(CFA_REG) ", [x2, #" S(REG_OFFSET_GR(31)) "]") \ + TCR("# Use x" S(BASE_REG) " as base register for the CFI") \ + TCR("mov x" S(BASE_REG) ", x2") \ + TCR("# Call the handler") \ + TCR("blr x3") \ + TCR("# Release our frame and return (should never get here!).") \ + TCR("ldp x" S(CFA_REG) ", x" S(BASE_REG)" , [sp, #16]") \ + TCR("ldp fp, lr, [sp], 32") \ + TCR("ret") + +/* ----------------------------- + -- Symbol definition block -- + ----------------------------- */ + +#define SIGTRAMP_START(SYM) \ + CR("# " S(SYM) " signal trampoline") \ + CR(S(SYM) ":") \ + TCR(".cfi_startproc") \ + TCR(".cfi_signal_frame") + +/* ------------------------------ + -- Symbol termination block -- + ------------------------------ */ + +#define SIGTRAMP_END(SYM) \ + TCR(".cfi_endproc") + +/*---------------------------- + -- And now, the real code -- + ---------------------------- */ + +asm(".text\n" + TCR(".align 2")); + +/* sigtramp stub for common registers. */ + +#define TRAMP_COMMON ___gnat_sigtramp_common + +asm (SIGTRAMP_START(TRAMP_COMMON)); +asm (CFI_DEF_CFA); +asm (CFI_COMMON_REGS); +asm (SIGTRAMP_BODY); +asm (SIGTRAMP_END(TRAMP_COMMON)); diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads index 4b18de97f92..4ef11a31e8e 100644 --- a/gcc/ada/sinfo.ads +++ b/gcc/ada/sinfo.ads @@ -750,7 +750,7 @@ package Sinfo is -- to be sure to raise an ABE. This is used to trigger special handling -- of such cases, particularly in the instantiation case where we avoid -- instantiating the body if this flag is set. This flag is also present - -- in an N_Formal_Package_Declaration_Node since formal package + -- in an N_Formal_Package_Declaration node since formal package -- declarations are treated like instantiations, but it is always set to -- False in this context. diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c index ff85ca5baf5..3f40ae40c18 100644 --- a/gcc/ada/tracebak.c +++ b/gcc/ada/tracebak.c @@ -433,7 +433,7 @@ struct layout but our only alternative is the generic unwinder which requires compilation forcing a frame pointer to be reliable. */ -#if (defined (__x86_64__) || defined (__linux__)) && !defined (__USING_SJLJ_EXCEPTIONS__) +#if (defined (__x86_64__) || defined (__linux__)) && !defined (__USING_SJLJ_EXCEPTIONS__) && !defined (__vxworks) #define USE_GCC_UNWINDER #else #define USE_GENERIC_UNWINDER -- 2.30.2