This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

SH: patch for PIC and function sections


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]));



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]