This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
SH: patch for PIC and function sections
- To: gcc-patches at gcc dot gnu dot org
- Subject: SH: patch for PIC and function sections
- From: Andrew Haley <aph at cambridge dot redhat dot com>
- Date: Mon, 17 Sep 2001 13:11:44 +0100 (BST)
This testcase:
------------------------------------------------------------------
#include "stdio.h"
char s[] __attribute__ ((section (".text.foo"))) = "Hello, World!\n ";
static char *p (void) __attribute__ ((section (".text.bar")));
static char *
p (void)
{
return s;
}
int main(void)
{
fprintf (stderr, p());
exit (0);
}
------------------------------------------------------------------
crashes at runtime on SH when compiled -fPIC. The reason for this is
that gcc doesn't realize that it can't just produce a simple offset
between two symbols in different sections but needs a proper PLT
fixup.
I guess I should also commit the test case. OK?
Andrew.
2001-09-14 Andrew Haley <aph@cambridge.redhat.com>
* config/sh/sh.c (sh_call_needs_plt): New function.
* config/sh/sh-protos.h (sh_call_needs_plt): Delare it.
* config/sh/sh.md (call_pcrel): Use sh_call_needs_plt.
(call_value_pcrel): Likewise
(sibcall): Likewise.
* config/sh/sh.h (ENCODE_SECTION_INFO): Check the section of
non-global decls before deciding that we can use GOTOFF.
Index: config/sh/sh-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh-protos.h,v
retrieving revision 1.20
diff -w -p -2 -c -r1.20 sh-protos.h
*** sh-protos.h 2001/08/04 04:35:44 1.20
--- sh-protos.h 2001/09/17 12:01:05
*************** extern void expand_fp_branch PARAMS ((rt
*** 101,104 ****
--- 101,106 ----
extern int sh_insn_length_adjustment PARAMS ((rtx));
extern int sh_can_redirect_branch PARAMS ((rtx, rtx));
+ extern int sh_call_needs_plt PARAMS ((rtx));
+ rtx op;
#ifdef TREE_CODE
extern void sh_va_start PARAMS ((int, tree, rtx));
Index: config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.118
diff -w -p -2 -c -r1.118 sh.c
*** sh.c 2001/08/31 14:49:37 1.118
--- sh.c 2001/09/17 12:01:05
*************** sh_can_redirect_branch (branch1, branch2
*** 5553,5556 ****
--- 5553,5570 ----
insn && distance < 256;
insn = NEXT_INSN (insn))
+
+ /* Return true if a function call needs to use the PLT. This is true
+ iff the destination has SYMBOL_REF_FLAG clear -- in which case it's
+ either global or in a named section -- or the current function is
+ in a named section. With function-sections everything needs the
+ PLT. */
+ int
+ sh_call_needs_plt (op)
+ rtx op;
+ {
+ return (SYMBOL_REF_FLAG (op) == 0
+ || DECL_SECTION_NAME (current_function_decl)
+ || flag_function_sections);
+ }
{
if (insn == dest)
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.116
diff -w -p -2 -c -r1.116 sh.h
*** sh.h 2001/08/18 20:25:53 1.116
--- sh.h 2001/09/17 12:01:05
*************** do \
*** 1813,1817 ****
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = \
(TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
! || ! TREE_PUBLIC (DECL)); \
} \
} \
--- 1813,1819 ----
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = \
(TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
! || (! TREE_PUBLIC (DECL) \
! && DECL_SECTION_NAME (DECL) == 0 \
! && ! UNIQUE_SECTION_P(DECL))); \
} \
} \
Index: config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.89
diff -w -p -2 -c -r1.89 sh.md
*** sh.md 2001/08/18 00:53:20 1.89
--- sh.md 2001/09/17 12:01:06
***************
*** 3432,3436 ****
rtx lab = gen_call_site ();
! if (SYMBOL_REF_FLAG (operands[0]))
emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
else
--- 3432,3436 ----
rtx lab = gen_call_site ();
! if (! sh_call_needs_plt (operands[0]))
emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
else
***************
*** 3491,3495 ****
rtx lab = gen_call_site ();
! if (SYMBOL_REF_FLAG (operands[1]))
emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
else
--- 3491,3495 ----
rtx lab = gen_call_site ();
! if (! sh_call_needs_plt (operands[1]))
emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
else
***************
*** 3614,3618 ****
to restore it, so we can only use PC-relative PIC calls for
static functions. */
! && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
{
emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
--- 3614,3618 ----
to restore it, so we can only use PC-relative PIC calls for
static functions. */
! && ! sh_call_needs_plt (XEXP (operands[0], 0)))
{
emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));