aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/xtensa/xtensa.c35
2 files changed, 39 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c0e428..5c00702 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 3c382d9..32d5030 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -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;