s390-protos.h (s390_emit_tpf_eh_return): Add prototype.

2004-09-22  P.J. Darcy  <darcypj@us.ibm.com>

	* config/s390/s390-protos.h (s390_emit_tpf_eh_return): Add prototype.
	* config/s390/s390.c (s390_emit_tpf_eh_return): New function.
	* config/s390/s390.h (TARGET_TPF): New macro.
	* config/s390/s390.md ("eh_return"): New expander.
	* config/s390/t-tpf (LIB2ADDEH): Use unwind-dw2-fde.c rather than
	unwind-dw2-fde-glibc.c.  Add config/s390/tpf-eh.c.
	(LIB2ADDEHDEP): Remove unwind-dw2-fde.c.
	* config/s390/tpf.h (TARGET_TPF): Define to 1.
	(STACK_POINTER_OFFSET): Increase to 448.
	(TARGET_DEFAULT): Set -mtpf-trace on as default.
	(TPF_LOC_DIFF_OFFSET): New macro.
	(ASM_PREFERRED_EH_DATA_FORMAT): Redefine to always use absolute
	encoding.
	(__isPATrange): Add prototype.
	(MD_FALLBACK_FRAME_STATE_FOR): Define.
	* config/s390/tpf-eh.c: New file.

From-SVN: r87857
This commit is contained in:
P.J. Darcy 2004-09-22 13:57:40 +00:00 committed by Ulrich Weigand
parent 6a97296a06
commit 4798630cb0
8 changed files with 325 additions and 7 deletions

View File

@ -1,3 +1,22 @@
2004-09-22 P.J. Darcy <darcypj@us.ibm.com>
* config/s390/s390-protos.h (s390_emit_tpf_eh_return): Add prototype.
* config/s390/s390.c (s390_emit_tpf_eh_return): New function.
* config/s390/s390.h (TARGET_TPF): New macro.
* config/s390/s390.md ("eh_return"): New expander.
* config/s390/t-tpf (LIB2ADDEH): Use unwind-dw2-fde.c rather than
unwind-dw2-fde-glibc.c. Add config/s390/tpf-eh.c.
(LIB2ADDEHDEP): Remove unwind-dw2-fde.c.
* config/s390/tpf.h (TARGET_TPF): Define to 1.
(STACK_POINTER_OFFSET): Increase to 448.
(TARGET_DEFAULT): Set -mtpf-trace on as default.
(TPF_LOC_DIFF_OFFSET): New macro.
(ASM_PREFERRED_EH_DATA_FORMAT): Redefine to always use absolute
encoding.
(__isPATrange): Add prototype.
(MD_FALLBACK_FRAME_STATE_FOR): Define.
* config/s390/tpf-eh.c: New file.
2004-09-22 Diego Novillo <dnovillo@redhat.com>
* fold-const.c (fold): Avoid non INTEGER_TYPEs when widening

View File

@ -95,6 +95,7 @@ extern rtx s390_gen_rtx_const_DI (int, int);
extern void s390_output_dwarf_dtprel (FILE*, int, rtx);
extern int s390_agen_dep_p (rtx, rtx);
extern rtx s390_load_got (void);
extern void s390_emit_tpf_eh_return (rtx);
#endif /* RTX_CODE */

View File

@ -8017,5 +8017,25 @@ s390_conditional_register_usage (void)
}
}
/* Corresponding function to eh_return expander. */
static GTY(()) rtx s390_tpf_eh_return_symbol;
void
s390_emit_tpf_eh_return (rtx target)
{
rtx insn, reg;
if (!s390_tpf_eh_return_symbol)
s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
reg = gen_rtx_REG (Pmode, 2);
emit_move_insn (reg, target);
insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
gen_rtx_REG (Pmode, RETURN_REGNUM));
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
}
#include "gt-s390.h"

View File

@ -80,6 +80,9 @@ extern const char *s390_stack_guard_string;
/* Run-time target specification. */
/* This will be overridden by OS headers. */
#define TARGET_TPF 0
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \
do \

View File

@ -7504,3 +7504,15 @@
GEN_INT (0x7fffffff)));
DONE;
})
;; Instruction definition to expand eh_return macro to support
;; swapping in special linkage return addresses.
(define_expand "eh_return"
[(use (match_operand 0 "register_operand" ""))]
"TARGET_TPF"
{
s390_emit_tpf_eh_return (operands[0]);
DONE;
})

View File

