From: Franz Sirl Date: Thu, 23 Jan 2003 22:19:43 +0000 (+0000) Subject: linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy regs->nip. X-Git-Tag: releases/gcc-3.2.2~93 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1670ede6beca1a0e8f8b2e7d87ae4af40c4244af;p=thirdparty%2Fgcc.git linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy regs->nip. 2003-01-23 Franz Sirl * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy regs->nip. Fix rt_sigreturn frame layout. Add support for newer kernels. * config/rs6000/rs6000.c (rs6000_binds_local_p): New functiion. (rs6000_encode_section_info): Use it. From-SVN: r61673 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3ea37106b14..62d07e13c2aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-01-23 Franz Sirl + + PR java/6748 + * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy + regs->nip. Fix rt_sigreturn frame layout. Add support for newer + kernels. + + * config/rs6000/rs6000.c (rs6000_binds_local_p): New functiion. + (rs6000_encode_section_info): Use it. + 2003-01-23 Volker Reichelt PR other/7341 diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h index 99c045364893..f5cbd7a663eb 100644 --- a/gcc/config/rs6000/linux.h +++ b/gcc/config/rs6000/linux.h @@ -1,7 +1,7 @@ /* Definitions of target machine for GNU compiler, for powerpc machines running Linux. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, - Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 + Free Software Foundation, Inc. Contributed by Michael Meissner (meissner@cygnus.com). This file is part of GNU CC. @@ -91,12 +91,34 @@ enum { SIGNAL_FRAMESIZE = 64 }; long new_cfa_; \ int i_; \ \ - /* li r0, 0x7777; sc (rt_sigreturn) */ \ - /* li r0, 0x6666; sc (sigreturn) */ \ - if (((*(unsigned int *) (pc_+0) == 0x38007777) \ - || (*(unsigned int *) (pc_+0) == 0x38006666)) \ - && (*(unsigned int *) (pc_+4) == 0x44000002)) \ - sc_ = (CONTEXT)->cfa + SIGNAL_FRAMESIZE; \ + /* li r0, 0x7777; sc (sigreturn old) */ \ + /* li r0, 0x0077; sc (sigreturn new) */ \ + /* li r0, 0x6666; sc (rt_sigreturn old) */ \ + /* li r0, 0x00AC; sc (rt_sigreturn new) */ \ + if (*(unsigned int *) (pc_+4) != 0x44000002) \ + break; \ + if (*(unsigned int *) (pc_+0) == 0x38007777 \ + || *(unsigned int *) (pc_+0) == 0x38000077) \ + { \ + struct sigframe { \ + char gap[SIGNAL_FRAMESIZE]; \ + struct sigcontext sigctx; \ + } *rt_ = (CONTEXT)->cfa; \ + sc_ = &rt_->sigctx; \ + } \ + else if (*(unsigned int *) (pc_+0) == 0x38006666 \ + || *(unsigned int *) (pc_+0) == 0x380000AC) \ + { \ + struct rt_sigframe { \ + char gap[SIGNAL_FRAMESIZE]; \ + unsigned long _unused[2]; \ + struct siginfo *pinfo; \ + void *puc; \ + struct siginfo info; \ + struct ucontext uc; \ + } *rt_ = (CONTEXT)->cfa; \ + sc_ = &rt_->uc.uc_mcontext; \ + } \ else \ break; \ \ @@ -119,11 +141,13 @@ enum { SIGNAL_FRAMESIZE = 64 }; \ /* The unwinder expects the IP to point to the following insn, \ whereas the kernel returns the address of the actual \ - faulting insn. */ \ - sc_->regs->nip += 4; \ + faulting insn. We store NIP+4 in an unused register slot to \ + get the same result for multiple evaluation of the same signal \ + frame. */ \ + sc_->regs->gpr[47] = sc_->regs->nip + 4; \ (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \ (FS)->regs.reg[CR0_REGNO].loc.offset \ - = (long)&(sc_->regs->nip) - new_cfa_; \ + = (long)&(sc_->regs->gpr[47]) - new_cfa_; \ (FS)->retaddr_column = CR0_REGNO; \ goto SUCCESS; \ } while (0) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5f05573dc7fb..89808cca8201 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1,6 +1,6 @@ /* Subroutines used for code generation on IBM RS/6000. Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GNU CC. @@ -155,6 +155,7 @@ static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int)); #ifdef OBJECT_FORMAT_COFF static void xcoff_asm_named_section PARAMS ((const char *, unsigned int)); #endif +static bool rs6000_binds_local_p PARAMS ((tree)); static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int)); static int rs6000_adjust_priority PARAMS ((rtx, int)); static int rs6000_issue_rate PARAMS ((void)); @@ -10939,7 +10940,45 @@ rs6000_unique_section (decl, reloc) DECL_SECTION_NAME (decl) = build_string (len, string); } - + +static bool +rs6000_binds_local_p (exp) + tree exp; +{ + bool local_p; + tree attr; + + /* A non-decl is an entry in the constant pool. */ + if (!DECL_P (exp)) + local_p = true; + /* Static variables are always local. */ + else if (! TREE_PUBLIC (exp)) + local_p = true; + /* Otherwise, variables defined outside this object may not be local. */ + else if (DECL_EXTERNAL (exp)) + local_p = false; + /* Linkonce and weak data are never local. */ + else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp)) + local_p = false; + /* If PIC, then assume that any global name can be overridden by + * symbols resolved from other modules. */ + else if (flag_pic || rs6000_flag_pic) + local_p = false; + /* Uninitialized COMMON variable may be unified with symbols + * resolved from other modules. */ + else if (DECL_COMMON (exp) + && (DECL_INITIAL (exp) == NULL + || DECL_INITIAL (exp) == error_mark_node)) + local_p = false; + /* Otherwise we're left with initialized (or non-common) global data + * which is of necessity defined locally. */ + else + local_p = true; + + return local_p; +} + + /* If we are referencing a function that is static or is known to be in this file, make the SYMBOL_REF special. We can use this to indicate that we can branch to this function without emitting a no-op after the @@ -10955,12 +10994,7 @@ rs6000_encode_section_info (decl) if (TREE_CODE (decl) == FUNCTION_DECL) { rtx sym_ref = XEXP (DECL_RTL (decl), 0); - if (!TREE_PUBLIC (decl) - || (!DECL_EXTERNAL (decl) - && !DECL_ONE_ONLY (decl) - && !DECL_WEAK (decl) - && !flag_pic - && !rs6000_flag_pic)) + if (rs6000_binds_local_p (decl)) SYMBOL_REF_FLAG (sym_ref) = 1; if (DEFAULT_ABI == ABI_AIX) @@ -10979,11 +11013,15 @@ rs6000_encode_section_info (decl) && DEFAULT_ABI == ABI_V4 && TREE_CODE (decl) == VAR_DECL) { + rtx sym_ref = XEXP (DECL_RTL (decl), 0); int size = int_size_in_bytes (TREE_TYPE (decl)); tree section_name = DECL_SECTION_NAME (decl); const char *name = (char *)0; int len = 0; + if (rs6000_binds_local_p (decl)) + SYMBOL_REF_FLAG (sym_ref) = 1; + if (section_name) { if (TREE_CODE (section_name) == STRING_CST)