mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			[ARC] Fix to unwinding.
gcc/ChangeLog:
2017-11-03  Cupertino Miranda  <cmiranda@synopsys.com>
        * config/arc/arc.c (arc_save_restore): Corrected CFA note.
        (arc_expand_prologue): Restore blink for millicode.
        * config/arc/linux.h (LINK_EH_SPEC): Defined.
libgcc/ChangeLog:
2017-11-03  Cupertino Miranda  <cmiranda@synopsys.com>
            Vineet Gupta <vgupta@synopsys.com>
        * config.host (arc*-*-linux*): Set md_unwind_header variable.
        * config/arc/linux-unwind-reg.def: New file.
        * config/arc/linux-unwind.h: Likewise.
Co-Authored-By: Vineet Gupta <vgupta@synopsys.com>
From-SVN: r254367
			
			
This commit is contained in:
		
							parent
							
								
									a34a16abe5
								
							
						
					
					
						commit
						b0c7ddf816
					
				|  | @ -1,3 +1,9 @@ | |||
| 2017-11-03  Cupertino Miranda  <cmiranda@synopsys.com> | ||||
| 
 | ||||
| 	* config/arc/arc.c (arc_save_restore): Corrected CFA note. | ||||
| 	(arc_expand_prologue): Restore blink for millicode. | ||||
| 	* config/arc/linux.h (LINK_EH_SPEC): Defined. | ||||
| 
 | ||||
| 2017-11-03  Richard Sandiford  <richard.sandiford@linaro.org> | ||||
| 
 | ||||
| 	PR target/82809 | ||||
|  |  | |||
|  | @ -2823,12 +2823,23 @@ arc_save_restore (rtx base_reg, | |||
| 	  else | ||||
| 	    { | ||||
| 	      insn = frame_insn (insn); | ||||
| 	      if (epilogue_p) | ||||
| 		for (r = start_call; r <= end_call; r++) | ||||
| 		  { | ||||
| 		    rtx reg = gen_rtx_REG (SImode, r); | ||||
| 		    add_reg_note (insn, REG_CFA_RESTORE, reg); | ||||
| 		  } | ||||
| 	      for (r = start_call, off = 0; | ||||
| 		   r <= end_call; | ||||
| 		   r++, off += UNITS_PER_WORD) | ||||
| 		{ | ||||
| 		  rtx reg = gen_rtx_REG (SImode, r); | ||||
| 		  if (epilogue_p) | ||||
| 		      add_reg_note (insn, REG_CFA_RESTORE, reg); | ||||
| 		  else | ||||
| 		    { | ||||
| 		      rtx mem = gen_rtx_MEM (SImode, plus_constant (Pmode, | ||||
| 								    base_reg, | ||||
| 								    off)); | ||||
| 
 | ||||
| 		      add_reg_note (insn, REG_CFA_OFFSET, | ||||
| 				    gen_rtx_SET (mem, reg)); | ||||
| 		    } | ||||
| 		} | ||||
| 	    } | ||||
| 	  offset += off; | ||||
| 	} | ||||
|  | @ -3070,6 +3081,19 @@ arc_expand_prologue (void) | |||
|       frame_size_to_allocate -= cfun->machine->frame_info.reg_size; | ||||
|     } | ||||
| 
 | ||||
|   /* In the case of millicode thunk, we need to restore the clobbered
 | ||||
|      blink register.  */ | ||||
|   if (cfun->machine->frame_info.millicode_end_reg > 0 | ||||
|       && arc_must_save_return_addr (cfun)) | ||||
|     { | ||||
|       HOST_WIDE_INT tmp = cfun->machine->frame_info.reg_size; | ||||
|       emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), | ||||
| 			      gen_rtx_MEM (Pmode, | ||||
| 					   plus_constant (Pmode, | ||||
| 							  stack_pointer_rtx, | ||||
| 							  tmp)))); | ||||
|     } | ||||
| 
 | ||||
