OSDN Git Service

* config/xtensa/xtensa.c (xtensa_multibss_section_type_flags): Add
authorbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Sep 2003 23:19:21 +0000 (23:19 +0000)
committerbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Sep 2003 23:19:21 +0000 (23:19 +0000)
ATTRIBUTE_UNUSED.
(call_insn_operand): For PIC, don't allow a direct call to a
function in a different section than the current one.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71415 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/xtensa/xtensa.c

index 3c0e428..5c00702 100644 (file)
@@ -1,3 +1,10 @@
+2003-09-15  Bob Wilson  <bob.wilson@acm.org>
+
+       * config/xtensa/xtensa.c (xtensa_multibss_section_type_flags): Add
+       ATTRIBUTE_UNUSED.
+       (call_insn_operand): For PIC, don't allow a direct call to a
+       function in a different section than the current one.
+
 2003-09-16  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
         
         * doc/invoke.texi (Warning Options): Add missing hyphen before
index 3c382d9..32d5030 100644 (file)
@@ -200,7 +200,7 @@ static struct machine_function * xtensa_init_machine_status PARAMS ((void));
 static void printx PARAMS ((FILE *, signed int));
 static void xtensa_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
 static unsigned int xtensa_multibss_section_type_flags
-  PARAMS ((tree, const char *, int));
+  PARAMS ((tree, const char *, int)) ATTRIBUTE_UNUSED;
 static void xtensa_select_rtx_section
   PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT));
 static bool xtensa_rtx_costs PARAMS ((rtx, int, int, int *));
@@ -581,8 +581,37 @@ call_insn_operand (op, mode)
   if (CONSTANT_ADDRESS_P (op))
     {
       /* Direct calls only allowed to static functions with PIC.  */
-      return (!flag_pic
-             || (GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)));
+      if (flag_pic)
+       {
+         tree callee, callee_sec, caller_sec;
+
+         if (GET_CODE (op) != SYMBOL_REF || !SYMBOL_REF_LOCAL_P (op))
+           return FALSE;
+
+         /* Don't attempt a direct call if the callee is known to be in
+            a different section, since there's a good chance it will be
+            out of range.  */
+
+         if (flag_function_sections
+             || DECL_ONE_ONLY (current_function_decl))
+           return FALSE;
+         caller_sec = DECL_SECTION_NAME (current_function_decl);
+         callee = SYMBOL_REF_DECL (op);
+         if (callee)
+           {
+             if (DECL_ONE_ONLY (callee))
+               return FALSE;
+             callee_sec = DECL_SECTION_NAME (callee);
+             if (((caller_sec == NULL_TREE) ^ (callee_sec == NULL_TREE))
+                 || (caller_sec != NULL_TREE
+                     && strcmp (TREE_STRING_POINTER (caller_sec),
+                                TREE_STRING_POINTER (callee_sec)) != 0))
+               return FALSE;
+           }
+         else if (caller_sec != NULL_TREE)
+           return FALSE;
+       }
+      return TRUE;
     }
 
   return FALSE;