This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Bad patch to elf.c.
- To: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
- Subject: Re: Bad patch to elf.c.
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Thu, 12 Oct 2000 03:10:04 +1100 (EST)
- cc: "H . J . Lu" <hjl at lucon dot org>, binutils at sourceware dot cygnus dot com
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;