|   /* Save frame pointer if needed.  First save the FP on stack, if not
 | ||||
|      autosaved.  */ | ||||
|   if (arc_frame_pointer_needed () | ||||
|  |  | |||
|  | @ -91,3 +91,11 @@ along with GCC; see the file COPYING3.  If not see | |||
| /* Pre/post modify with register displacement are default off.  */ | ||||
| #undef TARGET_AUTO_MODIFY_REG_DEFAULT | ||||
| #define TARGET_AUTO_MODIFY_REG_DEFAULT 0 | ||||
| 
 | ||||
| #if DEFAULT_LIBC == LIBC_GLIBC | ||||
| /* Override linux.h LINK_EH_SPEC definition.
 | ||||
|    Signalize that because we have fde-glibc, we don't need all C shared libs | ||||
|    linked against -lgcc_s.  */ | ||||
| #undef LINK_EH_SPEC | ||||
| #define LINK_EH_SPEC "--eh-frame-hdr" | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,3 +1,10 @@ | |||
| 2017-11-03  Cupertino Miranda  <cmiranda@synopsys.com> | ||||
| 	    Vineet Gupta <vgupta@synopsys.com> | ||||
| 
 | ||||
| 	* config.host (arc*-*-linux*): Set md_unwind_header variable. | ||||
| 	* config/arc/linux-unwind-reg.def: New file. | ||||
| 	* config/arc/linux-unwind-reg.h: Likewise. | ||||
| 
 | ||||
| 2017-10-23  Sebastian Perta  <sebastian.perta@renesas.com> | ||||
| 
 | ||||
| 	* config/rl78/subdi3.S: New assembly file. | ||||
|  |  | |||
|  | @ -390,6 +390,7 @@ arc*-*-linux*) | |||
| 	tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc-uClibc arc/t-arc" | ||||
| 	extra_parts="$extra_parts crti.o crtn.o" | ||||
| 	extra_parts="$extra_parts crttls.o" | ||||
| 	md_unwind_header=arc/linux-unwind.h | ||||
| 	;; | ||||
| arm-wrs-vxworks|arm-wrs-vxworks7) | ||||
| 	tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp" | ||||
|  |  | |||
|  | @ -0,0 +1,42 @@ | |||
| /* Copyright (C) 2017 Free Software Foundation, Inc. | ||||
| 
 | ||||
|    This file is part of GCC. | ||||
| 
 | ||||
|    GCC is free software; you can redistribute it and/or modify it | ||||
|    under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation; either version 3, or (at your option) | ||||
|    any later version. | ||||
| 
 | ||||
|    GCC is distributed in the hope that it will be useful, but WITHOUT | ||||
|    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||||
|    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public | ||||
|    License for more details. | ||||
| 
 | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    along with GCC; see the file COPYING3.  If not see | ||||
|    <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
| 
 | ||||
| REGISTER_IN_STACK(bta, -1) | ||||
| REGISTER_IN_STACK(lp_start, -1) | ||||
| REGISTER_IN_STACK(lp_end, -1) | ||||
| REGISTER_IN_STACK(lp_count, -1) | ||||
| REGISTER_IN_STACK(status32, -1) | ||||
| REGISTER_IN_STACK(ret, -1) | ||||
| REGISTER_IN_STACK(blink, 31) | ||||
| REGISTER_IN_STACK(fp, 27) | ||||
| REGISTER_IN_STACK(gp, 26) | ||||
| REGISTER_IN_STACK(r12, 12) | ||||
| REGISTER_IN_STACK(r11, 11) | ||||
| REGISTER_IN_STACK(r10, 10) | ||||
| REGISTER_IN_STACK(r9, 9) | ||||
| REGISTER_IN_STACK(r8, 8) | ||||
| REGISTER_IN_STACK(r7, 7) | ||||
| REGISTER_IN_STACK(r6, 6) | ||||
| REGISTER_IN_STACK(r5, 5) | ||||
| REGISTER_IN_STACK(r4, 4) | ||||
| REGISTER_IN_STACK(r3, 3) | ||||
| REGISTER_IN_STACK(r2, 2) | ||||
| REGISTER_IN_STACK(r1, 1) | ||||
| REGISTER_IN_STACK(r0, 0) | ||||
| REGISTER_IN_STACK(sp, 28) | ||||
|  | @ -0,0 +1,153 @@ | |||
| /* DWARF2 EH unwinding support for ARC Linux.
 | ||||
|    Copyright (C) 2017 Free Software Foundation, Inc. | ||||
| 
 | ||||
|    This file is part of GCC. | ||||
| 
 | ||||
|    GCC is free software; you can redistribute it and/or modify it | ||||
|    under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation; either version 3, or (at your option) | ||||
|    any later version. | ||||
| 
 | ||||
|    GCC is distributed in the hope that it will be useful, but WITHOUT | ||||
|    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||||
|    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public | ||||
|    License for more details. | ||||
| 
 | ||||
|    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. | ||||
| 
 | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    and a copy of the GCC Runtime Library Exception along with this | ||||
|    program; see the files COPYING3 and COPYING.RUNTIME respectively. | ||||
|    If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| /* This order is defined by a structure in the kernel, in file
 | ||||
|    arch/arc/kernel/signal.c.  */ | ||||
| 
 | ||||
| #define REGISTER_IN_STACK(REG_NAME, ID) \ | ||||
|   REG_NAME, | ||||
| enum registers_stack_order { | ||||
|   REGISTER_STACK_ORDER_START = -1, | ||||
|   #include "config/arc/linux-unwind-reg.def" | ||||
|   REGISTER_STACK_ORDER_SIZE, | ||||
| }; | ||||
| 
 | ||||
| struct register_position { | ||||
|   int reg_id; | ||||
|   int offset_in_stack; | ||||
| }; | ||||
| #undef REGISTER_IN_STACK | ||||
| 
 | ||||
| #define REGISTER_SIZE_IN_WORDS 4 | ||||
| #define REGISTER_IN_STACK(REG_NAME, ID) (int) ID, | ||||
| int | ||||
| register_id_for_index[REGISTER_STACK_ORDER_SIZE] = { | ||||
|   #include "config/arc/linux-unwind-reg.def" | ||||
| }; | ||||
| #undef REGISTER_IN_STACK | ||||
| 
 | ||||
