* ld.h (ld_config_type): Add new field warn_once.
authorIan Lance Taylor <ian@airs.com>
Wed, 14 Sep 1994 22:27:16 +0000 (22:27 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 14 Sep 1994 22:27:16 +0000 (22:27 +0000)
* ldmain.c (undefined_symbol): Handle -warn-once.
* lexsup.c (parse_args): Recognize -warn-once.
* ld.texinfo (Options): Document -warn-once.
* ld.1: Likewise.
PR 4456.

ld/ChangeLog
ld/ld.1
ld/ld.h
ld/ldmain.c
ld/lexsup.c

index a77789b..d5def59 100644 (file)
@@ -5,6 +5,12 @@ Wed Sep 14 12:49:12 1994  Steve Chamberlain  (sac@jonny.cygnus.com)
 
 Wed Sep 14 12:48:09 1994  Ian Lance Taylor  (ian@sanguine.cygnus.com)
 
 
 Wed Sep 14 12:48:09 1994  Ian Lance Taylor  (ian@sanguine.cygnus.com)
 
+       * ld.h (ld_config_type): Add new field warn_once.
+       * ldmain.c (undefined_symbol): Handle -warn-once.
+       * lexsup.c (parse_args): Recognize -warn-once.
+       * ld.texinfo (Options): Document -warn-once.
+       * ld.1: Likewise.
+
        * ldmisc.c (vfinfo): Handle %D as %C, but never print the function
        name.  For %C, print the function name on a separate line, to keep
        the length of error messages under control.
        * ldmisc.c (vfinfo): Handle %D as %C, but never print the function
        name.  For %C, print the function name on a separate line, to keep
        the length of error messages under control.
diff --git a/ld/ld.1 b/ld/ld.1
index 965e791..3b63934 100644 (file)
--- a/ld/ld.1
+++ b/ld/ld.1
@@ -101,6 +101,7 @@ ld \- the GNU linker
 .RB "[\|" \-v "\|]"
 .RB "[\|" \-\-version "\|]"
 .RB "[\|" \-warn\-common "\|]" 
 .RB "[\|" \-v "\|]"
 .RB "[\|" \-\-version "\|]"
 .RB "[\|" \-warn\-common "\|]" 
+.RB "[\|" \-warn\-once "\|]" 
 .RB "[\|" \-X "\|]" 
 .RB "[\|" \-x "\|]" 
 .ad b
 .RB "[\|" \-X "\|]" 
 .RB "[\|" \-x "\|]" 
 .ad b
@@ -778,6 +779,11 @@ but linkers on some other operating systems do not.  This option allows
 you to find potential problems from combining global symbols.
 
 .TP
 you to find potential problems from combining global symbols.
 
 .TP
+.B \-warn\-once
+Only warn once for each undefined symbol, rather than once per module
+which refers to it.
+
+.TP
 .B \-X 
 If \c
 .B \-s\c
 .B \-X 
 If \c
 .B \-s\c
diff --git a/ld/ld.h b/ld/ld.h
index ff654a6..d23633e 100644 (file)
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -49,6 +49,15 @@ typedef struct
   /* 1 => assign space to common symbols even if `relocatable_output'.  */
   boolean force_common_definition;
   boolean relax;
   /* 1 => assign space to common symbols even if `relocatable_output'.  */
   boolean force_common_definition;
   boolean relax;
+
+  /* Name of runtime interpreter to invoke.  */
+  char *interpreter;
+
+  /* Name to give runtime libary from the -soname argument.  */
+  char *soname;
+
+  /* Runtime library search path from the -rpath argument.  */
+  char *rpath;
 } args_type;
 
 extern args_type command_line;
 } args_type;
 
 extern args_type command_line;
@@ -72,6 +81,9 @@ typedef struct
   /* If true, warn about merging common symbols with others.  */
   boolean warn_common;
 
   /* If true, warn about merging common symbols with others.  */
   boolean warn_common;
 
+  /* If true, only warn once about a particular undefined symbol.  */
+  boolean warn_once;
+
   boolean sort_common;
 
   boolean text_read_only;
   boolean sort_common;
 
   boolean text_read_only;
index 754813b..392d302 100644 (file)
@@ -782,6 +782,27 @@ undefined_symbol (info, name, abfd, section, address)
 
 #define MAX_ERRORS_IN_A_ROW 5
 
 
 #define MAX_ERRORS_IN_A_ROW 5
 
