public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
@ 2001-12-18 18:41 DJ Delorie
  2001-12-18 18:51 ` Ian Lance Taylor
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 18:41 UTC (permalink / raw)
  To: gcc-bugs, binutils; +Cc: dj


Ok, I seem to have bumped into a "this just isn't possible" scenario.

We create unaligned 32-bit pointers in unwind tables (specifically,
in the augmentation fields for context->lsda in gcc/unwind-dw2.c).

If these pointers are in a shared library, the dynamic linker needs to
adjust them according to where the shared library is loaded.

However, the only reloc available for that is R_SPARC_RELATIVE, and it
requires aligned data.  If you try to use it with unaligned data,
ld.so aborts.  If you don't use it, unwinding causes aborts because
the pointer points to the wrong place.

Could we make that pointer fde-relative or something, so that ld.so
doesn't need to adjust it?  Or make it aligned?  I can't think of any
other fix, unless there's some other R_SPARC_* reloc that does what's
needed here.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 18:41 R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again DJ Delorie
@ 2001-12-18 18:51 ` Ian Lance Taylor
  2001-12-18 18:57   ` DJ Delorie
  2001-12-18 19:03 ` Alan Modra
  2001-12-19  0:45 ` Jakub Jelinek
  2 siblings, 1 reply; 26+ messages in thread
From: Ian Lance Taylor @ 2001-12-18 18:51 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-bugs, binutils

DJ Delorie <dj@redhat.com> writes:

> Ok, I seem to have bumped into a "this just isn't possible" scenario.
> 
> We create unaligned 32-bit pointers in unwind tables (specifically,
> in the augmentation fields for context->lsda in gcc/unwind-dw2.c).
> 
> If these pointers are in a shared library, the dynamic linker needs to
> adjust them according to where the shared library is loaded.
> 
> However, the only reloc available for that is R_SPARC_RELATIVE, and it
> requires aligned data.  If you try to use it with unaligned data,
> ld.so aborts.  If you don't use it, unwinding causes aborts because
> the pointer points to the wrong place.
> 
> Could we make that pointer fde-relative or something, so that ld.so
> doesn't need to adjust it?  Or make it aligned?  I can't think of any
> other fix, unless there's some other R_SPARC_* reloc that does what's
> needed here.

R_SPARC_RELATIVE is an optimization which skips the symbol lookup.  It
seems to me that you can always use an R_SPARC_UA32 reloc against an
offset from a section, or at the very least you could do that against
a symbol.

Ian

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 18:51 ` Ian Lance Taylor
@ 2001-12-18 18:57   ` DJ Delorie
  2001-12-18 18:57     ` Ian Lance Taylor
  0 siblings, 1 reply; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 18:57 UTC (permalink / raw)
  To: ian; +Cc: gcc-bugs, binutils


> R_SPARC_RELATIVE is an optimization which skips the symbol lookup.  It
> seems to me that you can always use an R_SPARC_UA32 reloc against an
> offset from a section, or at the very least you could do that against
> a symbol.

That would be nice, but it doesn't work.  The R_SPARC_UA32 relocs are
there, interspersed with the R_SPARC_RELATIVEs, but when the program
runs the pointer is wrong.  If you read the Sparc PS-ABI, the only
reloc that uses the image load base in its calculation is
R_SPARC_RELATIVE.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 18:57   ` DJ Delorie
@ 2001-12-18 18:57     ` Ian Lance Taylor
  0 siblings, 0 replies; 26+ messages in thread
From: Ian Lance Taylor @ 2001-12-18 18:57 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-bugs, binutils

DJ Delorie <dj@delorie.com> writes:

> > R_SPARC_RELATIVE is an optimization which skips the symbol lookup.  It
> > seems to me that you can always use an R_SPARC_UA32 reloc against an
> > offset from a section, or at the very least you could do that against
> > a symbol.
> 
> That would be nice, but it doesn't work.  The R_SPARC_UA32 relocs are
> there, interspersed with the R_SPARC_RELATIVEs, but when the program
> runs the pointer is wrong.  If you read the Sparc PS-ABI, the only
> reloc that uses the image load base in its calculation is
> R_SPARC_RELATIVE.

I think you are misreading the ABI.  When there is a dynamic
relocation against a symbol defined in a dynamic object, the
relocation is done using the runtime value of the symbol, which
naturally incorporates the image load base.

R_SPARC_RELATIVE mentions the image load base explicitly only because
R_SPARC_RELATIVE does not use any symbol value.  You could replace all
R_SPARC_RELATIVE relocations with a R_SPARC_32 relocation against a
symbol with the appropriate value, and the program would run
correctly, although it would load slightly more slowly.

I don't know why the program isn't working, but I don't think you have
analyzed the problem correctly.

Ian

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 18:41 R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again DJ Delorie
  2001-12-18 18:51 ` Ian Lance Taylor
@ 2001-12-18 19:03 ` Alan Modra
  2001-12-18 19:21   ` DJ Delorie
  2001-12-19  0:45 ` Jakub Jelinek
  2 siblings, 1 reply; 26+ messages in thread
