diff options
-rw-r--r-- | ld/ChangeLog | 6 | ||||
-rw-r--r-- | ld/ld.1 | 6 | ||||
-rw-r--r-- | ld/ld.h | 12 | ||||
-rw-r--r-- | ld/ldmain.c | 21 | ||||
-rw-r--r-- | ld/lexsup.c | 59 |
5 files changed, 99 insertions, 5 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index a77789b..d5def59 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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) + * 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. @@ -101,6 +101,7 @@ ld \- the GNU linker .RB "[\|" \-v "\|]" .RB "[\|" \-\-version "\|]" .RB "[\|" \-warn\-common "\|]" +.RB "[\|" \-warn\-once "\|]" .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 +.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 @@ -49,6 +49,15 @@ typedef struct /* 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; @@ -72,6 +81,9 @@ typedef struct /* 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; diff --git a/ld/ldmain.c b/ld/ldmain.c index 754813b..392d302 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -782,6 +782,27 @@ undefined_symbol (info, name, abfd, section, address) #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 diff --git a/ld/lexsup.c b/ld/lexsup.c index 128f0b6..21e8f12 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -34,6 +34,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #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 (); @@ -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_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) @@ -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_WARN_ONCE (OPTION_WARN_COMMON + 1) 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}, + {"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}, @@ -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}, + {"rpath", required_argument, NULL, OPTION_RPATH}, {"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, '('}, @@ -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}, + {"warn-once", no_argument, NULL, OPTION_WARN_ONCE}, {NULL, no_argument, NULL, 0} }; @@ -256,9 +268,40 @@ parse_args (argc, argv) 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; @@ -275,6 +318,9 @@ parse_args (argc, argv) 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; @@ -327,6 +373,9 @@ parse_args (argc, argv) 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; |