* dwarf2read.c (follow_die_ref): Add comment.
[deliverable/binutils-gdb.git] / bfd / xcofflink.c
index 97c051a2b9fe6f8bd6ec64a0dbaae1f32522fb61..896292b393e8f8685dbcad1bb74e86c4dbae1953 100644 (file)
@@ -86,6 +86,12 @@ struct xcoff_archive_info
      this archive in the .loader section.  */
   const char *imppath;
   const char *impfile;
+
+  /* True if the archive contains a dynamic object.  */
+  unsigned int contains_shared_object_p : 1;
+
+  /* True if the previous field is valid.  */
+  unsigned int know_contains_shared_object_p : 1;
 };
 
 struct xcoff_link_hash_table
@@ -2465,6 +2471,21 @@ _bfd_xcoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
     }
 }
 \f
+bfd_boolean
+_bfd_xcoff_define_common_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
+                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                                struct bfd_link_hash_entry *harg)
+{
+  struct xcoff_link_hash_entry *h;
+
+  if (!bfd_generic_define_common_symbol (output_bfd, info, harg))
+    return FALSE;
+
+  h = (struct xcoff_link_hash_entry *) harg;
+  h->flags |= XCOFF_DEF_REGULAR;
+  return TRUE;
+}
+\f
 /* If symbol H has not been interpreted as a function descriptor,
    see whether it should be.  Set up its descriptor information if so.  */
 
@@ -2504,14 +2525,23 @@ xcoff_find_function (struct bfd_link_info *info,
 /* Return true if the given bfd contains at least one shared object.  */
 
 static bfd_boolean
-xcoff_archive_contains_shared_object_p (bfd *archive)
+xcoff_archive_contains_shared_object_p (struct bfd_link_info *info,
+                                       bfd *archive)
 {
+  struct xcoff_archive_info *archive_info;
   bfd *member;
 
-  member = bfd_openr_next_archived_file (archive, NULL);
-  while (member != NULL && (member->flags & DYNAMIC) == 0)
-    member = bfd_openr_next_archived_file (archive, member);
-  return member != NULL;
+  archive_info = xcoff_get_archive_info (info, archive);
+  if (!archive_info->know_contains_shared_object_p)
+    {
+      member = bfd_openr_next_archived_file (archive, NULL);
+      while (member != NULL && (member->flags & DYNAMIC) == 0)
+       member = bfd_openr_next_archived_file (archive, member);
+
+      archive_info->contains_shared_object_p = (member != NULL);
+      archive_info->know_contains_shared_object_p = 1;
+    }
+  return archive_info->contains_shared_object_p;
 }
 
 /* Symbol H qualifies for export by -bexpfull.  Return true if it also
@@ -2539,7 +2569,8 @@ xcoff_covered_by_expall_p (struct xcoff_link_hash_entry *h)
    specified by AUTO_EXPORT_FLAGS.  */
 
 static bfd_boolean
-xcoff_auto_export_p (struct xcoff_link_hash_entry *h,
+xcoff_auto_export_p (struct bfd_link_info *info,
+                    struct xcoff_link_hash_entry *h,
                     unsigned int auto_export_flags)
 {
   /* Don't automatically export things that were explicitly exported.  */
@@ -2576,7 +2607,7 @@ xcoff_auto_export_p (struct xcoff_link_hash_entry *h,
       owner = h->root.u.def.section->owner;
       if (owner != NULL
          && owner->my_archive != NULL
-         && xcoff_archive_contains_shared_object_p (owner->my_archive))
+         && xcoff_archive_contains_shared_object_p (info, owner->my_archive))
        return FALSE;
     }
 
@@ -3196,7 +3227,7 @@ xcoff_mark_auto_exports (struct xcoff_link_hash_entry *h, void *data)
   struct xcoff_loader_info *ldinfo;
 
   ldinfo = (struct xcoff_loader_info *) data;
-  if (xcoff_auto_export_p (h, ldinfo->auto_export_flags))
+  if (xcoff_auto_export_p (ldinfo->info, h, ldinfo->auto_export_flags))
     {
       if (!xcoff_mark_symbol (ldinfo->info, h))
        ldinfo->failed = TRUE;
@@ -3314,19 +3345,6 @@ xcoff_post_gc_symbol (struct xcoff_link_hash_entry *h, void * p)
   if (h->flags & XCOFF_RTINIT)
     return TRUE;
 
-  /* If this is a final link, and the symbol was defined as a common
-     symbol in a regular object file, and there was no definition in
-     any dynamic object, then the linker will have allocated space for
-     the symbol in a common section but the XCOFF_DEF_REGULAR flag
-     will not have been set.  */
-  if (h->root.type == bfd_link_hash_defined
-      && (h->flags & XCOFF_DEF_REGULAR) == 0
-      && (h->flags & XCOFF_REF_REGULAR) != 0
-      && (h->flags & XCOFF_DEF_DYNAMIC) == 0
-      && (bfd_is_abs_section (h->root.u.def.section)
-         || (h->root.u.def.section->owner->flags & DYNAMIC) == 0))
-    h->flags |= XCOFF_DEF_REGULAR;
-
   /* We don't want to garbage collect symbols which are not defined in
      XCOFF files.  This is a convenient place to mark them.  */
   if (xcoff_hash_table (ldinfo->info)->gc
@@ -3355,7 +3373,7 @@ xcoff_post_gc_symbol (struct xcoff_link_hash_entry *h, void * p)
 
   if (xcoff_hash_table (ldinfo->info)->loader_section)
     {
-      if (xcoff_auto_export_p (h, ldinfo->auto_export_flags))
+      if (xcoff_auto_export_p (ldinfo->info, h, ldinfo->auto_export_flags))
        h->flags |= XCOFF_EXPORT;
 
       if (!xcoff_build_ldsym (ldinfo, h))
@@ -4289,6 +4307,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
 
   esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
   esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
+  sym_hash = obj_xcoff_sym_hashes (input_bfd);
   isymp = finfo->internal_syms;
   indexp = finfo->sym_indices;
   csectpp = xcoff_data (input_bfd)->csects;
@@ -4336,6 +4355,16 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
                }
            }
 
+         /* Make __rtinit C_HIDEXT rather than C_EXT.  This avoids
+            multiple definition problems when linking a shared object
+            statically.  (The native linker doesn't enter __rtinit into
+            the normal table at all, but having a local symbol can make
+            the objdump output easier to read.)  */
+         if (isym.n_sclass == C_EXT
+             && *sym_hash
+             && ((*sym_hash)->flags & XCOFF_RTINIT) != 0)
+           isym.n_sclass = C_HIDEXT;
+
          /* The value of a C_FILE symbol is the symbol index of the
             next C_FILE symbol.  The value of the last C_FILE symbol
             is -1.  We try to get this right, below, just before we
@@ -4664,6 +4693,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
            }
        }
 
+      sym_hash += add;
       indexp += add;
       isymp += add;
       csectpp += add;
This page took 0.024488 seconds and 4 git commands to generate.