From: Alan Modra @ 2001-12-18 19:03 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-bugs, binutils

On Tue, Dec 18, 2001 at 09:31:35PM -0500, DJ Delorie wrote:
> 
> Ok, I seem to have bumped into a "this just isn't possible" scenario.

Hmm.  Latest CVS binutils should only use R_SPARC_RELATIVE if the offset
is suitable.  See elf32-sparc.c:1455

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 19:03 ` Alan Modra
@ 2001-12-18 19:21   ` DJ Delorie
  2001-12-18 19:23     ` Alan Modra
  0 siblings, 1 reply; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 19:21 UTC (permalink / raw)
  To: amodra; +Cc: gcc-bugs, binutils


> Hmm.  Latest CVS binutils should only use R_SPARC_RELATIVE if the offset
> is suitable.  See elf32-sparc.c:1455

Right, I found that bug.  We started out using R_SPARC_RELATIVE for
R_SPARC_32.  We later used it for R_SPARC_UA32 also, but that caused
aborts in ld.so, so we took it out.  However, now it seems (to me at
least) that something still needs to be done about those relocs.  Ian
disagrees, and I'm going to debug it some more, but that's what I'm
seeing right now...

Oh, and the gcc test case works fine if I link with a static version
of the library.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 19:21   ` DJ Delorie
@ 2001-12-18 19:23     ` Alan Modra
  2001-12-18 19:56       ` DJ Delorie
  0 siblings, 1 reply; 26+ messages in thread
From: Alan Modra @ 2001-12-18 19:23 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-bugs, binutils

On Tue, Dec 18, 2001 at 10:01:48PM -0500, DJ Delorie wrote:
> 
> Right, I found that bug.  We started out using R_SPARC_RELATIVE for
> R_SPARC_32.  We later used it for R_SPARC_UA32 also, but that caused
> aborts in ld.so, so we took it out.  However, now it seems (to me at
> least) that something still needs to be done about those relocs.  Ian
> disagrees, and I'm going to debug it some more, but that's what I'm
> seeing right now...

Making a wild guess at the problem, and solution...

Index: elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.34
diff -u -p -r1.34 elf32-sparc.c
--- elf32-sparc.c	2001/12/17 00:52:35	1.34
+++ elf32-sparc.c	2001/12/19 03:14:58
@@ -1530,6 +1530,13 @@ elf32_sparc_relocate_section (output_bfd
 			      bfd_set_error (bfd_error_bad_value);
 			      return false;
 			    }
+
+			  /* We are turning this relocation into one
+			     against a section symbol, so subtract out
+			     the output section's address but not the
+			     offset of the input section in the output
+			     section.  */
+			  relocation -= osec->vma;
 			}
 
 		      outrel.r_info = ELF32_R_INFO (indx, r_type);

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 19:23     ` Alan Modra
@ 2001-12-18 19:56       ` DJ Delorie
  2001-12-18 20:19         ` Ian Lance Taylor
  2001-12-18 20:24         ` Alan Modra
  0 siblings, 2 replies; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 19:56 UTC (permalink / raw)
  To: amodra; +Cc: gcc-bugs, binutils


> Making a wild guess at the problem, and solution...

Well, it made a change, but not nearly enough.  Before, the value is
something like 0x790000.  After, it's like 0x730000.  It needs to be
like 0xef790000 (the so is loaded at 0xef730000).

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 19:56       ` DJ Delorie
@ 2001-12-18 20:19         ` Ian Lance Taylor
  2001-12-18 20:22           ` DJ Delorie
  2001-12-18 20:24         ` Alan Modra
  1 sibling, 1 reply; 26+ messages in thread
From: Ian Lance Taylor @ 2001-12-18 20:19 UTC (permalink / raw)
  To: DJ Delorie; +Cc: amodra, gcc-bugs, binutils

DJ Delorie <dj@delorie.com> writes:

> > Making a wild guess at the problem, and solution...
> 
> Well, it made a change, but not nearly enough.  Before, the value is
> something like 0x790000.  After, it's like 0x730000.  It needs to be
> like 0xef790000 (the so is loaded at 0xef730000).

What does the reloc look like in the dynamic object?  Is it against a
symbol or a section?  Is the section/symbol being loaded, or is it
being dropped?

By the way, although it is a good idea to identify this bug, your
earlier suggestion of a fde relative offset sounds like a good idea to
me.  Using any sort of dynamic reloc means that you pay a cost when
you run the program, because the dynamic linker must resolve the reloc
(except for R_SPARC_JMP_SLOT which can be evaluated lazily).  Ideally
exception handling should be free except when an exception is thrown.
Obviously this ideal is unreachable, but we can move closer to it by
eliminating relocations which must be processed by the dynamic linker
every time the program is run.

Ian

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 20:19         ` Ian Lance Taylor
@ 2001-12-18 20:22           ` DJ Delorie
  0 siblings, 0 replies; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 20:22 UTC (permalink / raw)
  To: ian; +Cc: amodra, gcc-bugs, binutils


