]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy regs->nip.
authorFranz Sirl <Franz.Sirl-kernel@lauterbach.com>
Thu, 23 Jan 2003 22:19:43 +0000 (22:19 +0000)
committerFranz Sirl <sirl@gcc.gnu.org>
Thu, 23 Jan 2003 22:19:43 +0000 (22:19 +0000)
2003-01-23  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>

* 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

gcc/ChangeLog
gcc/config/rs6000/linux.h
gcc/config/rs6000/rs6000.c

index e3ea37106b1490455a0d54fd503abd428161de26..62d07e13c2aa49d19959bc838e2cada1696dc2e8 100644 (file)
@@ -1,3 +1,13 @@
+2003-01-23  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
+
+       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  <reichelt@igpm.rwth-aachen.de>
 
        PR other/7341
index 99c04536489395b5a79e65f30c8d6fc674eebfa6..f5cbd7a663eb2bdae71b38f4556c523b4d161a2e 100644 (file)
@@ -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)
index 5f05573dc7fbb4a80dba1e671c8ffd46b98aa66d..89808cca82012d311122c4e676f68b8aa1fbe616 100644 (file)
@@ -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);
 }
 
-\f
+
+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)