This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


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

Re: A relocation problem in shared objects for SH


On Sep 14, 2000, kaz Kojima <kkojima@rr.iij4u.or.jp> wrote:

> We have a problem when making libc.so for sh-unknown-linux-gnu target. This
> comes from that SH ELF uses both rela relocation and the implicit rel value
> in memory (to support COFF, I think).

Which version of the assembler are you using?  I can't reproduce this
problem with current binutils.  In fact, the symptoms look very
similar to those of the bug fixed with:

2000-09-01  Alexandre Oliva  <aoliva@redhat.com>
	* config/tc-sh.c (md_apply_fix): Map 32-bit relocations that
	become PC-relative to BFD_RELOC_32_PCREL.  Reject 16- or 8-bit
	similar relocs.

Anyway, there is a bug, but it is in GCC.  It isn't generating PIC
code for computed goto, which glibc's vfprintf uses.

Here's a patch that fixes this problem in GCC.  Ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* config/sh/sh.c (nonpic_symbol_mentioned_p): Check LABEL_REFs.
	* config/sh/sh.md (sym_label2reg, symPLT_label2reg): Protect
	LABEL_REFs with a PIC-safe unspec.

Index: gcc/config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.c,v
retrieving revision 1.62
diff -u -p -r1.62 sh.c
--- gcc/config/sh/sh.c 2000/09/07 22:24:33 1.62
+++ gcc/config/sh/sh.c 2000/09/16 07:44:41
@@ -5277,8 +5277,8 @@ sh_insn_length_adjustment (insn)
   return 0;
 }
 
-/* Return TRUE if X references a SYMBOL_REF whose symbol doesn't have
-   @GOT or @GOTOFF.  */
+/* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol
+   isn't protected by a PIC unspec.  */
 int
 nonpic_symbol_mentioned_p (x)
      rtx x;
@@ -5286,7 +5286,7 @@ nonpic_symbol_mentioned_p (x)
   register const char *fmt;
   register int i;
 
-  if (GET_CODE (x) == SYMBOL_REF)
+  if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
     return 1;
 
   if (GET_CODE (x) == UNSPEC
Index: gcc/config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.md,v
retrieving revision 1.48
diff -u -p -r1.48 sh.md
--- gcc/config/sh/sh.md 2000/09/15 16:33:52 1.48
+++ gcc/config/sh/sh.md 2000/09/16 07:44:41
@@ -3482,8 +3482,9 @@ else
   [(set (match_operand:SI 0 "" "")
 	(const (minus:SI
 		(unspec [(match_operand:SI 1 "" "")] 6)
-		(const (plus:SI (label_ref (match_operand:SI 2 "" ""))
-				(const_int 2))))))]
+		(const (plus:SI
+			(unspec [(label_ref (match_operand:SI 2 "" ""))] 6)
+			(const_int 2))))))]
   "" "")
 
 (define_expand "symGOT2reg"
@@ -3514,8 +3515,10 @@ else
 	(const (minus:SI
 		(plus:SI (pc)
 			 (unspec [(match_operand:SI 1 "" "")] 9))
-		(const (plus:SI (label_ref (match_operand:SI 2 "" ""))
-				(const_int 2))))))
+		(const
+		 (plus:SI
+		  (unspec [(label_ref (match_operand:SI 2 "" ""))] 6)
+		  (const_int 2))))))
    (use (match_dup 3))]
   ;; Even though the PIC register is not really used by the call
   ;; sequence in which this is expanded, the PLT code assumes the PIC

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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