> What does the reloc look like in the dynamic object?  Is it against a
> symbol or a section?  Is the section/symbol being loaded, or is it
> being dropped?

Here's a trivial test case, sample commands (running from the
gcc/testsuite directory), and output.  The last four bytes
output by dj-b.exe should be ef 7a 03 15.

--- dj-b.c
main()
{
  unsigned char *n = bar();
  int i;
  printf("0x%08x = ", n);
  for (i=0; i<9; i++)
    printf(" %02x", n[i]);
  printf("\n");
  return 0;
}

--- dj-s.s
        .file   "<stdin>"
        .global z
        .section        ".data"
        .type   z,#object
        .size   z,4
z:
        .byte   0
x:
        .uaword 0x123
y:
        .uaword x

--- dj-s2.c
extern char z[];
void *bar()
{
  return z;
}

--- commands
gcc -c dj-s2.c
../as dj-s.s -o dj-s.o
../g++ -B../ -shared dj-s.o dj-s2.o -o libdj-s.so -nostdlib
gcc dj-b.c -L. -ldj-s -o dj-b.exe

$ objdump -R libdj-s.so
DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
00000304 R_SPARC_HI22      z
00000308 R_SPARC_LO10      z
00010319 R_SPARC_UA32      .data+0x00000001

$ ./dj-b.exe
0xef7a0314 =  00 00 00 01 23 00 79 00 01

$ (gdb) info shared
From        To          Syms Read   Shared Object Library
0xef790000  0xef7a03a0  Yes         ./libdj-s.so

$ objdump -sh libdj-s.so

Contents of section .data:
 10314 00000001 23000000 00                 ....#....       

  6 .data         00000009  00010314  00010314  00000314  2**0
                  CONTENTS, ALLOC, LOAD, DATA

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 19:56       ` DJ Delorie
  2001-12-18 20:19         ` Ian Lance Taylor
@ 2001-12-18 20:24         ` Alan Modra
  2001-12-18 20:37           ` DJ Delorie
  2001-12-19  0:57           ` Jakub Jelinek
  1 sibling, 2 replies; 26+ messages in thread
From: Alan Modra @ 2001-12-18 20:24 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-bugs, binutils

On Tue, Dec 18, 2001 at 10:36:02PM -0500, DJ Delorie wrote:
> 
> > Making a wild guess at the problem, and solution...
> 
> Well, it made a change, but not nearly enough.  Before, the value is
> something like 0x790000.  After, it's like 0x730000.  It needs to be
> like 0xef790000 (the so is loaded at 0xef730000).

glibc's sparc32/dl-machine.h looks wrong to me.

An extract:

#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
  if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
    {
# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
      if (map != &_dl_rtld_map) /* Already done in rtld itself. */
# endif
	*reloc_addr += map->l_addr + reloc->r_addend;
    }
  else
#endif
    {
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
      const Elf32_Sym *const refsym = sym;
#endif
      Elf32_Addr value;
#ifndef RESOLVE_CONFLICT_FIND_MAP
      if (sym->st_shndx != SHN_UNDEF &&
	  ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
	value = map->l_addr;
      else
	{
	  value = RESOLVE (&sym, version, r_type);
	  if (sym)
	    value += sym->st_value;
	}
#else
      value = 0;
#endif
      value += reloc->r_addend;	/* Assume copy relocs have zero addend.  */

Seems like local sym values are ignored, at least inside the #ifndef
RESOLVE_CONFLICT_FIND MAP (whatever that is), and of course section
syms are local.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 20:24         ` Alan Modra
@ 2001-12-18 20:37           ` DJ Delorie
  2001-12-18 20:44             ` Alan Modra
  2001-12-18 20:59             ` Ian Lance Taylor
  2001-12-19  0:57           ` Jakub Jelinek
  1 sibling, 2 replies; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 20:37 UTC (permalink / raw)
  To: amodra; +Cc: gcc-bugs, binutils


> glibc's sparc32/dl-machine.h looks wrong to me.

