* xcofflink.c (xcoff_mark_symbol): New static function, broken out
authorIan Lance Taylor <ian@airs.com>
Tue, 31 Oct 1995 17:36:12 +0000 (17:36 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 31 Oct 1995 17:36:12 +0000 (17:36 +0000)
of xcoff_mark.
(xcoff_mark): Call xcoff_mark_symbol.
(bfd_xcoff_export_symbol): Call xcoff_mark_symbol.
(bfd_xcoff_link_count_reloc): Call xcoff_mark_symbol rather than
doing it by hand.
(xcoff_build_ldsyms): Build a .loader symbol for an export symbol.

bfd/ChangeLog
bfd/xcofflink.c

index 7e4b57dadf678c5d59c76b040a01693783e9f647..59c913e97af822ddc84c4e7c81c655cc9eaebab7 100644 (file)
@@ -1,3 +1,13 @@
+Tue Oct 31 12:34:11 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * xcofflink.c (xcoff_mark_symbol): New static function, broken out
+       of xcoff_mark.
+       (xcoff_mark): Call xcoff_mark_symbol.
+       (bfd_xcoff_export_symbol): Call xcoff_mark_symbol.
+       (bfd_xcoff_link_count_reloc): Call xcoff_mark_symbol rather than
+       doing it by hand.
+       (xcoff_build_ldsyms): Build a .loader symbol for an export symbol.
+
 Mon Oct 30 14:53:48 1995  Ian Lance Taylor  <ian@cygnus.com>
 
        * xcofflink.c (struct xcoff_final_link_info): Add new line_filepos
index aca22b15384628476996fa7601f6be5bb51072a1..cc65a2a533913b32d3d4327c7026353744fbf22e 100644 (file)
@@ -1911,6 +1911,207 @@ xcoff_link_add_dynamic_symbols (abfd, info)
 /* Routines that are called after all the input files have been
    handled, but before the sections are laid out in memory.  */
 
+/* Mark a symbol as not being garbage, including the section in which
+   it is defined.  */
+
+static INLINE boolean
+xcoff_mark_symbol (info, h)
+     struct bfd_link_info *info;
+     struct xcoff_link_hash_entry *h;
+{
+  if ((h->flags & XCOFF_MARK) != 0)
+    return true;
+
+  h->flags |= XCOFF_MARK;
+  if (h->root.type == bfd_link_hash_defined
+      || h->root.type == bfd_link_hash_defweak)
+    {
+      asection *hsec;
+
+      hsec = h->root.u.def.section;
+      if ((hsec->flags & SEC_MARK) == 0)
+       {
+         if (! xcoff_mark (info, hsec))
+           return false;
+       }
+    }
+
+  if (h->toc_section != NULL
+      && (h->toc_section->flags & SEC_MARK) == 0)
+    {
+      if (! xcoff_mark (info, h->toc_section))
+       return false;
+    }
+
+  return true;
+}
+
+/* The mark phase of garbage collection.  For a given section, mark
+   it, and all the sections which define symbols to which it refers.
+   Because this function needs to look at the relocs, we also count
+   the number of relocs which need to be copied into the .loader
+   section.  */
+
+static boolean
+xcoff_mark (info, sec)
+     struct bfd_link_info *info;
+     asection *sec;
+{
+  if ((sec->flags & SEC_MARK) != 0)
+    return true;
+
+  sec->flags |= SEC_MARK;
+
+  if (sec->owner->xvec == info->hash->creator
+      && coff_section_data (sec->owner, sec) != NULL
+      && xcoff_section_data (sec->owner, sec) != NULL)
+    {
+      register struct xcoff_link_hash_entry **hp, **hpend;
+      struct internal_reloc *rel, *relend;
+
+      /* Mark all the symbols in this section.  */
+
+      hp = (obj_xcoff_sym_hashes (sec->owner)
+           + xcoff_section_data (sec->owner, sec)->first_symndx);
+      hpend = (obj_xcoff_sym_hashes (sec->owner)
+              + xcoff_section_data (sec->owner, sec)->last_symndx);
+      for (; hp < hpend; hp++)
+       {
+         register struct xcoff_link_hash_entry *h;
+
+         h = *hp;
+         if (h != NULL
+             && (h->flags & XCOFF_MARK) == 0)
+           {
+             if (! xcoff_mark_symbol (info, h))
+               return false;
+           }
+       }
+
+      /* Look through the section relocs.  */
+
+      if ((sec->flags & SEC_RELOC) != 0
+         && sec->reloc_count > 0)
+       {
+         rel = xcoff_read_internal_relocs (sec->owner, sec, true,
+                                           (bfd_byte *) NULL, false,
+                                           (struct internal_reloc *) NULL);
+         if (rel == NULL)
+           return false;
+         relend = rel + sec->reloc_count;
+         for (; rel < relend; rel++)
+           {
+             asection *rsec;
+             struct xcoff_link_hash_entry *h;
+
+             if ((unsigned int) rel->r_symndx
+                 > obj_raw_syment_count (sec->owner))
+               continue;
+
+             h = obj_xcoff_sym_hashes (sec->owner)[rel->r_symndx];
+             if (h != NULL
+                 && (h->flags & XCOFF_MARK) == 0)
+               {
+                 if (! xcoff_mark_symbol (info, h))
+                   return false;
+               }
+
+             rsec = xcoff_data (sec->owner)->csects[rel->r_symndx];
+             if (rsec != NULL
+                 && (rsec->flags & SEC_MARK) == 0)
+               {
+                 if (! xcoff_mark (info, rsec))
+                   return false;
+               }
+
+             /* See if this reloc needs to be copied into the .loader
+                 section.  */
+             switch (rel->r_type)
+               {
+               default:
+                 if (h == NULL
+                     || h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak
+                     || h->root.type == bfd_link_hash_common
+                     || ((h->flags & XCOFF_CALLED) != 0
+                         && (h->flags & XCOFF_DEF_REGULAR) == 0
+                         && (h->flags & XCOFF_REF_DYNAMIC) != 0
+                         && (h->root.type == bfd_link_hash_undefined
+                             || h->root.type == bfd_link_hash_undefweak)
+                         && h->root.root.string[0] == '.'))
+                   break;
+                 /* Fall through.  */
+               case R_POS:
+               case R_NEG:
+               case R_RL:
+               case R_RLA:
+                 ++xcoff_hash_table (info)->ldrel_count;
+                 if (h != NULL)
+                   h->flags |= XCOFF_LDREL;
+                 break;
+               case R_TOC:
+               case R_GL:
+               case R_TCL:
+               case R_TRL:
+               case R_TRLA:
+                 /* We should never need a .loader reloc for a TOC
+                    relative reloc.  */
+                 break;
+               }
+           }
+
+         if (! info->keep_memory
+             && coff_section_data (sec->owner, sec) != NULL
+             && coff_section_data (sec->owner, sec)->relocs != NULL
+             && ! coff_section_data (sec->owner, sec)->keep_relocs)
+           {
+             free (coff_section_data (sec->owner, sec)->relocs);
+             coff_section_data (sec->owner, sec)->relocs = NULL;
+           }
+       }
+    }
+
+  return true;
+}
+
+/* The sweep phase of garbage collection.  Remove all garbage
+   sections.  */
+
+static void
+xcoff_sweep (info)
+     struct bfd_link_info *info;
+{
+  bfd *sub;
+
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+    {
+      asection *o;
+
+      for (o = sub->sections; o != NULL; o = o->next)
+       {
+         if ((o->flags & SEC_MARK) == 0)
+           {
+             /* Keep all sections from non-XCOFF input files.  Keep
+                 special sections.  Keep .debug sections for the
+                 moment.  */
+             if (sub->xvec != info->hash->creator
+                 || o == xcoff_hash_table (info)->debug_section
+                 || o == xcoff_hash_table (info)->loader_section
+                 || o == xcoff_hash_table (info)->linkage_section
+                 || o == xcoff_hash_table (info)->toc_section
+                 || strcmp (o->name, ".debug") == 0)
+               o->flags |= SEC_MARK;
+             else
+               {
+                 o->_raw_size = 0;
+                 o->reloc_count = 0;
+                 o->lineno_count = 0;
+               }
+           }
+       }
+    }
+}
+
 /* Record the number of elements in a set.  This is used to output the
    correct csect length.  */
 
@@ -2048,6 +2249,10 @@ bfd_xcoff_export_symbol (output_bfd, info, harg, syscall)
   /* FIXME: I'm not at all sure what syscall is supposed to mean, so
      I'm just going to ignore it until somebody explains it.  */
 
+  /* Make sure we don't garbage collect this symbol.  */
+  if (! xcoff_mark_symbol (info, h))
+    return false;
+
   return true;
 }
 