@ -7,7 +7,8 @@ TARGET_LIBGCC2_CFLAGS = -fPIC
# the symbol versions that glibc used.
SHLIB_MAPFILES += $(srcdir)/config/s390/libgcc-glibc.ver
# Use unwind-dw2-fde-glibc
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
# Use unwind-dw2-fde and extra tpf-eh support routines.
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c \
$(srcdir)/config/s390/tpf-eh.c
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h

183
gcc/config/s390/tpf-eh.c Normal file
View File

@ -0,0 +1,183 @@
/* Exception handling routines for TPF.
Copyright (C) 2004 Free Software Foundation, Inc.
Contributed by P.J. Darcy (darcypj@us.ibm.com).
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 2, or (at your option)
any later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
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 COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#define __USE_GNU 1
#define _GNU_SOURCE
#include <dlfcn.h>
#undef __USE_GNU
#undef _GNU_SOURCE
#define CURRENT_STACK_PTR() \
({ register unsigned long int *stack_ptr asm ("%r15"); stack_ptr; })
#define PREVIOUS_STACK_PTR() \
((unsigned long int *)(*(CURRENT_STACK_PTR())))
#define RA_OFFSET_FROM_START_OF_STACK_FRAME 112
#define CURRENT_STACK_PTR_OFFSET 120
#define TPFRA_OFFSET_FROM_START_OF_STACK_FRAME 168
#define MIN_PATRANGE 0x10000
#define MAX_PATRANGE 0x800000
#define INVALID_RETURN 0
/* Function Name: __isPATrange
Parameters passed into it: address to check
Return Value: A 1 if address is in pat code "range", 0 if not
Description: This function simply checks to see if the address
passed to it is in the CP pat code range. */
unsigned int __isPATrange(void *addr)
{
if (addr > (void *)MIN_PATRANGE && addr < (void *)MAX_PATRANGE)
return 1;
else
return 0;
}
/* Function Name: __tpf_eh_return
Parameters passed into it: Destination address to jump to.
Return Value: Converted Destination address if a Pat Stub exists.
Description: This function swaps the uwinding return address
with the cp stub code. The original target return address is
then stored into the tpf return address field. The cp stub
code is searched for by climbing back up the stack and
comparing the tpf stored return address object address to
that of the targets object address. */
void *__tpf_eh_return (void *target)
{
Dl_info targetcodeInfo, currentcodeInfo;
int retval;
void *current, *stackptr;
unsigned long int shifter;
/* Get code info for target return's address. */
retval = dladdr (target, &targetcodeInfo);
/* Get the return address of the stack frame to be replaced by
the exception unwinder. So that the __cxa_throw return is
replaced by the target return. */
current = (void *) *((unsigned long int *)
((*((unsigned long int *)*(PREVIOUS_STACK_PTR())))
+ RA_OFFSET_FROM_START_OF_STACK_FRAME));
/* Ensure the code info is valid (for target). */
if (retval != INVALID_RETURN)
{
/* Now check to see if the current RA is a PAT
stub return address. */
if ( __isPATrange(current))
{
/* It was! Then go into the TPF private stack area and fetch
the real address. */
current = (void *) *((unsigned long int *)
((unsigned long int)*((unsigned long int *)
*(PREVIOUS_STACK_PTR()))
+TPFRA_OFFSET_FROM_START_OF_STACK_FRAME));
}
/* Get code info for current return address. */
retval = dladdr (current, &currentcodeInfo);
/* Ensure the code info is valid (for current frame). */
if (retval != INVALID_RETURN)
{
/* Get the stack pointer of the stack frame to be replaced by
the exception unwinder. So that we can begin our climb
there. */
stackptr = (void *) (*((unsigned long int *)
(*((unsigned long int *)(*(PREVIOUS_STACK_PTR()))))));
/* Begin looping through stack frames. Stop if invalid
code information is retrieved or if a match between the
current stack frame iteration shared object's address
matches that of the target, calculated above. */
while (retval != INVALID_RETURN
&& targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase)
{
/* Get return address based on our stackptr iterator. */
current = (void *) *((unsigned long int *)
(stackptr+RA_OFFSET_FROM_START_OF_STACK_FRAME));
/* Is it a Pat Stub? */
if (__isPATrange (current))
{
/* Yes it was, get real return address
in TPF stack area. */
current = (void *) *((unsigned long int *)
(stackptr+TPFRA_OFFSET_FROM_START_OF_STACK_FRAME));
}
/* Get codeinfo on RA so that we can figure out
the module address. */
retval = dladdr (current, &currentcodeInfo);
/* Check that codeinfo for current stack frame is valid.
Then compare the module address of current stack frame
to target stack frame to determine if we have the pat
stub address we want. */
if (retval != INVALID_RETURN
&& targetcodeInfo.dli_fbase == currentcodeInfo.dli_fbase)
{
/* Yes! They are in the same module. Now store the
real target address into the TPF stack area of
the target frame we are jumping to. */
*((unsigned long int *)(*((unsigned long int *)
(*PREVIOUS_STACK_PTR() + CURRENT_STACK_PTR_OFFSET))
+ TPFRA_OFFSET_FROM_START_OF_STACK_FRAME))
= (unsigned long int) target;
/* Before returning the desired pat stub address to
the exception handling unwinder so that it can
actually do the "leap" shift out the low order
bit designated to determine if we are in 64BIT mode.
This is nececcary for CTOA stubs.
Otherwise we leap one byte past where we want to
go to in the TPF pat stub linkage code. */
shifter = *((unsigned long int *)
(stackptr + RA_OFFSET_FROM_START_OF_STACK_FRAME));
shifter &= ~1ul;
return (void *) shifter;
}
/* Desired module pat stub not found ...
Bump stack frame iterator. */
stackptr = (void *) *(unsigned long int *) stackptr;
}
}
}
/* No pat stub found, could be a problem? Simply return unmodified
target address. */
return target;
}