Um, I'm on sparc-sun-solaris2.5.1.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 20:37           ` DJ Delorie
@ 2001-12-18 20:44             ` Alan Modra
  2001-12-18 21:03               ` DJ Delorie
  2001-12-18 20:59             ` Ian Lance Taylor
  1 sibling, 1 reply; 26+ messages in thread
From: Alan Modra @ 2001-12-18 20:44 UTC (permalink / raw)
  To: DJ Delorie; +Cc: binutils

On Tue, Dec 18, 2001 at 11:23:20PM -0500, DJ Delorie wrote:
> 
> > glibc's sparc32/dl-machine.h looks wrong to me.
> 
> Um, I'm on sparc-sun-solaris2.5.1.

OK, so you're using Sun's libc and ld.so.  Smells like a bug in their
ld.so, as the testcase objects look good to me.  For amusement, see
what happens if you poke some non-zero values in libdj-s.so's image
.data for "y".

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 20:37           ` DJ Delorie
  2001-12-18 20:44             ` Alan Modra
@ 2001-12-18 20:59             ` Ian Lance Taylor
  2001-12-18 21:25               ` DJ Delorie
  1 sibling, 1 reply; 26+ messages in thread
From: Ian Lance Taylor @ 2001-12-18 20:59 UTC (permalink / raw)
  To: DJ Delorie; +Cc: amodra, gcc-bugs, binutils

DJ Delorie <dj@delorie.com> writes:

> > glibc's sparc32/dl-machine.h looks wrong to me.
> 
> Um, I'm on sparc-sun-solaris2.5.1.

What happens if you use the Solaris assembler and linker?  If it
works, how do the results differ from the GNU output?

Ian

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 20:44             ` Alan Modra
@ 2001-12-18 21:03               ` DJ Delorie
  2001-12-18 23:12                 ` Alan Modra
  0 siblings, 1 reply; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 21:03 UTC (permalink / raw)
  To: amodra; +Cc: binutils


> OK, so you're using Sun's libc and ld.so.  Smells like a bug in their
> ld.so, as the testcase objects look good to me.

Present in 2.5.1, 2.6, and fixed in 2.7, and 2.8 if so.  The 2.5.1
test binary/so work fine in 2.7 and 2.8.

Sigh.  That means I can't fix it...

>  For amusement, see what happens if you poke some non-zero values in
> libdj-s.so's image .data for "y".

It twiddles the result accordingly.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 20:59             ` Ian Lance Taylor
@ 2001-12-18 21:25               ` DJ Delorie
  0 siblings, 0 replies; 26+ messages in thread
From: DJ Delorie @ 2001-12-18 21:25 UTC (permalink / raw)
  To: ian; +Cc: amodra, gcc-bugs, binutils


> What happens if you use the Solaris assembler and linker?

No noticeable difference.  Except I had to revert Alan's wild guess
patch (sorry Alan) to get the right results on 2.7 and 2.8.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 21:03               ` DJ Delorie
@ 2001-12-18 23:12                 ` Alan Modra
  0 siblings, 0 replies; 26+ messages in thread
From: Alan Modra @ 2001-12-18 23:12 UTC (permalink / raw)
  To: DJ Delorie; +Cc: binutils

On Tue, Dec 18, 2001 at 11:58:17PM -0500, DJ Delorie wrote:
> 
> > OK, so you're using Sun's libc and ld.so.  Smells like a bug in their
> > ld.so, as the testcase objects look good to me.
> 
> Present in 2.5.1, 2.6, and fixed in 2.7, and 2.8 if so.  The 2.5.1
> test binary/so work fine in 2.7 and 2.8.
> 
> Sigh.  That means I can't fix it...

Yes you can.

> >  For amusement, see what happens if you poke some non-zero values in
> > libdj-s.so's image .data for "y".
> 
> It twiddles the result accordingly.

And this is why it can be fixed.  All that needs to be done is for the
relocation to be applied to the section contents.  The following might
need some tweaking (eg. you've already said my "wild guess" patch didn't
work, although I'm still of the opinion it's logically correct) to suit
any further bugs you might find in Sun's dynamic linkers, but the general
idea ought to work.  The beauty is that changing the section contents
won't break dynamic linkers that behave correctly.

Index: elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.34
diff -u -p -r1.34 elf32-sparc.c
--- elf32-sparc.c	2001/12/17 00:52:35	1.34
+++ elf32-sparc.c	2001/12/19 06:58:44
@@ -1415,6 +1415,7 @@ elf32_sparc_relocate_section (output_bfd
 	    {
 	      Elf_Internal_Rela outrel;
 	      boolean skip;
+	      boolean relocate;
 
 	      /* When generating a shared object, these relocations
                  are copied into the output file to be resolved at run
@@ -1449,6 +1450,7 @@ elf32_sparc_relocate_section (output_bfd
 		skip = true;
 	      outrel.r_offset += (input_section->output_section->vma
 				  + input_section->output_offset);
+	      outrel.r_addend = rel->r_addend;
 
 	      /* Optimize unaligned reloc usage now that we know where
 		 it finally resides.  */
@@ -1472,6 +1474,7 @@ elf32_sparc_relocate_section (output_bfd
 		  break;
 		}
 
+	      relocate = false;
 	      if (skip)
 		memset (&outrel, 0, sizeof outrel);
 	      /* h->dynindx may be -1 if the symbol was marked to
@@ -1483,14 +1486,15 @@ elf32_sparc_relocate_section (output_bfd
 		{
 		  BFD_ASSERT (h->dynindx != -1);
 		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
-		  outrel.r_addend = rel->r_addend;
 		}
 	      else
 		{
+		  relocate = true;
+		  outrel.r_addend += relocation;
+
 		  if (r_type == R_SPARC_32)
 		    {
 		      outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
-		      outrel.r_addend = relocation + rel->r_addend;
 		    }
 		  else
 		    {
@@ -1505,6 +1509,7 @@ elf32_sparc_relocate_section (output_bfd
 					  == bfd_link_hash_defweak));
 			  sec = h->root.u.def.section;
 			}
+
 		      if (sec != NULL && bfd_is_abs_section (sec))
 			indx = 0;
 		      else if (sec == NULL || sec->owner == NULL)
@@ -1530,10 +1535,16 @@ elf32_sparc_relocate_section (output_bfd
 			      bfd_set_error (bfd_error_bad_value);
 			      return false;
 			    }
+
+			  /* We are turning this relocation into one
+			     against a section symbol, so subtract out
+			     the output section's address but not the
+			     offset of the input section in the output
+			     section.  */
+			  outrel.r_addend -= osec->vma;
 			}
 
 		      outrel.r_info = ELF32_R_INFO (indx, r_type);
-		      outrel.r_addend = relocation + rel->r_addend;
 		    }
 		}
 
