]> Git Repo - binutils.git/blobdiff - ld/ldmain.c
Tue Mar 30 09:40:25 1993 Steve Chamberlain ([email protected])
[binutils.git] / ld / ldmain.c
index 965aa721e9e61f85e0f14db7535d6c7ea3bc1d92..137368bfcf8bfbe1098a2831afc799c1a9c7ed1a 100644 (file)
@@ -54,6 +54,9 @@ bfd *output_bfd = 0;
 
 extern boolean option_v;
 
+/* set if -y on the command line */
+int had_y;
+
 /* The local symbol prefix */
 char lprefix = 'L';
 
@@ -184,13 +187,16 @@ main (argc, argv)
   ldemul_before_parse ();
   lang_has_input_file = false;
   parse_args (argc, argv);
+
+  if (config.relocateable_output && command_line.relax)
+    {
+      einfo ("%P%F: -relax and -r may not be used together\n");
+    }
   lang_final ();
 
   if (trace_files)
     {
-
       info ("%P: mode %s\n", emulation);
-
     }
   if (lang_has_input_file == false)
     {
@@ -236,43 +242,34 @@ main (argc, argv)
     }
 
   if (config.relocateable_output)
-    {
-      output_bfd->flags &= ~EXEC_P;
-
-      ldwrite ();
-      bfd_close (output_bfd);
-    }
-
+    output_bfd->flags &= ~EXEC_P;
   else
-    {
-
-      output_bfd->flags |= EXEC_P;
-
-      ldwrite ();
-
-
-      if (config.make_executable == false && force_make_executable == false)
-       {
+    output_bfd->flags |= EXEC_P;
 
-         if (trace_files == true)
-           {
-             einfo ("%P: Link errors found, deleting executable `%s'\n",
-                    output_filename);
-           }
+  ldwrite ();
 
-         if (output_bfd->iostream)
-           fclose ((FILE *) (output_bfd->iostream));
+  /* Even if we're producing relocateable output, some non-fatal errors should
+     be reported in the exit status.  (What non-fatal errors, if any, do we
+     want to ignore for relocateable output?)  */
 
-         unlink (output_filename);
-         exit (1);
-       }
-      else
+  if (config.make_executable == false && force_make_executable == false)
+    {
+      if (trace_files == true)
        {
-         bfd_close (output_bfd);
+         einfo ("%P: Link errors found, deleting executable `%s'\n",
+                output_filename);
        }
-    }
 
+      if (output_bfd->iostream)
+       fclose ((FILE *) (output_bfd->iostream));
 
+      unlink (output_filename);
+      exit (1);
+    }
+  else
+    {
+      bfd_close (output_bfd);
+    }
 
   exit (0);
 }                              /* main() */
@@ -348,9 +345,11 @@ DEFUN (Q_enter_global_ref, (nlist_p, name),
   flagword this_symbol_flags = sym->flags;
 
   sp = ldsym_get (name);
-  /* If this symbol already has udata, it means that something strange 
+
+
+  /* If this symbol already has udata, it means that something strange
      has happened.
-     
+
      The strange thing is that we've had an undefined symbol resolved by
      an alias, but the thing the alias defined wasn't in the file. So
      the symbol got a udata entry, but the file wasn't loaded.  Then
@@ -359,128 +358,130 @@ DEFUN (Q_enter_global_ref, (nlist_p, name),
 
 
   if (sym->udata)
-   return;
+    return;
 
 
   if (flag_is_constructor (this_symbol_flags))
-  {
-    /* Add this constructor to the list we keep */
-    ldlang_add_constructor (sp);
-    /* Turn any commons into refs */
-    if (sp->scoms_chain != (asymbol **) NULL)
     {
-      refize (sp, sp->scoms_chain);
-      sp->scoms_chain = 0;
-    }
+      /* Add this constructor to the list we keep */
+      ldlang_add_constructor (sp);
+      /* Turn any commons into refs */
+      if (sp->scoms_chain != (asymbol **) NULL)
+       {
+         refize (sp, sp->scoms_chain);
+         sp->scoms_chain = 0;
+       }
 
 
-  }
+    }
   else