View File

@ -1,5 +1,5 @@
/* Definitions for target OS TPF for GNU compiler, for IBM S/390 hardware
Copyright (C) 2003 Free Software Foundation, Inc.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Contributed by P.J. Darcy (darcypj@us.ibm.com),
Hartmut Penner (hpenner@de.ibm.com), and
Ulrich Weigand (uweigand@de.ibm.com).
@ -25,6 +25,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define _TPF_H
/* TPF wants the following macros defined/undefined as follows. */
#undef TARGET_TPF
#define TARGET_TPF 1
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
#undef ASM_APP_OFF
@ -50,11 +52,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* TPF OS specific stack-pointer offset. */
#undef STACK_POINTER_OFFSET
#define STACK_POINTER_OFFSET 280
#define STACK_POINTER_OFFSET 448
/* TPF stack placeholder offset. */
#undef TPF_LOC_DIFF_OFFSET
#define TPF_LOC_DIFF_OFFSET 168
/* When building for TPF, set a generic default target that is 64 bits. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 0x33
#define TARGET_DEFAULT 0xb3
/* Exception handling. */
/* Select a format to encode pointers in exception handling data. */
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) DW_EH_PE_absptr
/* TPF OS specific compiler settings. */
#undef TARGET_OS_CPP_BUILTINS
@ -108,5 +119,73 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld64.so}}}"
extern unsigned int __isPATrange (void *);
/* Exceptions macro defined for TPF so that functions without
dwarf frame information can be used with exceptions. */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do \
{ \
unsigned long int regs_; \
unsigned long int new_cfa_; \
int i_; \
\
if ((CONTEXT)->cfa == NULL) \
goto SUCCESS; \
\
/* Are we going through special linkage code? */ \
if (__isPATrange((CONTEXT)->ra)) \
{ \
/* No stack frame. */ \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 15; \
(FS)->cfa_offset = STACK_POINTER_OFFSET; \
\
/* All registers remain unchanged ... */ \
for (i_ = 0; i_ < 32; i_++) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_REG; \
(FS)->regs.reg[i_].loc.reg = i_; \
} \
\
/* ... except for %r14, which is stored at CFA-112 \
and used as return address. */ \
(FS)->regs.reg[14].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[14].loc.offset = \
TPF_LOC_DIFF_OFFSET - STACK_POINTER_OFFSET; \
(FS)->retaddr_column = 14; \
\
goto SUCCESS; \
\
} \
\
regs_ = *((unsigned long int *) \
(((unsigned long int) (CONTEXT)->cfa) - STACK_POINTER_OFFSET)); \
new_cfa_ = regs_ + STACK_POINTER_OFFSET; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 15; \
(FS)->cfa_offset = new_cfa_ - \
(unsigned long int) (CONTEXT)->cfa + STACK_POINTER_OFFSET; \
\
for (i_ = 0; i_ < 16; i_++) \
{ \
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[i_].loc.offset = \
(regs_+(i_*8)) - new_cfa_; \
} \
\
for (i_ = 0; i_ < 4; i_++) \
{ \
(FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[16+i_].loc.offset = \
(regs_+(16*8)+(i_*8)) - new_cfa_; \
} \
\
(FS)->retaddr_column = 14; \
\
goto SUCCESS; \
\
} while (0)
#endif /* ! _TPF_H */