@@ -1544,8 +1555,11 @@ elf32_sparc_relocate_section (output_bfd
 	      ++sreloc->reloc_count;
 
 	      /* This reloc will be computed at runtime, so there's no
-                 need to do anything now.  */
-	      continue;
+                 need to do anything now.  Sigh, except that the Solaris
+		 2.5.1 and 2.6 dynamic linker use the section contents when
+		 relocating dynamic relocs against local symbols.  */
+	      if (!relocate)
+		continue;
 	    }
 	  break;
 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 18:41 R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again DJ Delorie
  2001-12-18 18:51 ` Ian Lance Taylor
  2001-12-18 19:03 ` Alan Modra
@ 2001-12-19  0:45 ` Jakub Jelinek
  2 siblings, 0 replies; 26+ messages in thread
From: Jakub Jelinek @ 2001-12-19  0:45 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-bugs, binutils

On Tue, Dec 18, 2001 at 09:31:35PM -0500, DJ Delorie wrote:
> 
> Ok, I seem to have bumped into a "this just isn't possible" scenario.
> 
> We create unaligned 32-bit pointers in unwind tables (specifically,
> in the augmentation fields for context->lsda in gcc/unwind-dw2.c).
> 
> If these pointers are in a shared library, the dynamic linker needs to
> adjust them according to where the shared library is loaded.
> 
> However, the only reloc available for that is R_SPARC_RELATIVE, and it
> requires aligned data.  If you try to use it with unaligned data,
> ld.so aborts.  If you don't use it, unwinding causes aborts because
> the pointer points to the wrong place.
> 
> Could we make that pointer fde-relative or something, so that ld.so
> doesn't need to adjust it?  Or make it aligned?  I can't think of any
> other fix, unless there's some other R_SPARC_* reloc that does what's
> needed here.

Yes, we surely should make it fde-relative.
There are 2 ways of doing this:
1) (the preferable) - I need to revive a patch to introduce
   %r_disp{8,16,32,64} and %r_plt{32,64} (the former is Solaris way
   of doing x-.)
2) the .eh_frame code is able to automatically make relative
   initial_location and LSDA pointers from absolute ones (provided gcc
   creates an R resp. L augmentation), but this is currently disabled
   since some ELF backends need to be slightly changed for this.
The former is preferable, since 2) would only be able to change
SPARC 64-bit DW_EH_PE_absptr|DW_EH_PE_udata8 to
DW_EH_PE_pcrel|DW_EH_PE_udata8, while with 1) it could be
DW_EH_PE_pcrel|DW_EH_PE_sdata4.

As for what's going on with R_SPARC_UA32 in your case, I'll check it out
today if time permits.

	Jakub

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-18 20:24         ` Alan Modra
  2001-12-18 20:37           ` DJ Delorie
@ 2001-12-19  0:57           ` Jakub Jelinek
  2001-12-19  5:54             ` Jakub Jelinek
  1 sibling, 1 reply; 26+ messages in thread
From: Jakub Jelinek @ 2001-12-19  0:57 UTC (permalink / raw)
  To: DJ Delorie, gcc-bugs, binutils; +Cc: drepper, rth, davem

On Wed, Dec 19, 2001 at 02:52:11PM +1030, Alan Modra wrote:
> #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
>       const Elf32_Sym *const refsym = sym;
> #endif
>       Elf32_Addr value;
> #ifndef RESOLVE_CONFLICT_FIND_MAP
>       if (sym->st_shndx != SHN_UNDEF &&
> 	  ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
> 	value = map->l_addr;

I don't know exactly what is this for, but in powerpc/dl-machine.h above
similar code is:

  /* The condition on the next two lines is a hack around a bug in Solaris
     tools on Sparc.  It's not clear whether it should really be here at all,
     but if not the binutils need to be changed.  */

If this is what Solaris used to do in their ld.so (which wouldn't surprise
me, theer have been other ld.so bugs found in the past), then IMHO the best things
to fix this up are:
1) check all shared libraries on say 2 different sparc linux distros to
   search for section relative dynamic relocs
2) if none are found, kill the above code from glibc
3) change binutils, so that it never creates section relative dynamic relocs
   for shared libs (because ld.so cannot be trusted). It could change the
   dynamic reloc to ELF32_R_INFO (0, non-R_SPARC_RELATIVE) and adjust addend
   accordingly.

	Jakub

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-19  0:57           ` Jakub Jelinek
@ 2001-12-19  5:54             ` Jakub Jelinek
  2001-12-19  6:03               ` Alan Modra
  0 siblings, 1 reply; 26+ messages in thread