-  {
-    if (sym->section == &bfd_com_section)
     {
-      /* If we have a definition of this symbol already then
+      if (bfd_is_com_section (sym->section))
+       {
+         /* If we have a definition of this symbol already then
         this common turns into a reference. Also we only
         ever point to the largest common, so if we
         have a common, but it's bigger that the new symbol
         the turn this into a reference too. */
-      if (sp->sdefs_chain)
-      {
-       /* This is a common symbol, but we already have a definition
+         if (sp->sdefs_chain)
+           {
+             /* This is a common symbol, but we already have a definition
           for it, so just link it into the ref chain as if
           it were a reference  */
-       refize (sp, nlist_p);
-      }
-      else if (sp->scoms_chain)
-      {
-       /* If we have a previous common, keep only the biggest */
-       if ((*(sp->scoms_chain))->value > sym->value)
-       {
-         /* other common is bigger, throw this one away */
-         refize (sp, nlist_p);
-       }
-       else if (sp->scoms_chain != nlist_p)
-       {
-         /* other common is smaller, throw that away */
-         refize (sp, sp->scoms_chain);
-         sp->scoms_chain = nlist_p;
-       }
-      }
-      else
-      {
-       /* This is the first time we've seen a common, so remember it
+             refize (sp, nlist_p);
+           }
+         else if (sp->scoms_chain)
+           {
+             /* If we have a previous common, keep only the biggest */
+             if ((*(sp->scoms_chain))->value > sym->value)
+               {
+                 /* other common is bigger, throw this one away */
+                 refize (sp, nlist_p);
+               }
+             else if (sp->scoms_chain != nlist_p)
+               {
+                 /* other common is smaller, throw that away */
+                 refize (sp, sp->scoms_chain);
+                 sp->scoms_chain = nlist_p;
+               }
+           }
+         else
+           {
+             /* This is the first time we've seen a common, so remember it
           - if it was undefined before, we know it's defined now. If
           the symbol has been marked as really being a constructor,
           then treat this as a ref
           */
-       if (sp->flags & SYM_CONSTRUCTOR)
-       {
-         /* Turn this into a ref */
-         refize (sp, nlist_p);
-       }
-       else
-       {
-         /* treat like a common */
-         if (sp->srefs_chain)
-          undefined_global_sym_count--;
+             if (sp->flags & SYM_CONSTRUCTOR)
+               {
+                 /* Turn this into a ref */
+                 refize (sp, nlist_p);
+               }
+             else
+               {
+                 /* treat like a common */
+                 if (sp->srefs_chain)
+                   undefined_global_sym_count--;
 
-         commons_pending++;
-         sp->scoms_chain = nlist_p;
+                 commons_pending++;
+                 sp->scoms_chain = nlist_p;
+               }
+           }
        }
-      }
-    }
 
-    else if (sym->section != &bfd_und_section)
-    {
-      /* This is the definition of a symbol, add to def chain */
-      if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section)
-      {
-       /* Multiple definition */
-       asymbol *sy = *(sp->sdefs_chain);
-       lang_input_statement_type *stat = (lang_input_statement_type *) sy->the_bfd->usrdata;
-       lang_input_statement_type *stat1 = (lang_input_statement_type *) sym->the_bfd->usrdata;
-       asymbol **stat1_symbols = stat1 ? stat1->asymbols : 0;
-       asymbol **stat_symbols = stat ? stat->asymbols : 0;
-
-       multiple_def_count++;
-       einfo ("%X%C: multiple definition of `%T'\n",
-              sym->the_bfd, sym->section, stat1_symbols, sym->value, sym);
-
-       einfo ("%X%C: first seen here\n",
-              sy->the_bfd, sy->section, stat_symbols, sy->value);
-      }
+      else if (sym->section != &bfd_und_section)
+       {
+         /* This is the definition of a symbol, add to def chain */
+         if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section)
+           {
+             /* Multiple definition */
+             asymbol *sy = *(sp->sdefs_chain);
+             lang_input_statement_type *stat =
+             (lang_input_statement_type *) bfd_asymbol_bfd (sy)->usrdata;
+             lang_input_statement_type *stat1 =
+             (lang_input_statement_type *) bfd_asymbol_bfd (sym)->usrdata;
+             asymbol **stat1_symbols = stat1 ? stat1->asymbols : 0;
+             asymbol **stat_symbols = stat ? stat->asymbols : 0;
+
+             multiple_def_count++;
+             einfo ("%X%C: multiple definition of `%T'\n",
+                    bfd_asymbol_bfd (sym), sym->section, stat1_symbols, sym->value, sym);
+
+             einfo ("%X%C: first seen here\n",
+               bfd_asymbol_bfd (sy), sy->section, stat_symbols, sy->value);
+           }
+         else
+           {
+             sym->udata = (PTR) (sp->sdefs_chain);
+             sp->sdefs_chain = nlist_p;
+           }
+         /* A definition overrides a common symbol */
+         if (sp->scoms_chain)
+           {
+             refize (sp, sp->scoms_chain);
+             sp->scoms_chain = 0;
+             commons_pending--;
+           }
+         else if (sp->srefs_chain && relaxing == false)
+           {
+             /* If previously was undefined, then remember as defined */
+             undefined_global_sym_count--;
+           }
+       }
       else
