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.
> 

Reply via email to