From: Jakub Jelinek @ 2001-12-19  5:54 UTC (permalink / raw)
  To: DJ Delorie, gcc-bugs, binutils

On Wed, Dec 19, 2001 at 09:59:25AM +0100, Jakub Jelinek wrote:
> On Wed, Dec 19, 2001 at 02:52:11PM +1030, Alan Modra wrote:
> > #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
> >       const Elf32_Sym *const refsym = sym;
> > #endif
> >       Elf32_Addr value;
> > #ifndef RESOLVE_CONFLICT_FIND_MAP
> >       if (sym->st_shndx != SHN_UNDEF &&
> > 	  ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
> > 	value = map->l_addr;
> 
> I don't know exactly what is this for, but in powerpc/dl-machine.h above
> similar code is:
> 
>   /* The condition on the next two lines is a hack around a bug in Solaris
>      tools on Sparc.  It's not clear whether it should really be here at all,
>      but if not the binutils need to be changed.  */
> 
> If this is what Solaris used to do in their ld.so (which wouldn't surprise
> me, theer have been other ld.so bugs found in the past), then IMHO the best things
> to fix this up are:
> 1) check all shared libraries on say 2 different sparc linux distros to
>    search for section relative dynamic relocs
> 2) if none are found, kill the above code from glibc
> 3) change binutils, so that it never creates section relative dynamic relocs
>    for shared libs (because ld.so cannot be trusted). It could change the
>    dynamic reloc to ELF32_R_INFO (0, non-R_SPARC_RELATIVE) and adjust addend
>    accordingly.

Ok, after checking the real situation:
1) many libraries do so (e.g. all with non-fPIC objects)
2) glibc code matches what does Solaris 8 ld.so and what Solaris ld creates:
   relocs against STB_LOCAL symbols have addend which is relative to
   library VMA, not the actual STB_LOCAL symbol value
As I have no access to Solaris 2.5, I cannot tell more. Is it just
R_SPARC_UA32 which doesn't work properly (e.g. if you put sethi %hi(.data + 35), %o0
into some writeable section (Solaris ld doesn't want to create DT_TEXTREL
apparently), does it resolve properly)?

	Jakub

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-19  5:54             ` Jakub Jelinek
@ 2001-12-19  6:03               ` Alan Modra
  2001-12-19  6:14                 ` Jakub Jelinek
  2001-12-19 10:08                 ` DJ Delorie
  0 siblings, 2 replies; 26+ messages in thread
From: Alan Modra @ 2001-12-19  6:03 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: DJ Delorie, gcc-bugs, binutils

On Wed, Dec 19, 2001 at 02:18:57PM +0100, Jakub Jelinek wrote:
> 
> 2) glibc code matches what does Solaris 8 ld.so and what Solaris ld creates:
>    relocs against STB_LOCAL symbols have addend which is relative to
>    library VMA, not the actual STB_LOCAL symbol value

ie. behave as a reloc against STN_UNDEF.  Sounds like your idea of
avoiding any section symbol relocs is the cure.

DJ, try this patch:

Index: bfd/elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.34
diff -u -p -r1.34 elf32-sparc.c
--- elf32-sparc.c	2001/12/17 00:52:35	1.34
+++ elf32-sparc.c	2001/12/19 13:50:25
@@ -1415,6 +1415,7 @@ elf32_sparc_relocate_section (output_bfd
 	    {
 	      Elf_Internal_Rela outrel;
 	      boolean skip;
+	      boolean relocate;
 
 	      /* When generating a shared object, these relocations
                  are copied into the output file to be resolved at run
@@ -1449,6 +1450,7 @@ elf32_sparc_relocate_section (output_bfd
 		skip = true;
 	      outrel.r_offset += (input_section->output_section->vma
 				  + input_section->output_offset);
+	      outrel.r_addend = rel->r_addend;
 
 	      /* Optimize unaligned reloc usage now that we know where
 		 it finally resides.  */
@@ -1472,6 +1474,7 @@ elf32_sparc_relocate_section (output_bfd
 		  break;
 		}
 
+	      relocate = false;
 	      if (skip)
 		memset (&outrel, 0, sizeof outrel);
 	      /* h->dynindx may be -1 if the symbol was marked to
@@ -1483,57 +1486,27 @@ elf32_sparc_relocate_section (output_bfd
 		{
 		  BFD_ASSERT (h->dynindx != -1);
 		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
-		  outrel.r_addend = rel->r_addend;
 		}
 	      else
 		{
+		  relocate = true;
+		  outrel.r_addend += relocation;
+
 		  if (r_type == R_SPARC_32)
 		    {
 		      outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
-		      outrel.r_addend = relocation + rel->r_addend;
 		    }
 		  else
 		    {
-		      long indx;
-
-		      if (h == NULL)
-			sec = local_sections[r_symndx];
-		      else
-			{
-			  BFD_ASSERT (h->root.type == bfd_link_hash_defined
-				      || (h->root.type
-					  == bfd_link_hash_defweak));
-			  sec = h->root.u.def.section;
-			}
-		      if (sec != NULL && bfd_is_abs_section (sec))
-			indx = 0;
-		      else if (sec == NULL || sec->owner == NULL)
-			{
-			  bfd_set_error (bfd_error_bad_value);
-			  return false;
-			}
-		      else
-			{
-			  asection *osec;
-
-			  osec = sec->output_section;
-			  indx = elf_section_data (osec)->dynindx;
-
-			  /* FIXME: we really should be able to link non-pic
-			     shared libraries.  */
-			  if (indx == 0)
-			    {
-			      BFD_FAIL ();
-			      (*_bfd_error_handler)
-				(_("%s: probably compiled without -fPIC?"),
-				 bfd_archive_filename (input_bfd));
-			      bfd_set_error (bfd_error_bad_value);
-			      return false;
-			    }
-			}
+		      /* Normally we would turn some cases of this reloc
+			 against a local sym into one against the relevant
+			 section symbol, but the Solaris 8 (and earlier)
+			 dynamic linkers ignore the symbol value.  ie.
+			 behave as if the reloc was against index 0,
+			 STN_UNDEF for all local syms.  So avoid confusing
+			 the issue with ignored section syms.  */
 
-		      outrel.r_info = ELF32_R_INFO (indx, r_type);
-		      outrel.r_addend = relocation + rel->r_addend;
+		      outrel.r_info = ELF32_R_INFO (0, r_type);
 		    }
 		}
 
@@ -1544,8 +1517,11 @@ elf32_sparc_relocate_section (output_bfd
 	      ++sreloc->reloc_count;
 
 	      /* This reloc will be computed at runtime, so there's no
-                 need to do anything now.  */
-	      continue;
+                 need to do anything now.  Sigh, except that the Solaris
+		 2.5.1 and 2.6 dynamic linker use the section contents when
+		 resolving dynamic relocs against local symbols.  */
+	      if (!relocate)
+		continue;
 	    }
 	  break;
 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-19  6:03               ` Alan Modra
@ 2001-12-19  6:14                 ` Jakub Jelinek
  2001-12-19 10:11                   ` DJ Delorie
  2001-12-19 10:08                 ` DJ Delorie
  1 sibling, 1 reply; 26+ messages in thread
From: Jakub Jelinek @ 2001-12-19  6:14 UTC (permalink / raw)
  To: DJ Delorie, gcc-bugs, binutils

On Thu, Dec 20, 2001 at 12:24:10AM +1030, Alan Modra wrote:
> On Wed, Dec 19, 2001 at 02:18:57PM +0100, Jakub Jelinek wrote:
> > 
> > 2) glibc code matches what does Solaris 8 ld.so and what Solaris ld creates:
> >    relocs against STB_LOCAL symbols have addend which is relative to
> >    library VMA, not the actual STB_LOCAL symbol value
> 
> ie. behave as a reloc against STN_UNDEF.  Sounds like your idea of
> avoiding any section symbol relocs is the cure.

I'd prefer to find out first what exactly is broken in Solars 2.5 ld.so.
DJ, can you try to build a shared library from say:
.data
1: .word 0xdeadbeef, 0xbeefdead, 0xabcdef01
.section ".textw", #alloc, #write, #execinstr
.global foo
foo:
sethi %hi(1b + 4), %o0
retl
or %o0, %lo(1b + 4), %o0
.byte 1
.uaword 1b + 8

and see what the dynamic linker does?
Current binutils end up with:
Relocation section '.rela.textw' at offset 0x2a0 contains 3 entries:
 Offset     Info    Type            Symbol's Value  Symbol's Name          Addend
000002c4  00000609 R_SPARC_HI22          000102d8  .data                     + 102dc
000002cc  0000060c R_SPARC_LO10          000102d8  .data                     + 102dc
000002d1  00000617 R_SPARC_UA32          000102d8  .data                     + 102d8

Symbol table '.dynsym' contains 18 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000094     0 SECTION LOCAL  DEFAULT    1
     2: 00000128     0 SECTION LOCAL  DEFAULT    2
     3: 00000248     0 SECTION LOCAL  DEFAULT    3
     4: 000002a0     0 SECTION LOCAL  DEFAULT    4
     5: 000002c4     0 SECTION LOCAL  DEFAULT    5
     6: 000102d8     0 SECTION LOCAL  DEFAULT    6
     7: 000102e0     0 SECTION LOCAL  DEFAULT    7
     8: 00010358     0 SECTION LOCAL  DEFAULT    8
     9: 00010358     0 SECTION LOCAL  DEFAULT    9
    10: 0001035c     0 SECTION LOCAL  DEFAULT   10

