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]

[PATCH] SEC_MERGE fix (was Re: Is the current ld brolen? (Re: ld is broken on Linux/alpha))


On Mon, Nov 26, 2001 at 10:38:10PM +1030, Alan Modra wrote:
> On Mon, Nov 26, 2001 at 12:26:18PM +0100, Jakub Jelinek wrote:
> > 
> > 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?
> 
> Yes.
> 
> I wonder.  Perhaps it might be safe to distinguish between .Lxx+num
> and .Lxx, simplifying to the section sym in the latter case.

Actually, fx_offset != 0 check covers far more than SEC_DEBUGGING test,
so here it is instead.
I'm just not sure whether
http://sources.redhat.com/ml/binutils/2001-10/msg00253.html is correct or
not, because e.g. if such SEC_MERGE symbol is e.g. weak, the addend will be
bogus (as machine independent fixup_segment will decide not to adjust it,
but machine specific code will not know about it and thus will subtract it
because it is weak or some other reason why it should be unadjusted (I saw
this in as output on SPARC).
In that case, each port would have to take care of it (as in the patch
below), otherwise instead of the config/ changes fixup_segment should do it.

2001-11-26  Jakub Jelinek  <jakub@redhat.com>

	* write.c (adjust_reloc_syms): Mark SEC_MERGE symbols as used
	in reloc if it has non-zero addend.
	* config/tc-alpha.c (tc_gen_reloc): Reinstall SEC_MERGE check.
	* config/tc-sparc.c (md_apply_fix3): Likewise.

--- gas/config/tc-sparc.c.jj	Thu Nov 22 00:08:11 2001
+++ gas/config/tc-sparc.c	Mon Nov 26 18:04:15 2001
@@ -2909,12 +2909,7 @@ md_apply_fix3 (fixP, valP, segment)
       if (symbol_used_in_reloc_p (sym)
 	  && (S_IS_EXTERNAL (sym)
 	      || S_IS_WEAK (sym)
-#if 0 /* Although fixups against local symbols in SEC_MERGE sections
-	 should be treated as if they were against external symbols
-	 write.c:fixup_segment() will not have included the value of
-	 the symbol under these particular cicumstances.  */
 	      || (seg->flags & SEC_MERGE)
-#endif
 	      || (sparc_pic_code && ! fixP->fx_pcrel)
 	      || (seg != segment
 		  && (((bfd_get_section_flags (stdoutput, seg) & SEC_LINK_ONCE) != 0)
--- gas/config/tc-alpha.c.jj	Fri Nov 23 14:26:42 2001
+++ gas/config/tc-alpha.c	Mon Nov 26 18:08:34 2001
@@ -1507,7 +1507,8 @@ tc_gen_reloc (sec, fixp)
        * at assembly time.  bfd_perform_reloc doesn't know about this sort
        * of thing, and as a result we need to fake it out here.
        */
-      if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
+      if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
+	   || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
 	  && !S_IS_COMMON (fixp->fx_addsy))
 	reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
 #endif
--- gas/write.c.jj	Fri Nov 23 14:26:42 2001
+++ gas/write.c	Mon Nov 26 18:01:11 2001
@@ -873,6 +873,14 @@ 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
+	   with non-zero addend.  */
+	if ((symsec->flags & SEC_MERGE) && fixp->fx_offset)
+	  {
+	    symbol_mark_used_in_reloc (fixp->fx_addsy);
+	    goto done;
+	  }
 #endif
 
 	/* Is there some other reason we can't adjust this one?  (E.g.,


	Jakub


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