-      {
-       sym->udata = (PTR) (sp->sdefs_chain);
-       sp->sdefs_chain = nlist_p;
-      }
-      /* A definition overrides a common symbol */
-      if (sp->scoms_chain)
-      {
-       refize (sp, sp->scoms_chain);
-       sp->scoms_chain = 0;
-       commons_pending--;
-      }
-      else if (sp->srefs_chain && relaxing == false)
-      {
-       /* If previously was undefined, then remember as defined */
-       undefined_global_sym_count--;
-      }
-    }
-    else
-    {
-      if (sp->scoms_chain == (asymbol **) NULL
-         && sp->srefs_chain == (asymbol **) NULL
-         && sp->sdefs_chain == (asymbol **) NULL)
-      {
-       /* And it's the first time we've seen it */
-       undefined_global_sym_count++;
+       {
+         if (sp->scoms_chain == (asymbol **) NULL
+             && sp->srefs_chain == (asymbol **) NULL
+             && sp->sdefs_chain == (asymbol **) NULL)
+           {
+             /* And it's the first time we've seen it */
+             undefined_global_sym_count++;
 
-      }
+           }
 
-      refize (sp, nlist_p);
+         refize (sp, nlist_p);
+       }
     }
-  }
 
   ASSERT (sp->sdefs_chain == 0 || sp->scoms_chain == 0);
   ASSERT (sp->scoms_chain == 0 || (*(sp->scoms_chain))->udata == 0);
@@ -496,7 +497,7 @@ Q_enter_file_symbols (entry)
 
   entry->common_section =
     bfd_make_section_old_way (entry->the_bfd, "COMMON");
-
+  entry->common_section->flags = SEC_NEVER_LOAD;
   ldlang_add_file (entry);
 
 
@@ -513,7 +514,20 @@ Q_enter_file_symbols (entry)
        {
          asymbol *p = *q;
 
-         if (p->flags & BSF_INDIRECT)
+         if (had_y && p->name)
+           {
+             /* look up the symbol anyway to see if the trace bit was
+          set */
+             ldsym_type *s = ldsym_get (p->name);
+             if (s->flags & SYM_Y)
+               {
+                 einfo ("%B: %s %T\n", entry->the_bfd,
+                        p->section == &bfd_und_section ? "reference to" : "definition of ",
+                        p);
+               }
+           }
+
+         if (p->section == &bfd_ind_section)
            {
              add_indirect (q);
            }
@@ -523,7 +537,7 @@ Q_enter_file_symbols (entry)
            }
          else if (p->section == &bfd_und_section
                   || (p->flags & BSF_GLOBAL)
-                  || p->section == &bfd_com_section
+                  || bfd_is_com_section (p->section)
                   || (p->flags & BSF_CONSTRUCTOR))
 
            {
@@ -540,17 +554,19 @@ Q_enter_file_symbols (entry)
                }
              else if (p->section == &bfd_und_section
                       || (p->flags & BSF_GLOBAL)
-                      || p->section == &bfd_com_section
+                      || bfd_is_com_section (p->section)
                       || (p->flags & BSF_CONSTRUCTOR))
                {
                  Q_enter_global_ref (q, p->name);
                }
 
            }
