[patch bfd]: Some adjustments on coff-link.c

Kai Tietz ktietz70@googlemail.com
Sun Oct 9 19:18:00 GMT 2011


Hello,

Now at right ML.
This patch improves COFF linker for undefined weak symbols
and avoids writing symbols for discarded sections - if linker tells so
-, and for IR generated sections.

ChangeLog

2011-10-09  Kai Tietz  <ktietz@redhat.com>

       * cofflink.c (coff_link_check_ar_symbols): Allow
       adding of archive-file if symbol was undefined weak.
       (_bfd_coff_write_global_sym): Skip write for symbol
       in discared section, or if section is coming from IR, or
       if input section has explicit SEC_EXCLUDED set.
       (_bfd_coff_generic_relocate_section): For undefined weak
       symbol and replacing it by another undefined weak, mark
       section as absolute.

Regression tested for i686-w64-mingw32, x86_64-w64-mingw32, and
i686-pc-cygwin.  Ok for apply?

Regards,
Kai


Index: src/bfd/cofflink.c
===================================================================
--- src.orig/bfd/cofflink.c
+++ src/bfd/cofflink.c
@@ -242,7 +242,8 @@ coff_link_check_ar_symbols (bfd *abfd,
            COFF linkers do not bring in an object file which defines
            it.  */
         if (h != (struct bfd_link_hash_entry *) NULL
-             && h->type == bfd_link_hash_undefined)
+             && (h->type == bfd_link_hash_undefined
+                 || h->type == bfd_link_hash_undefweak))
           {
             if (!(*info->callbacks
                   ->add_archive_element) (info, abfd, name, subsbfd))
@@ -2527,6 +2528,7 @@ _bfd_coff_write_global_sym (struct bfd_h
  bfd_size_type symesz;
  unsigned int i;
  file_ptr pos;
+  asection *input_sec;

  output_bfd = finfo->output_bfd;

@@ -2547,6 +2549,21 @@ _bfd_coff_write_global_sym (struct bfd_h
                                  h->root.root.string, FALSE, FALSE)
                 == NULL))))
    return TRUE;
+  else if (h->indx != -2
+           && (h->root.type == bfd_link_hash_defined
+              || h->root.type == bfd_link_hash_defweak)
+          && ((finfo->info->strip_discarded
+               && !bfd_is_abs_section (h->root.u.def.section)
+               && bfd_is_abs_section (h->root.u.def.section->output_section))
+              || (h->root.u.def.section->owner != NULL
+                  && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0)))
+    return TRUE;
+  else if (h->indx != -2
+           && (h->root.type == bfd_link_hash_undefined
+              || h->root.type == bfd_link_hash_undefweak)
+          && h->root.u.undef.abfd != NULL
+          && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
+    return TRUE;

  switch (h->root.type)
    {
@@ -2560,26 +2577,37 @@ _bfd_coff_write_global_sym (struct bfd_h
    case bfd_link_hash_undefweak:
      isym.n_scnum = N_UNDEF;
      isym.n_value = 0;
+      input_sec = bfd_und_section_ptr;
      break;

    case bfd_link_hash_defined:
    case bfd_link_hash_defweak:
-      {
-       asection *sec;
+      input_sec = h->root.u.def.section;
+      if (input_sec->output_section != NULL)
+       {
+         asection *sec;

-       sec = h->root.u.def.section->output_section;
-       if (bfd_is_abs_section (sec))
-         isym.n_scnum = N_ABS;
-       else
-         isym.n_scnum = sec->target_index;
-       isym.n_value = (h->root.u.def.value
-                       + h->root.u.def.section->output_offset);
-       if (! obj_pe (finfo->output_bfd))
-         isym.n_value += sec->vma;
-      }
+         sec = h->root.u.def.section->output_section;
+         if (bfd_is_abs_section (sec))
+           isym.n_scnum = N_ABS;
+         else
+           isym.n_scnum = sec->target_index;
+         isym.n_value = (h->root.u.def.value
+                         + h->root.u.def.section->output_offset);
+         if (! obj_pe (finfo->output_bfd))
+           isym.n_value += sec->vma;
+       }
+      else
+        {
+         BFD_ASSERT (input_sec->owner == NULL);
+         isym.n_scnum = N_UNDEF;
+         isym.n_value = 0;
+         input_sec = bfd_und_section_ptr;
+       }
      break;

    case bfd_link_hash_common:
+      input_sec = h->root.u.c.p->section;
      isym.n_scnum = N_UNDEF;
      isym.n_value = h->root.u.c.size;
      break;
@@ -2589,6 +2617,9 @@ _bfd_coff_write_global_sym (struct bfd_h
      return TRUE;
    }

+  if ((input_sec->flags & SEC_EXCLUDE) != 0)
+    return TRUE;
+
  if (strlen (h->root.root.string) <= SYMNMLEN)
    strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN);
  else
@@ -3013,7 +3044,8 @@ _bfd_coff_generic_relocate_section (bfd
                   h->auxbfd->tdata.coff_obj_data->sym_hashes[
                   h->aux->x_sym.x_tagndx.l];

-                 if (!h2 || h2->root.type == bfd_link_hash_undefined)
+                 if (!h2 || h2->root.type == bfd_link_hash_undefined
+                     || h2->root.type == bfd_link_hash_undefweak)
                   {
                     sec = bfd_abs_section_ptr;
                     val = 0;



-- 
|  (\_/) This is Bunny. Copy and paste
| (='.'=) Bunny into your signature to help
| (")_(") him gain world domination



More information about the Binutils mailing list