+  if (config.warn_once)
+    {
+      static struct bfd_hash_table *hash;
+
+      /* Only warn once about a particular undefined symbol.  */
+
+      if (hash == NULL)
+       {
+         hash = ((struct bfd_hash_table *)
+                 xmalloc (sizeof (struct bfd_hash_table)));
+         if (! bfd_hash_table_init (hash, bfd_hash_newfunc))
+           einfo ("%F%P: bfd_hash_table_init failed: %E\n");
+       }
+
+      if (bfd_hash_lookup (hash, name, false, false) != NULL)
+       return true;
+
+      if (bfd_hash_lookup (hash, name, true, true) == NULL)
+       einfo ("%F%P: bfd_hash_lookup failed: %E\n");
+    }
+
   /* We never print more than a reasonable number of errors in a row
      for a single symbol.  */
   if (error_name != (char *) NULL
   /* We never print more than a reasonable number of errors in a row
      for a single symbol.  */
   if (error_name != (char *) NULL
index 128f0b6..21e8f12 100644 (file)
@@ -34,6 +34,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "ldfile.h"
 #include "ldver.h"
 
 #include "ldfile.h"
 #include "ldver.h"
 
+/* Somewhere above, sys/stat.h got included . . . . */
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define        S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
 /* Omit args to avoid the possibility of clashing with a system header
    that might disagree about consts.  */
 unsigned long strtoul ();
 /* Omit args to avoid the possibility of clashing with a system header
    that might disagree about consts.  */
 unsigned long strtoul ();
@@ -72,8 +77,10 @@ parse_args (argc, argv)
 #define OPTION_OFORMAT                 (OPTION_NON_SHARED + 1)
 #define OPTION_RELAX                   (OPTION_OFORMAT + 1)
 #define OPTION_RETAIN_SYMBOLS_FILE     (OPTION_RELAX + 1)
 #define OPTION_OFORMAT                 (OPTION_NON_SHARED + 1)
 #define OPTION_RELAX                   (OPTION_OFORMAT + 1)
 #define OPTION_RETAIN_SYMBOLS_FILE     (OPTION_RELAX + 1)
-#define OPTION_SHARED                  (OPTION_RETAIN_SYMBOLS_FILE + 1)
-#define OPTION_SORT_COMMON             (OPTION_SHARED + 1)
+#define OPTION_RPATH                   (OPTION_RETAIN_SYMBOLS_FILE + 1)
+#define OPTION_SHARED                  (OPTION_RPATH + 1)
+#define OPTION_SONAME                  (OPTION_SHARED + 1)
+#define OPTION_SORT_COMMON             (OPTION_SONAME + 1)
 #define OPTION_STATS                   (OPTION_SORT_COMMON + 1)
 #define OPTION_TBSS                    (OPTION_STATS + 1)
 #define OPTION_TDATA                   (OPTION_TBSS + 1)
 #define OPTION_STATS                   (OPTION_SORT_COMMON + 1)
 #define OPTION_TBSS                    (OPTION_STATS + 1)
 #define OPTION_TDATA                   (OPTION_TBSS + 1)
@@ -82,6 +89,7 @@ parse_args (argc, argv)
 #define OPTION_UR                      (OPTION_TRADITIONAL_FORMAT + 1)
 #define OPTION_VERSION                 (OPTION_UR + 1)
 #define OPTION_WARN_COMMON             (OPTION_VERSION + 1)
 #define OPTION_UR                      (OPTION_TRADITIONAL_FORMAT + 1)
 #define OPTION_VERSION                 (OPTION_UR + 1)
 #define OPTION_WARN_COMMON             (OPTION_VERSION + 1)
+#define OPTION_WARN_ONCE               (OPTION_WARN_COMMON + 1)
 
   static struct option longopts[] = {
     {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
 
   static struct option longopts[] = {
     {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
@@ -89,6 +97,7 @@ parse_args (argc, argv)
     {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
     {"dc", no_argument, NULL, 'd'},
     {"defsym", required_argument, NULL, OPTION_DEFSYM},
     {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
     {"dc", no_argument, NULL, 'd'},
     {"defsym", required_argument, NULL, OPTION_DEFSYM},
+    {"dll-verbose", no_argument, NULL, OPTION_VERSION}, /* Linux.  */
     {"dn", no_argument, NULL, OPTION_NON_SHARED},
     {"dp", no_argument, NULL, 'd'},
     {"dy", no_argument, NULL, OPTION_CALL_SHARED},
     {"dn", no_argument, NULL, OPTION_NON_SHARED},
     {"dp", no_argument, NULL, 'd'},
     {"dy", no_argument, NULL, OPTION_CALL_SHARED},
@@ -108,7 +117,9 @@ parse_args (argc, argv)
     {"qmagic", no_argument, NULL, OPTION_IGNORE}, /* Linux compatibility.  */
     {"relax", no_argument, NULL, OPTION_RELAX},
     {"retain-symbols-file", required_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE},
     {"qmagic", no_argument, NULL, OPTION_IGNORE}, /* Linux compatibility.  */
     {"relax", no_argument, NULL, OPTION_RELAX},
     {"retain-symbols-file", required_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE},
+    {"rpath", required_argument, NULL, OPTION_RPATH},
     {"shared", no_argument, NULL, OPTION_SHARED},
     {"shared", no_argument, NULL, OPTION_SHARED},
+    {"soname", required_argument, NULL, OPTION_SONAME},
     {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
     {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
     {"start-group", no_argument, NULL, '('},
     {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
     {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
     {"start-group", no_argument, NULL, '('},
@@ -121,6 +132,7 @@ parse_args (argc, argv)
     {"Ur", no_argument, NULL, OPTION_UR},
     {"version", no_argument, NULL, OPTION_VERSION},
     {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
     {"Ur", no_argument, NULL, OPTION_UR},
     {"version", no_argument, NULL, OPTION_VERSION},
     {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
+    {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
     {NULL, no_argument, NULL, 0}
   };
 
     {NULL, no_argument, NULL, 0}
   };
 
@@ -256,9 +268,40 @@ parse_args (argc, argv)
          config.dynamic_link = false;
          break;
        case 'R':
          config.dynamic_link = false;
          break;
        case 'R':
-         lang_add_input_file (optarg,
-                              lang_input_file_is_symbols_only_enum,
-                              (char *) NULL);
+         /* The GNU linker traditionally uses -R to mean to include
+            only the symbols from a file.  The Solaris linker uses -R
+            to set the path used by the runtime linker to find
+            libraries.  This is the GNU linker -rpath argument.  We
+            try to support both simultaneously by checking the file
+            named.  If it is a directory, rather than a regular file,
+            we assume -rpath was meant.  */
+         {
+           struct stat s;
+
+           if (stat (optarg, &s) >= 0
+               && ! S_ISDIR (s.st_mode))
+             {
+               lang_add_input_file (optarg,
+                                    lang_input_file_is_symbols_only_enum,
+                                    (char *) NULL);
+               break;
+             }
+         }
+         /* Fall through.  */
+       case OPTION_RPATH:
+         if (command_line.rpath == NULL)
+           command_line.rpath = buystring (optarg);
+         else
+           {
+             char *buf;
+
+             buf = xmalloc (strlen (command_line.rpath)
+                            + strlen (optarg)
+                            + 2);
+             sprintf (buf, "%s:%s", command_line.rpath, optarg);
+             free (command_line.rpath);
+             command_line.rpath = buf;
+           }
          break;
        case OPTION_RELAX:
          command_line.relax = true;
          break;
        case OPTION_RELAX:
          command_line.relax = true;
@@ -275,6 +318,9 @@ parse_args (argc, argv)
        case OPTION_SHARED:
          link_info.shared = true;
          break;
        case OPTION_SHARED:
          link_info.shared = true;
          break;
+       case OPTION_SONAME:
+         command_line.soname = optarg;
+         break;
        case OPTION_SORT_COMMON:
          config.sort_common = true;
          break;
        case OPTION_SORT_COMMON:
          config.sort_common = true;
          break;
@@ -327,6 +373,9 @@ parse_args (argc, argv)
        case OPTION_WARN_COMMON:
          config.warn_common = true;
          break;
        case OPTION_WARN_COMMON:
          config.warn_common = true;
          break;
+       case OPTION_WARN_ONCE:
+         config.warn_once = true;
+         break;
        case 'X':
          link_info.discard = discard_l;
          break;
        case 'X':
          link_info.discard = discard_l;
          break;