+
        }
     }
 }
 
+
 /* Searching libraries */
 
 struct lang_input_statement_struct *decode_library_subfile ();
@@ -579,7 +595,7 @@ search_library (entry)
 
 #ifdef GNU960
 static
-       boolean
+  boolean
 gnu960_check_format (abfd, format)
      bfd *abfd;
      bfd_format format;
@@ -658,21 +674,37 @@ decode_library_subfile (library_entry, subfile_offset)
      bfd *subfile_offset;
 {
   register struct lang_input_statement_struct *subentry;
-  subentry = (struct lang_input_statement_struct *) ldmalloc ((bfd_size_type) (sizeof (struct lang_input_statement_struct)));
 
-  subentry->filename = subfile_offset->filename;
-  subentry->local_sym_name = subfile_offset->filename;
-  subentry->asymbols = 0;
-  subentry->the_bfd = subfile_offset;
-  subentry->subfiles = 0;
-  subentry->next = 0;
-  subentry->superfile = library_entry;
-  subentry->is_archive = false;
 
-  subentry->just_syms_flag = false;
-  subentry->loaded = false;
-  subentry->chain = 0;
+  /* First, check if we already have a loaded
+     lang_input_statement_struct  for this library subfile.  If so,
+     just return it.  Otherwise, allocate some space and build a new one. */
 
+  if (subfile_offset->usrdata
+      && ((struct lang_input_statement_struct *) subfile_offset->usrdata)->
+      loaded == true)
+    {
+      subentry = (struct lang_input_statement_struct *) subfile_offset->usrdata;
+    }
+  else
+    {
+      subentry =
+       (struct lang_input_statement_struct *)
+       ldmalloc ((bfd_size_type) (sizeof (struct lang_input_statement_struct)));
+
+      subentry->filename = subfile_offset->filename;
+      subentry->local_sym_name = subfile_offset->filename;
+      subentry->asymbols = 0;
+      subentry->the_bfd = subfile_offset;
+      subentry->subfiles = 0;
+      subentry->next = 0;
+      subentry->superfile = library_entry;
+      subentry->is_archive = false;
+
+      subentry->just_syms_flag = false;
+      subentry->loaded = false;
+      subentry->chain = 0;
+    }
   return subentry;
 }
 