@@ -2076,29 +2281,8 @@ bfd_xcoff_link_count_reloc (output_bfd, info, name)
   ++xcoff_hash_table (info)->ldrel_count;
   
   /* Mark the symbol to avoid garbage collection.  */
-  if ((h->flags & XCOFF_MARK) == 0)
-    {
-      h->flags |= XCOFF_MARK;
-      if (h->root.type == bfd_link_hash_defined
-         || h->root.type == bfd_link_hash_defweak)
-       {
-         asection *hsec;
-
-         hsec = h->root.u.def.section;
-         if ((hsec->flags & SEC_MARK) == 0)
-           {
-             if (! xcoff_mark (info, hsec))
-               return false;
-           }
-       }
-
-      if (h->toc_section != NULL
-         && (h->toc_section->flags & SEC_MARK) == 0)
-       {
-         if (! xcoff_mark (info, h->toc_section))
-           return false;
-       }
-    }
+  if (! xcoff_mark_symbol (info, h))
+    return false;
 
   return true;
 }
@@ -2479,208 +2663,6 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
   return false;
 }
 
-/* The mark phase of garbage collection.  For a given section, mark
-   it, and all the sections which define symbols to which it refers.
-   Because this function needs to look at the relocs, we also count
-   the number of relocs which need to be copied into the .loader
-   section.  */
-
-static boolean
-xcoff_mark (info, sec)
-     struct bfd_link_info *info;
-     asection *sec;
-{
-  if ((sec->flags & SEC_MARK) != 0)
-    return true;
-
-  sec->flags |= SEC_MARK;
-
-  if (sec->owner->xvec == info->hash->creator
-      && coff_section_data (sec->owner, sec) != NULL
-      && xcoff_section_data (sec->owner, sec) != NULL)
-    {
-      register struct xcoff_link_hash_entry **hp, **hpend;
-      struct internal_reloc *rel, *relend;
-
-      /* Mark all the symbols in this section.  */
-
-      hp = (obj_xcoff_sym_hashes (sec->owner)
-           + xcoff_section_data (sec->owner, sec)->first_symndx);
-      hpend = (obj_xcoff_sym_hashes (sec->owner)
-              + xcoff_section_data (sec->owner, sec)->last_symndx);
-      for (; hp < hpend; hp++)
-       {
-         register struct xcoff_link_hash_entry *h;
-
-         h = *hp;
-         if (h != NULL
-             && (h->flags & XCOFF_MARK) == 0)
-           {
-             h->flags |= XCOFF_MARK;
-             if (h->root.type == bfd_link_hash_defined
-                 || h->root.type == bfd_link_hash_defweak)
-               {
-                 asection *hsec;
-
-                 hsec = h->root.u.def.section;
-                 if ((hsec->flags & SEC_MARK) == 0)
-                   {
-                     if (! xcoff_mark (info, hsec))
-                       return false;
-                   }
-               }
-
-             if (h->toc_section != NULL
-                 && (h->toc_section->flags & SEC_MARK) == 0)
-               {
-                 if (! xcoff_mark (info, h->toc_section))
-                   return false;
-               }
-           }
-       }
-
-      /* Look through the section relocs.  */
-
-      if ((sec->flags & SEC_RELOC) != 0
-         && sec->reloc_count > 0)
-       {
-         rel = xcoff_read_internal_relocs (sec->owner, sec, true,
-                                           (bfd_byte *) NULL, false,
-                                           (struct internal_reloc *) NULL);
-         if (rel == NULL)
-           return false;
-         relend = rel + sec->reloc_count;
-         for (; rel < relend; rel++)
-           {
-             asection *rsec;
-             struct xcoff_link_hash_entry *h;
-
-             if ((unsigned int) rel->r_symndx
-                 > obj_raw_syment_count (sec->owner))
-               continue;
-
-             h = obj_xcoff_sym_hashes (sec->owner)[rel->r_symndx];
-             if (h != NULL
-                 && (h->flags & XCOFF_MARK) == 0)
-               {
-                 h->flags |= XCOFF_MARK;
-                 if (h->root.type == bfd_link_hash_defined
-                     || h->root.type == bfd_link_hash_defweak)
-                   {
-                     asection *hsec;
-
-                     hsec = h->root.u.def.section;
-                     if ((hsec->flags & SEC_MARK) == 0)
-                       {
-                         if (! xcoff_mark (info, hsec))
-                           return false;
-                       }
-                   }
-
-                 if (h->toc_section != NULL
-                     && (h->toc_section->flags & SEC_MARK) == 0)
-                   {
-                     if (! xcoff_mark (info, h->toc_section))
-                       return false;
-                   }
-               }
-
-             rsec = xcoff_data (sec->owner)->csects[rel->r_symndx];
-             if (rsec != NULL
-                 && (rsec->flags & SEC_MARK) == 0)
-               {
-                 if (! xcoff_mark (info, rsec))
-                   return false;
-               }
-
-             /* See if this reloc needs to be copied into the .loader
-                 section.  */
-             switch (rel->r_type)
-               {
-               default:
-                 if (h == NULL
-                     || h->root.type == bfd_link_hash_defined
-                     || h->root.type == bfd_link_hash_defweak
-                     || h->root.type == bfd_link_hash_common
-                     || ((h->flags & XCOFF_CALLED) != 0
-                         && (h->flags & XCOFF_DEF_REGULAR) == 0
-                         && (h->flags & XCOFF_REF_DYNAMIC) != 0
-                         && (h->root.type == bfd_link_hash_undefined
-                             || h->root.type == bfd_link_hash_undefweak)
-                         && h->root.root.string[0] == '.'))
-                   break;
-                 /* Fall through.  */
-               case R_POS:
-               case R_NEG:
-               case R_RL:
-               case R_RLA:
-                 ++xcoff_hash_table (info)->ldrel_count;
-                 if (h != NULL)
-                   h->flags |= XCOFF_LDREL;
-                 break;
-               case R_TOC:
-               case R_GL:
-               case R_TCL:
-               case R_TRL:
-               case R_TRLA:
-                 /* We should never need a .loader reloc for a TOC
-                    relative reloc.  */
-                 break;
-               }
-           }
-
-         if (! info->keep_memory
-             && coff_section_data (sec->owner, sec) != NULL
-             && coff_section_data (sec->owner, sec)->relocs != NULL
-             && ! coff_section_data (sec->owner, sec)->keep_relocs)
-           {
-             free (coff_section_data (sec->owner, sec)->relocs);
-             coff_section_data (sec->owner, sec)->relocs = NULL;
-           }
-       }
-    }
-
-  return true;
-}
-
-/* The sweep phase of garbage collection.  Remove all garbage
-   sections.  */
-
-static void
-xcoff_sweep (info)
-     struct bfd_link_info *info;
-{
-  bfd *sub;
-
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
-    {
-      asection *o;
-
-      for (o = sub->sections; o != NULL; o = o->next)
-       {
-         if ((o->flags & SEC_MARK) == 0)
-           {
-             /* Keep all sections from non-XCOFF input files.  Keep
-                 special sections.  Keep .debug sections for the
-                 moment.  */
-             if (sub->xvec != info->hash->creator
-                 || o == xcoff_hash_table (info)->debug_section
-                 || o == xcoff_hash_table (info)->loader_section
-                 || o == xcoff_hash_table (info)->linkage_section
-                 || o == xcoff_hash_table (info)->toc_section
-                 || strcmp (o->name, ".debug") == 0)
-               o->flags |= SEC_MARK;
-             else
-               {
-                 o->_raw_size = 0;
-                 o->reloc_count = 0;
-                 o->lineno_count = 0;
-               }
-           }
-       }
-    }
-}
-
 /* Add a symbol to the .loader symbols, if necessary.  */
 
 static boolean
@@ -2762,13 +2744,15 @@ xcoff_build_ldsyms (h, p)
 
   /* We need to add a symbol to the .loader section if it is mentioned
      in a reloc which we are copying to the .loader section and it was
-     not defined or common, or if it is the entry point.  */
+     not defined or common, or if it is the entry point, or if it is
+     being exported.  */
 
   if (((h->flags & XCOFF_LDREL) == 0
        || h->root.type == bfd_link_hash_defined
        || h->root.type == bfd_link_hash_defweak
        || h->root.type == bfd_link_hash_common)
-      && (h->flags & XCOFF_ENTRY) == 0)
+      && (h->flags & XCOFF_ENTRY) == 0
+      && (h->flags & XCOFF_EXPORT) == 0)
     {
       h->ldsym = NULL;
       return true;