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: Bad patch to elf.c.


On Wed, 11 Oct 2000, Maciej W. Rozycki wrote:

> On Wed, 11 Oct 2000, Alan Modra wrote:
> 
> > > After backing out elf.c and gas/config/obj-elf.c changes, everything
> > > is back to normal for me.
> > 
> > I'm going to revert the changes on sourceware CVS as I don't have time to
> > track the problem down.  global section symbols are probably a bad idea.
> 
>  I'll see how linkonce section symbols can be marked as local on the final
> link.  I already have MIPS changes ready, but I'll post them as a part of
> the whole solution. 

The attached patch seems to work for me, but I'll sleep on it first before
committing to CVS.  You may find a more elegant solution too.  Builds CVS
gcc with --enable-shared and passes make check with no new regressions
that I noticed.

Regards, Alan Modra
-- 
Linuxcare.  Support for the Revolution.

Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.67
diff -u -p -r1.67 bfd-in2.h
--- bfd-in2.h	2000/09/15 18:52:12	1.67
+++ bfd-in2.h	2000/10/11 15:46:39
@@ -1219,6 +1219,10 @@ typedef struct sec
 
   struct bfd_comdat_info *comdat;
 
+  /* Points to the kept section if this section is a link-once section,
+     and is discarded.  */
+  struct sec *kept_section;
+
   /* When a section is being output, this value changes as more
      linenumbers are written out.  */
 
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.73
diff -u -p -r1.73 elflink.h
--- elflink.h	2000/10/07 13:40:33	1.73
+++ elflink.h	2000/10/11 15:47:02
@@ -1371,8 +1371,6 @@ elf_link_add_object_symbols (abfd, info)
 	  if (sym.st_shndx != SHN_UNDEF
 	      && sym.st_shndx != SHN_COMMON)
 	    flags = BSF_GLOBAL;
-	  else
-	    flags = 0;
 	}
       else if (bind == STB_WEAK)
 	flags = BSF_WEAK;
@@ -5536,14 +5534,66 @@ elf_link_input_bfd (finfo, input_bfd)
       if (esym == external_syms)
 	continue;
 
+      if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+	{
+	  asection *ksec;
+	  bfd *kbfd;
+
+	  /* Save away all section symbol values (ab)using
+	     elf_section_syms.  */
+	  if (elf_section_syms (input_bfd) == NULL)
+	    {
+	      bfd_vma *ssyms;
+	      asection *asect;
+	      int max_index = 0;
+
+	      for (asect = input_bfd->sections; asect; asect = asect->next)
+		if (max_index < asect->index)
+		  max_index = asect->index;
+
+	      max_index++;
+	      ssyms = (bfd_vma *)
+		bfd_zalloc (input_bfd, max_index * sizeof (bfd_vma));
+	      if (ssyms == NULL)
+		return false;
+	      elf_section_syms (input_bfd) = (asymbol **) ssyms;
+	    }
+
+	  if (isec != NULL)
+	    ((bfd_vma *) (elf_section_syms (input_bfd)))[isec->index]
+	      = isym->st_value;
+
+	  /* If this is a discarded link-once section, update it's
+	     value to that of the kept section symbol.  The linker
+	     will keep the first of any matching link-once sections,
+	     so we should have already saved it's section symbol.
+	     I trust no-one will have the bright idea of re-ordering
+	     the bfd list...  */
+	  if (isec != NULL
+	      && (bfd_get_section_flags (input_bfd, isec) & SEC_LINK_ONCE) != 0
+	      && (ksec = isec->kept_section) != NULL
+	      && (kbfd = ksec->owner) != NULL
+	      && bfd_get_flavour (kbfd) == bfd_target_elf_flavour
+	      && elf_section_syms (kbfd) != NULL)
+	    {
+	      isym->st_value =
+		((bfd_vma *) (elf_section_syms (kbfd)))[ksec->index];
+
+	      /* That put the value right, but the section info is all
+		 wrong.  I hope this works.  */
+	      isec->output_offset = ksec->output_offset;
+	      isec->output_section = ksec->output_section;
+	    }
+
+	  /* We never output section symbols.  Instead, we use the
+	     section symbol of the corresponding section in the output
+	     file.  */
+	  continue;
+	}
+
       /* If we are stripping all symbols, we don't want to output this
 	 one.  */
       if (finfo->info->strip == strip_all)
-	continue;
-
-      /* We never output section symbols.  Instead, we use the section
-	 symbol of the corresponding section in the output file.  */
-      if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
 	continue;
 
       /* If we are discarding all local symbols, we don't want to
Index: bfd/section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.24
diff -u -p -r1.24 section.c
--- section.c	2000/10/10 15:23:38	1.24
+++ section.c	2000/10/11 15:47:06
@@ -471,6 +471,10 @@ CODE_FRAGMENT
 .
 .  struct bfd_comdat_info *comdat;
 .
+.  {* Points to the kept section if this section is a link-once section,
+.     and is discarded.  *}
+.  struct sec *kept_section;
+.
 .  {* When a section is being output, this value changes as more
 .     linenumbers are written out.  *}
 .
@@ -578,11 +582,11 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */	\
        0,            NULL,     NULL,     NULL,   0,			\
 									\
-    /* comdat, moving_line_filepos, target_index, used_by_bfd,       */	\
-       NULL,   0,                   0,            NULL,			\
+    /* comdat, kept_section, moving_line_filepos, target_index,      */	\
+       NULL,   NULL,         0,                   0,			\
 									\
-    /* constructor_chain, owner,                                     */	\
-       NULL,              NULL,						\
+    /* used_by_bfd, constructor_chain, owner,                        */	\
+       NULL,        NULL,              NULL,				\
 									\
     /* symbol,                                                       */	\
        (struct symbol_cache_entry *) &global_syms[IDX],			\
@@ -789,6 +793,7 @@ bfd_make_section_anyway (abfd, name)
   newsect->line_filepos = 0;
   newsect->owner = abfd;
   newsect->comdat = NULL;
+  newsect->kept_section = NULL;
 
   /* Create a symbol whos only job is to point to this section. This is
      useful for things like relocs which are relative to the base of a
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.33
diff -u -p -r1.33 ldlang.c
--- ldlang.c	2000/10/09 15:09:17	1.33
+++ ldlang.c	2000/10/11 15:58:24
@@ -995,6 +995,7 @@ section_already_linked (abfd, sec, data)
 	     discarded, we must retain a pointer to the section which
 	     we are really going to use.  */
 	  sec->output_section = bfd_abs_section_ptr;
+	  sec->kept_section = l->sec;
 	  if (sec->comdat != NULL)
 	    sec->comdat->sec = l->sec;
 



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