@@ -824,9 +856,15 @@ linear_library (entry)
 
   if (entry->complained == false)
     {
-      einfo ("%P: library %s has bad table of contents, rerun ranlib\n",
-            entry->the_bfd->filename);
+      if (entry->the_bfd->xvec->flavour != bfd_target_ieee_flavour)
+
+       {
+         /* IEEE can use table of contents, so this message is bogus */
+         einfo ("%P: library %s has bad table of contents, rerun ranlib\n",
+                entry->the_bfd->filename);
+       }
       entry->complained = true;
+
     }
   while (more_to_do)
     {
@@ -836,36 +874,43 @@ linear_library (entry)
       more_to_do = false;
       while (archive)
        {
+         /* Don't check this file if it's already been read in
+            once */
+
+         if (!archive->usrdata ||
+             !((lang_input_statement_type *) (archive->usrdata))->loaded)
+           {
 #ifdef GNU960
-         if (gnu960_check_format (archive, bfd_object))
+             if (gnu960_check_format (archive, bfd_object))
 #else
-         if (bfd_check_format (archive, bfd_object))
+             if (bfd_check_format (archive, bfd_object))
 #endif
-           {
-             register struct lang_input_statement_struct *subentry;
-
-             subentry = decode_library_subfile (entry,
-                                                archive);
-
-             archive->usrdata = (PTR) subentry;
-             if (!subentry)
-               return;
-             if (subentry->loaded == false)
                {
-                 Q_read_entry_symbols (archive, subentry);
+                 register struct lang_input_statement_struct *subentry;
+
+                 subentry = decode_library_subfile (entry,
+                                                    archive);
 
-                 if (subfile_wanted_p (subentry) == true)
+                 archive->usrdata = (PTR) subentry;
+                 if (!subentry)
+                   return;
+                 if (subentry->loaded == false)
                    {
-                     Q_enter_file_symbols (subentry);
+                     Q_read_entry_symbols (archive, subentry);
 
-                     if (prev)
-                       prev->chain = subentry;
-                     else
-                       entry->subfiles = subentry;
-                     prev = subentry;
+                     if (subfile_wanted_p (subentry) == true)
+                       {
+                         Q_enter_file_symbols (subentry);
 
-                     more_to_do = true;
-                     subentry->loaded = true;
+                         if (prev)
+                           prev->chain = subentry;
+                         else
+                           entry->subfiles = subentry;
+                         prev = subentry;
+
+                         more_to_do = true;
+                         subentry->loaded = true;
+                       }
                    }
                }
            }
@@ -876,7 +921,7 @@ linear_library (entry)
     }
 }
 
- /* ENTRY is an entry for a file inside an archive
+/* ENTRY is an entry for a file inside an archive
     Its symbols have been read into core, but not entered into the
     linker ymbol table
     Return nonzero if we ought to load this file */
@@ -896,10 +941,10 @@ subfile_wanted_p (entry)
 
       if (p->flags & BSF_INDIRECT)
        {
-/**    add_indirect(q);*/
+         /**   add_indirect(q);*/
        }
 
-      if (p->section == &bfd_com_section
+      if (bfd_is_com_section (p->section)
          || (p->flags & BSF_GLOBAL)
          || (p->flags & BSF_INDIRECT))
        {
@@ -913,10 +958,16 @@ subfile_wanted_p (entry)
              if (sp->srefs_chain != (asymbol **) NULL
                  || sp->scoms_chain != (asymbol **) NULL)
                {
-                 /* This is a symbol we are looking for.  It is either
-                    not yet defined or common.  */
-
-                 if (p->section == &bfd_com_section)
+                 /* This is a symbol we are looking for.  It is
+                    either not yet defined or common.  If this is a
+                    common symbol, then if the symbol in the object
+                    file is common, we need to combine sizes.  But if
+                    we already have a common symbol, and the symbol
+                    in the object file is not common, we don't want
+                    the object file: it is providing a definition for
+                    a symbol that we already have a definition for
+                    (this is the else condition below).  */
+                 if (bfd_is_com_section (p->section))
                    {
 
                      /* If the symbol in the table is a constructor, we won't to
@@ -949,8 +1000,7 @@ subfile_wanted_p (entry)
                                (asymbol **) ((*(sp->srefs_chain))->udata);
                              (*(sp->scoms_chain))->udata = (PTR) NULL;
 
-                             (*(sp->scoms_chain))->section =
-                               &bfd_com_section;
+                             (*(sp->scoms_chain))->section = p->section;
                              (*(sp->scoms_chain))->flags = 0;
                              /* Remember the size of this item */
                              sp->scoms_chain[0]->value = p->value;
@@ -961,19 +1011,18 @@ subfile_wanted_p (entry)
                            asymbol *com = *(sp->scoms_chain);
 
                            if (((lang_input_statement_type *)
-                                (com->the_bfd->usrdata))->common_section ==
+                                (bfd_asymbol_bfd (com)->usrdata))->common_section ==
                                (asection *) NULL)
                              {
                                ((lang_input_statement_type *)
-                                (com->the_bfd->usrdata))->common_section =
-                                 bfd_make_section_old_way (com->the_bfd, "COMMON");
+                                (bfd_asymbol_bfd (com)->usrdata))->common_section =
+                                 bfd_make_section_old_way (bfd_asymbol_bfd (com), "COMMON");
                              }
                          }
                        }
                      ASSERT (p->udata == 0);
                    }
-
-                 else
+                 else if (sp->scoms_chain == (asymbol **) NULL)
                    {
                      if (write_map)
                        {
@@ -988,3 +1037,12 @@ subfile_wanted_p (entry)
 
   return false;
 }
+
+void
+add_ysym (text)
+     char *text;
+{
+  ldsym_type *lookup = ldsym_get (text);
+  lookup->flags |= SYM_Y;
+  had_y = 1;
+}
This page took 0.046996 seconds and 4 git commands to generate.