and as far as I could see, this worked well both on sparc linux and Solaris 2.8.

	Jakub

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-19  6:03               ` Alan Modra
  2001-12-19  6:14                 ` Jakub Jelinek
@ 2001-12-19 10:08                 ` DJ Delorie
  1 sibling, 0 replies; 26+ messages in thread
From: DJ Delorie @ 2001-12-19 10:08 UTC (permalink / raw)
  To: amodra; +Cc: jakub, gcc-bugs, binutils


> DJ, try this patch:

Still broke.

$ objdump -R libdj-s.so

libdj-s.so:     file format elf32-sparc

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
00000304 R_SPARC_HI22      z
00000308 R_SPARC_LO10      z
00010319 R_SPARC_UA32      *ABS*+0x00010315

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-19  6:14                 ` Jakub Jelinek
@ 2001-12-19 10:11                   ` DJ Delorie
  2001-12-19 10:24                     ` Jakub Jelinek
  0 siblings, 1 reply; 26+ messages in thread
From: DJ Delorie @ 2001-12-19 10:11 UTC (permalink / raw)
  To: jakub; +Cc: gcc-bugs, binutils


ld.so.1: ./dj-b.exe: fatal: relocation error: R_SPARC_HI22: file ./libdj-s.so:  symbol (unknown):  offset 0xffffffffef7a038d is non-aligned
ld.so.1: ./dj-b.exe: fatal: relocation error: R_SPARC_LO10: file ./libdj-s.so:  symbol (unknown):  offset 0xffffffffef7a0395 is non-aligned

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-19 10:11                   ` DJ Delorie
@ 2001-12-19 10:24                     ` Jakub Jelinek
  2001-12-19 10:47                       ` DJ Delorie
  0 siblings, 1 reply; 26+ messages in thread
From: Jakub Jelinek @ 2001-12-19 10:24 UTC (permalink / raw)
  To: DJ Delorie; +Cc: binutils

On Wed, Dec 19, 2001 at 01:07:29PM -0500, DJ Delorie wrote:
> 
> ld.so.1: ./dj-b.exe: fatal: relocation error: R_SPARC_HI22: file ./libdj-s.so:  symbol (unknown):  offset 0xffffffffef7a038d is non-aligned
> ld.so.1: ./dj-b.exe: fatal: relocation error: R_SPARC_LO10: file ./libdj-s.so:  symbol (unknown):  offset 0xffffffffef7a0395 is non-aligned

What about if you add .align 4 before the instructions?

	Jakub

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again
  2001-12-19 10:24                     ` Jakub Jelinek
@ 2001-12-19 10:47                       ` DJ Delorie
  0 siblings, 0 replies; 26+ messages in thread
From: DJ Delorie @ 2001-12-19 10:47 UTC (permalink / raw)
  To: jakub; +Cc: binutils


> What about if you add .align 4 before the instructions?

Works OK with a .align before the "foo:"

$ ./dj-b.exe 
0xef7a037c =  be ef de ad ab cd ef 01 00

But the uaword after foo() is still wrong:

(gdb) x/10x foo
0xef7a0390 <foo>:       0x113bde80      0x81c3e008      0x9012237c      0x01007a03
0xef7a03a0 <foo+16>:    0x80000000      0x00000004      0x00000094      0x00000005
0xef7a03b0 <foo+32>:    0x000002c0      0x00000006

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2001-12-19 18:24 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-18 18:41 R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again DJ Delorie
2001-12-18 18:51 ` Ian Lance Taylor
2001-12-18 18:57   ` DJ Delorie
2001-12-18 18:57     ` Ian Lance Taylor
2001-12-18 19:03 ` Alan Modra
2001-12-18 19:21   ` DJ Delorie
2001-12-18 19:23     ` Alan Modra
2001-12-18 19:56       ` DJ Delorie
2001-12-18 20:19         ` Ian Lance Taylor
2001-12-18 20:22           ` DJ Delorie
2001-12-18 20:24         ` Alan Modra
2001-12-18 20:37           ` DJ Delorie
2001-12-18 20:44             ` Alan Modra
2001-12-18 21:03               ` DJ Delorie
2001-12-18 23:12                 ` Alan Modra
2001-12-18 20:59             ` Ian Lance Taylor
2001-12-18 21:25               ` DJ Delorie
2001-12-19  0:57           ` Jakub Jelinek
2001-12-19  5:54             ` Jakub Jelinek
2001-12-19  6:03               ` Alan Modra
2001-12-19  6:14                 ` Jakub Jelinek
2001-12-19 10:11                   ` DJ Delorie
2001-12-19 10:24                     ` Jakub Jelinek
2001-12-19 10:47                       ` DJ Delorie
2001-12-19 10:08                 ` DJ Delorie
2001-12-19  0:45 ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).