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]
Other format: [Raw text]

Re: Another MIPS multigot patch


Daniel Jacobowitz <drow@false.org> writes:
> I have put it at:
>   http://www.false.org/~drow/binutils-mips-got.tgz

Thanks.  In hindsight, I really should have been able to work it
out from your description, sorry about that.

I think the problem is simply that check_relocs() was only checking
whether the symbol was defined, not whether the symbol was defined
by a regular or shared object.

The patch below seems to do the trick.  I'll run a bootstrap on irix,
but since you seem to trip over the problem more often, it'd be great
if you could give it a spin.

I've attached a shell archive (to be run from the top level of the
build directory).  Before the patch, a.x needlessly had a global GOT
entry for gs.  After the patch, both a.x and b.x only have a global
GOT entry for "us".

Richard


	* elfxx-mips.c (mips_elf_calculate_relocation): Use
	_bfd_elf_symbol_refs_local_p to decide whether to decay
	a GOT_PAGE/GOT_OFST pair to GOT_DISP/addend.
	(_bfd_mips_elf_check_relocs): Add a global GOT entry for GOT_PAGE
	relocs if the symbol wasn't defined by a regular object file.
	Don't check the symbol's dynindx.

Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.89
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.89 elfxx-mips.c
--- bfd/elfxx-mips.c	9 Feb 2004 08:04:00 -0000	1.89
+++ bfd/elfxx-mips.c	15 Feb 2004 21:24:41 -0000
@@ -3261,12 +3261,9 @@ mips_elf_calculate_relocation (bfd *abfd
     {
     case R_MIPS_GOT_PAGE:
     case R_MIPS_GOT_OFST:
-      /* If this symbol got a global GOT entry, we have to decay
-	 GOT_PAGE/GOT_OFST to GOT_DISP/addend.  */
-      local_p = local_p || ! h
-	|| (h->root.dynindx
-	    < mips_elf_get_global_gotsym_index (elf_hash_table (info)
-						->dynobj));
+      /* We need to decay to GOT_DISP/addend if the symbol doesn't
+	 bind locally.  */
+      local_p = local_p || _bfd_elf_symbol_refs_local_p (&h->root, info, 1);
       if (local_p || r_type == R_MIPS_GOT_OFST)
 	break;
       /* Fall through.  */
@@ -5384,25 +5381,10 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 		hmips = (struct mips_elf_link_hash_entry *)
 		  hmips->root.root.u.i.link;
 
-	      if ((hmips->root.root.type == bfd_link_hash_defined
-		   || hmips->root.root.type == bfd_link_hash_defweak)
-		  && hmips->root.root.u.def.section
+	      if ((hmips->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
 		  && ! (info->shared && ! info->symbolic
 			&& ! (hmips->root.elf_link_hash_flags
-			      & ELF_LINK_FORCED_LOCAL))
-		  /* If we've encountered any other relocation
-		     referencing the symbol, we'll have marked it as
-		     dynamic, and, even though we might be able to get
-		     rid of the GOT entry should we know for sure all
-		     previous relocations were GOT_PAGE ones, at this
-		     point we can't tell, so just keep using the
-		     symbol as dynamic.  This is very important in the
-		     multi-got case, since we don't decide whether to
-		     decay GOT_PAGE to GOT_DISP on a per-GOT basis: if
-		     the symbol is dynamic, we'll need a GOT entry for
-		     every GOT in which the symbol is referenced with
-		     a GOT_PAGE relocation.  */
-		  && hmips->root.dynindx == -1)
+			      & ELF_LINK_FORCED_LOCAL)))
 		break;
 	    }
 	  /* Fall through.  */
cat <<EOF > a.s
	.globl	__start
	.globl	gs
__start:
gs:
ls:
	lw	\$4,%got_page(us)(\$gp)
	addiu	\$4,\$4,%got_ofst(us)
	lw	\$4,%got_page(gs)(\$gp)
	addiu	\$4,\$4,%got_ofst(gs)
	lw	\$4,%got_page(ls)(\$gp)
	addiu	\$4,\$4,%got_ofst(ls)
EOF
cat <<EOF > b.s
	.globl	us
	.globl	gs
us:
gs:
ls:
	lw	\$4,%got_page(us)(\$gp)
	addiu	\$4,\$4,%got_ofst(us)
	lw	\$4,%got_page(gs)(\$gp)
	addiu	\$4,\$4,%got_ofst(gs)
	lw	\$4,%got_page(ls)(\$gp)
	addiu	\$4,\$4,%got_ofst(ls)
EOF
./gas/as-new a.s -o a.o
./gas/as-new b.s -o b.o
./ld/ld-new b.o -o b.so -shared
./ld/ld-new b.so a.o -o a.x
./ld/ld-new a.o b.so -o b.x


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