| #ifndef inhibit_libc | ||||
| /* Do code reading to identify a signal frame, and set the frame
 | ||||
|    state data appropriately.  See unwind-dw2.c for the structs.  */ | ||||
| 
 | ||||
| #include <signal.h> | ||||
| #include <asm/unistd.h> | ||||
| 
 | ||||
| /*
 | ||||
| 00010edc <__default_rt_sa_restorer>: | ||||
|    10edc:	208a 12c2		mov     r8,139 | ||||
|    10ee0:	781e			trap_s  0 | ||||
|    10ee2:	7ee0			j_s     [blink] | ||||
| */ | ||||
| 
 | ||||
| #if __BIG_ENDIAN__ | ||||
| #define MOV_R8_139	  0x8a20c212 | ||||
| #define TRAP_S_J_S_BLINK  0x1e78e07e | ||||
| #define SWI		  0x6f223f00 | ||||
| #elif __LITTLE_ENDIAN__ | ||||
| #define MOV_R8_139	  0x12c2208a | ||||
| #define TRAP_S_J_S_BLINK  0x7ee0781e | ||||
| #define SWI		  0x003f226f | ||||
| #endif | ||||
| 
 | ||||
| #define MD_FALLBACK_FRAME_STATE_FOR arc_fallback_frame_state | ||||
| 
 | ||||
| static __attribute__((noinline)) _Unwind_Reason_Code | ||||
| arc_fallback_frame_state (struct _Unwind_Context *context, | ||||
| 			   _Unwind_FrameState *fs) | ||||
| { | ||||
|   struct rt_sigframe { | ||||
|     siginfo_t info; | ||||
|     ucontext_t uc; | ||||
|     unsigned int sigret_magic; | ||||
|   }; | ||||
| 
 | ||||
|   struct rt_sigframe *rt_; | ||||
|   u_int32_t *pc = (u_int32_t *) context->ra; | ||||
|   struct sigcontext *sc; | ||||
|   _Unwind_Ptr new_cfa; | ||||
|   int i; | ||||
| 
 | ||||
| #ifdef __ARC700__ | ||||
|   if (pc[1] != SWI) | ||||
|     return _URC_END_OF_STACK; | ||||
| #else | ||||
|   if (pc[1] != TRAP_S_J_S_BLINK) | ||||
|     return _URC_END_OF_STACK; | ||||
| #endif | ||||
| 
 | ||||
|   if (pc[0] == MOV_R8_139) | ||||
|     { | ||||
|       rt_ = context->cfa; | ||||
|       sc = &rt_->uc.uc_mcontext; | ||||
|     } | ||||
|   else | ||||
|     return _URC_END_OF_STACK; | ||||
| 
 | ||||
|   new_cfa = (_Unwind_Ptr) sc; | ||||
|   fs->regs.cfa_how = CFA_REG_OFFSET; | ||||
|   fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__; | ||||
|   fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa; | ||||
| 
 | ||||
|   unsigned long *regs = &sc->regs.scratch.bta; | ||||
|   for (i = 0; i < REGISTER_STACK_ORDER_SIZE; i++) | ||||
|     { | ||||
|       if (register_id_for_index[i] == -1) | ||||
| 	continue; | ||||
|       fs->regs.reg[register_id_for_index[i]].how = REG_SAVED_OFFSET; | ||||
|       fs->regs.reg[register_id_for_index[i]].loc.offset | ||||
| 	= ((_Unwind_Ptr) &(regs[i])) - new_cfa; | ||||
|     } | ||||
| 
 | ||||
|   fs->regs.reg[31].how = REG_SAVED_VAL_OFFSET; | ||||
|   fs->regs.reg[31].loc.offset = ((_Unwind_Ptr) (regs[ret])) - new_cfa; | ||||
| 
 | ||||
|   fs->retaddr_column = 31; | ||||
| 
 | ||||
|   return _URC_NO_REASON; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #define MD_FROB_UPDATE_CONTEXT arc_frob_update_context | ||||
| /* Save fp register for unwinding to work.  */ | ||||
| 
 | ||||
| static void | ||||
| arc_frob_update_context (struct _Unwind_Context *context, | ||||
| 			 _Unwind_FrameState *fs) | ||||
| { | ||||
|   _Unwind_Word fp_val; | ||||
|   asm ("mov %0,fp" : "=r" (fp_val)); | ||||
| 
 | ||||
|   switch (fs->regs.reg[27].how) | ||||
|     { | ||||
|     case REG_UNSAVED: | ||||
|     case REG_UNDEFINED: | ||||
|       if (context->reg[27] == NULL) | ||||
| 	_Unwind_SetGRValue (context, 27, fp_val); | ||||
|       break; | ||||
| 
 | ||||
|     default: | ||||
|       break; | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	 Cupertino Miranda
						Cupertino Miranda