On Sat, Mar 02, 2013 at 10:36:50AM -0500, Brian Callahan wrote: > Hi tech -- > > While doing some ports testing with clang, I came across the > binutils bug mentioned here: > http://lists.gnu.org/archive/html/bug-binutils/2004-07/msg00000.html > > Below is a backport of the commit mentioned later in the thread. It > fixes the issue. > I was able to rebuild working kernels and do a full 'make build' on > amd64, loongson, and macppc with this patch. But since it affects > all archs, testing on the archs I don't have access to will be > needed. > > OK?
This patch does not apply, it seems your mail client is wrapping lines. > > ~Brian > > Index: elf-bfd.h > =================================================================== > RCS file: /cvs/src/gnu/usr.bin/binutils/bfd/elf-bfd.h,v > retrieving revision 1.8 > diff -u -p -r1.8 elf-bfd.h > --- elf-bfd.h 2 Nov 2004 20:45:06 -0000 1.8 > +++ elf-bfd.h 16 Feb 2013 22:43:53 -0000 > @@ -1055,8 +1055,8 @@ struct bfd_elf_section_data > #define elf_discarded_section(sec) \ > (!bfd_is_abs_section (sec) \ > && bfd_is_abs_section ((sec)->output_section) \ > - && sec->sec_info_type != ELF_INFO_TYPE_MERGE \ > - && sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS) > + && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \ > + && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS) > > #define get_elf_backend_data(abfd) \ > ((const struct elf_backend_data *) (abfd)->xvec->backend_data) > Index: elflink.c > =================================================================== > RCS file: /cvs/src/gnu/usr.bin/binutils/bfd/elflink.c,v > retrieving revision 1.9 > diff -u -p -r1.9 elflink.c > --- elflink.c 24 Nov 2004 16:55:31 -0000 1.9 > +++ elflink.c 16 Feb 2013 22:43:56 -0000 > @@ -6239,6 +6239,9 @@ elf_link_output_extsym (struct elf_link_ > return TRUE; > } > > +/* Return TRUE if special handling is done for relocs in SEC against > + symbols defined in discarded sections. */ > + > static bfd_boolean > elf_section_ignore_discarded_relocs (asection *sec) > { > @@ -6261,6 +6264,26 @@ elf_section_ignore_discarded_relocs (ase > return FALSE; > } > > +/* Return TRUE if we should complain about a reloc in SEC against a > + symbol defined in a discarded section. */ > + > +static bfd_boolean > +elf_section_complain_discarded (asection *sec) > +{ > + if (strncmp (".stab", sec->name, 5) == 0 > + && (!sec->name[5] || > + (sec->name[5] == '.' && ISDIGIT (sec->name[6])))) > + return FALSE; > + > + if (strcmp (".eh_frame", sec->name) == 0) > + return FALSE; > + > + if (strcmp (".gcc_except_table", sec->name) == 0) > + return FALSE; > + > + return TRUE; > +} > + > /* Link an input file into the linker output file. This function > handles all the sections and relocations of the input file at once. > This is so that we only have to read the local symbols once, and > @@ -6532,13 +6555,16 @@ elf_link_input_bfd (struct elf_final_lin > if (!elf_section_ignore_discarded_relocs (o)) > { > Elf_Internal_Rela *rel, *relend; > + bfd_boolean complain = elf_section_complain_discarded (o); > > rel = internal_relocs; > relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel; > for ( ; rel < relend; rel++) > { > unsigned long r_symndx = rel->r_info >> r_sym_shift; > - asection *sec; > + asection **ps, *sec; > + struct elf_link_hash_entry *h = NULL; > + const char *sym_name; > > if (r_symndx >= locsymcount > || (elf_bad_symtab (input_bfd) > @@ -6551,79 +6577,70 @@ elf_link_input_bfd (struct elf_final_lin > || h->root.type == bfd_link_hash_warning) > h = (struct elf_link_hash_entry *) h->root.u.i.link; > > - /* Complain if the definition comes from a > - discarded section. */ > - sec = h->root.u.def.section; > - if ((h->root.type == bfd_link_hash_defined > - || h->root.type == bfd_link_hash_defweak) > - && elf_discarded_section (sec)) > - { > - if ((o->flags & SEC_DEBUGGING) != 0) > - { > - BFD_ASSERT (r_symndx != 0); > - /* Try to preserve debug information. */ > - if ((o->flags & SEC_DEBUGGING) != 0 > - && sec->kept_section != NULL > - && sec->_raw_size == sec->kept_section->_raw_size) > - h->root.u.def.section > - = sec->kept_section; > - else > - memset (rel, 0, sizeof (*rel)); > - } > - else > - finfo->info->callbacks->error_handler > - (LD_DEFINITION_IN_DISCARDED_SECTION, > - _("%T: discarded in section `%s' from %s\n"), > - h->root.root.string, > - h->root.root.string, > - h->root.u.def.section->name, > - bfd_archive_filename (h->root.u.def.section->owner)); > - } > - } > - else > - { > - sec = finfo->sections[r_symndx]; > - > - if (sec != NULL && elf_discarded_section (sec)) > - { > - if ((o->flags & SEC_DEBUGGING) != 0 > - || (sec->flags & SEC_LINK_ONCE) != 0) > - { > - BFD_ASSERT (r_symndx != 0); > - /* Try to preserve debug information. */ > - if ((o->flags & SEC_DEBUGGING) != 0 > - && sec->kept_section != NULL > - && sec->_raw_size == sec->kept_section->_raw_size) > - finfo->sections[r_symndx] > - = sec->kept_section; > - else > - { > - rel->r_info &= r_type_mask; > - rel->r_addend = 0; > - } > - } > - else > - { > - static int count; > - int ok; > - char *buf; > - > - ok = asprintf (&buf, "local symbol %d", > - count++); > - if (ok <= 0) > - buf = (char *) "local symbol"; > - finfo->info->callbacks->error_handler > - (LD_DEFINITION_IN_DISCARDED_SECTION, > - _("%T: discarded in section `%s' from %s\n"), > - buf, buf, sec->name, > - bfd_archive_filename (input_bfd)); > - if (ok != -1) > - free (buf); > - } > - } > - } > - } > - } > + if (h->root.type != bfd_link_hash_defined > + && h->root.type != bfd_link_hash_defweak) > + continue; > + > + ps = &h->root.u.def.section; > + sym_name = h->root.root.string; > + } > + else > + { > + Elf_Internal_Sym *sym = isymbuf + r_symndx; > + ps = &finfo->sections[r_symndx]; > + sym_name = bfd_elf_local_sym_name (input_bfd, sym); > + } > + > + /* Complain if the definition comes from a > + discarded section. */ > + if ((sec = *ps) != NULL && elf_discarded_section (sec)) > + { > + if ((o->flags & SEC_DEBUGGING) != 0) > + { > + BFD_ASSERT (r_symndx != 0); > + > + /* Try to preserve debug information. > + FIXME: This is quite broken. Modifying > + the symbol here means we will be changing > + all uses of the symbol, not just those in > + debug sections. The only thing that makes > + this half reasonable is that debug sections > + tend to come after other sections. Of > + course, that doesn't help with globals. > + ??? All link-once sections of the same name > + ought to define the same set of symbols, so > + it would seem that globals ought to always > + be defined in the kept section. */ > + if (sec->kept_section != NULL > + && sec->_cooked_size == > sec->kept_section->_cooked_size) > + { > + *ps = sec->kept_section; > + continue; > + } > + } > + else if (complain) > + { > + finfo->info->callbacks->error_handler > + (LD_DEFINITION_IN_DISCARDED_SECTION, > + _("`%T' referenced in section `%s' of %B: " > + "defined in discarded section `%s' > of %B\n"), > + sym_name, > + sym_name, o->name, input_bfd, > + sec->name, sec->owner); > + } > + > + /* Remove the symbol reference from the reloc, but > + don't kill the reloc completely. This is so that > + a zero value will be written into the section, > + which may have non-zero contents put there by the > + assembler. Zero in things like an eh_frame fde > + pc_begin allows stack unwinders to recognize the > + fde as bogus. */ > + rel->r_info &= r_type_mask; > + rel->r_addend = 0; > + } > + } > + } > > /* Relocate the section by invoking a back end routine. >