This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Is the current ld brolen? (Re: ld is broken on Linux/alpha)
On Mon, Nov 26, 2001 at 09:40:18AM +1030, Alan Modra wrote:
> On Sun, Nov 25, 2001 at 12:44:47PM -0500, Jakub Jelinek wrote:
> > On Sat, Nov 24, 2001 at 11:24:39PM -0800, H . J . Lu wrote:
> > > Does your gcc support SHF_MERGE/STT_SECTION?
> >
> > Surely I was.
> >
> > > Did you see the linker messages during the build?
> >
> > I missed them in the log but now I'm seeing there too:
> >
> > .section .rodata.str1.1,"aMS",@progbits,1
> > .LC0:
> > .string "."
> > ...
> > leal 5+.LC0@GOTOFF(%ebx), %ecx
> >
> > No idea why it takes address 3 bytes beyond end of the string.
> > (in C there is strcpy(buf, "."); ).
>
> I'll bet this is due to glibc's strcpy optimisations. See
> include/bits/string2.h, __strcpy_args. Some of what should be dead code
> does access beyond the string, by why the dead code isn't being trimmed
> off is another queation.
There are multiple things. One is that most of string2.h optimizations
have to go for recent gcc versions, because gcc does a better job, second is
I'd like to see why gcc does that poor job on strcpy small with -O2 -fPIC
(while with -O2 alone it optimizes it fully).
And the last thing is that I'm afraid following change is needed, because
char *p = ".", *q = p + sizeof("."); while (--q > p) dosomething;
needs to be supported IMHO and this wouldn't work (because "." + 2 would be
considered as next string after "." which might be anywhere in the final
.rodata section and not necessarily right after ".").
This patch just doesn't keep SEC_MERGE local symbols in debugging section,
where such problems don't exist (and it saves a lot of space).
Ok to commit?
2001-11-26 Jakub Jelinek <jakub@redhat.com>
* write.c (adjust_reloc_syms): Mark SEC_MERGE symbols as used
in reloc unless it is in debugging section.
(fixup_segment): Treat such symbols accordingly.
--- gas/write.c.jj Fri Nov 23 14:26:42 2001
+++ gas/write.c Mon Nov 26 12:35:56 2001
@@ -873,6 +873,13 @@ adjust_reloc_syms (abfd, sec, xxx)
symbol_mark_used_in_reloc (fixp->fx_addsy);
goto done;
}
+
+ /* Never adjust a reloc against local symbol in a merge section. */
+ if ((symsec->flags & (SEC_MERGE | SEC_DEBUGGING)) == SEC_MERGE)
+ {
+ symbol_mark_used_in_reloc (fixp->fx_addsy);
+ goto done;
+ }
#endif
/* Is there some other reason we can't adjust this one? (E.g.,
@@ -2808,6 +2815,9 @@ fixup_segment (fixP, this_segment_type)
else if (add_symbol_segment == undefined_section
#ifdef BFD_ASSEMBLER
|| bfd_is_com_section (add_symbol_segment)
+ || (bfd_get_section_flags (stdoutput,
+ add_symbol_segment)
+ & (SEC_MERGE | SEC_DEBUGGING)) != SEC_MERGE
#endif
)
{
Jakub