]> Git Repo - binutils.git/blobdiff - ld/lexsup.c
Add support for ARM-PE.
[binutils.git] / ld / lexsup.c
index b9daf40dd668449f0489ac67d8345e679aa22363..1102efd0062ccea6902dac39cf4794c96a66e016 100644 (file)
@@ -32,6 +32,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "ldgram.h"
 #include "ldlex.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.  */
@@ -45,62 +51,88 @@ parse_args (argc, argv)
      int argc;
      char **argv;
 {
+  int ingroup = 0;
+
   /* Starting the short option string with '-' is for programs that
      expect options and other ARGV-elements in any order and that care about
      the ordering of the two.  We describe each non-option ARGV-element
      as if it were the argument of an option with character code 1.  */
 
-  const char *shortopts = "-A:B::b:cde:F::G:giL:l:Mm:NnO:o:R:rSsT:tu:VvXxY:y:";
+  const char *shortopts =
+    "-A:B::b:cde:F::G:giL:l:Mm:NnO:o:R:rSsT:tu:VvXxY:y:()";
 
   /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
 
+#define OPTION_CALL_SHARED             150
+#define OPTION_DEFSYM                  (OPTION_CALL_SHARED + 1)
+#define OPTION_DYNAMIC_LINKER          (OPTION_DEFSYM + 1)
+#define OPTION_EB                      (OPTION_DYNAMIC_LINKER + 1)
+#define OPTION_EL                      (OPTION_EB + 1)
+#define OPTION_HELP                    (OPTION_EL + 1)
+#define OPTION_IGNORE                  (OPTION_HELP + 1)
+#define OPTION_MAP                     (OPTION_IGNORE + 1)
+#define OPTION_NO_KEEP_MEMORY          (OPTION_MAP + 1)
+#define OPTION_NOINHIBIT_EXEC          (OPTION_NO_KEEP_MEMORY + 1)
+#define OPTION_NON_SHARED              (OPTION_NOINHIBIT_EXEC + 1)
+#define OPTION_OFORMAT                 (OPTION_NON_SHARED + 1)
+#define OPTION_RELAX                   (OPTION_OFORMAT + 1)
+#define OPTION_RETAIN_SYMBOLS_FILE     (OPTION_RELAX + 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_TTEXT                   (OPTION_TDATA + 1)
+#define OPTION_TRADITIONAL_FORMAT      (OPTION_TTEXT + 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[] = {
-#define OPTION_CALL_SHARED 150
+    {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
+    {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
     {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
     {"dc", no_argument, NULL, 'd'},
-#define OPTION_DEFSYM 151
     {"defsym", required_argument, NULL, OPTION_DEFSYM},
-    {"dn", no_argument, NULL, OPTION_CALL_SHARED},
+    {"dll-verbose", no_argument, NULL, OPTION_VERSION}, /* Linux.  */
+    {"dn", no_argument, NULL, OPTION_NON_SHARED},
     {"dp", no_argument, NULL, 'd'},
-#define OPTION_EB 152
+    {"dy", no_argument, NULL, OPTION_CALL_SHARED},
+    {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
     {"EB", no_argument, NULL, OPTION_EB},
-#define OPTION_EL 153
     {"EL", no_argument, NULL, OPTION_EL},
+    {"end-group", no_argument, NULL, ')'},
     {"format", required_argument, NULL, 'b'},
-#define OPTION_HELP 154
     {"help", no_argument, NULL, OPTION_HELP},
-#define OPTION_MAP 155
     {"Map", required_argument, NULL, OPTION_MAP},
-#define OPTION_NO_KEEP_MEMORY 156
     {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
-#define OPTION_NOINHIBIT_EXEC 157
     {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
     {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
-    {"non_shared", no_argument, NULL, OPTION_CALL_SHARED},
-#define OPTION_OFORMAT 158
+    {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
     {"oformat", required_argument, NULL, OPTION_OFORMAT},
-    {"Qy", no_argument, NULL, OPTION_CALL_SHARED},
-#define OPTION_RELAX 159
+    {"Qy", no_argument, NULL, OPTION_IGNORE},
+    {"qmagic", no_argument, NULL, OPTION_IGNORE}, /* Linux compatibility.  */
     {"relax", no_argument, NULL, OPTION_RELAX},
-#define OPTION_RETAIN_SYMBOLS_FILE 160
-    {"retain-symbols-file", no_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE},
-#define OPTION_SORT_COMMON 161
+    {"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},
-#define OPTION_STATS 162
+    {"start-group", no_argument, NULL, '('},
     {"stats", no_argument, NULL, OPTION_STATS},
-#define OPTION_TBSS 163
+    {"static", no_argument, NULL, OPTION_NON_SHARED},
     {"Tbss", required_argument, NULL, OPTION_TBSS},
-#define OPTION_TDATA 164
     {"Tdata", required_argument, NULL, OPTION_TDATA},
-#define OPTION_TTEXT 165
     {"Ttext", required_argument, NULL, OPTION_TTEXT},
-#define OPTION_UR 166
+    {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
     {"Ur", no_argument, NULL, OPTION_UR},
-#define OPTION_VERSION 167
     {"version", no_argument, NULL, OPTION_VERSION},
-#define OPTION_WARN_COMMON 168
     {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
+    {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -123,12 +155,11 @@ parse_args (argc, argv)
                               (char *) NULL);
          break;
 
+       case OPTION_IGNORE:
+         break;
        case 'A':
          ldfile_add_arch (optarg);
          break;
-       case 'B':
-         /* Ignore.  */
-         break;
        case 'b':
          lang_add_target (optarg);
          break;
@@ -138,7 +169,10 @@ parse_args (argc, argv)
          yyparse ();
          break;
        case OPTION_CALL_SHARED:
-         set_default_dirlist ((char *) longopts[longind].name);
+         config.dynamic_link = true;
+         break;
+       case OPTION_NON_SHARED:
+         config.dynamic_link = false;
          break;
        case 'd':
          command_line.force_common_definition = true;
@@ -148,18 +182,17 @@ parse_args (argc, argv)
          parser_input = input_defsym;
          yyparse ();
          break;
+       case OPTION_DYNAMIC_LINKER:
+         command_line.interpreter = optarg;
+         break;
        case OPTION_EB:
-         /* FIXME: This is currently ignored.  It means
-            ``produce a big-endian object file''.  It could
-            be used to select an output format.  */
+         command_line.endian = ENDIAN_BIG;
          break;
        case OPTION_EL:
-         /* FIXME: This is currently ignored.  It means
-            ``produce a little-endian object file''.  It could
-            be used to select an output format.  */
+         command_line.endian = ENDIAN_LITTLE;
          break;
        case 'e':
-         lang_add_entry (optarg);
+         lang_add_entry (optarg, 1);
          break;
        case 'F':
          /* Ignore.  */
@@ -169,7 +202,7 @@ parse_args (argc, argv)
            char *end;
            g_switch_value = strtoul (optarg, &end, 0);
            if (*end)
-             einfo ("%P%F: invalid number `%s'", optarg);
+             einfo ("%P%F: invalid number `%s'\n", optarg);
          }
          break;
        case 'g':
@@ -180,7 +213,7 @@ parse_args (argc, argv)
          xexit (0);
          break;
        case 'L':
-         ldfile_add_library_path (optarg);
+         ldfile_add_library_path (optarg, true);
          break;
        case 'l':
          lang_add_input_file (optarg, lang_input_file_is_l_enum,
@@ -193,7 +226,6 @@ parse_args (argc, argv)
          /* Ignore.  Was handled in a pre-parse.   */
          break;
        case OPTION_MAP:
-         write_map = true;
          config.map_filename = optarg;
          break;
        case 'N':
@@ -221,18 +253,51 @@ parse_args (argc, argv)
          lang_add_output (optarg, 0); 
          break;
        case OPTION_OFORMAT:
-         lang_add_output_format (optarg, 0);
+         lang_add_output_format (optarg, (char *) NULL, (char *) NULL, 0);
          break;
+       case 'i':
        case 'r':
          link_info.relocateable = true;
          config.build_constructors = false;
          config.magic_demand_paged = false;
          config.text_read_only = false;
+         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;
@@ -246,6 +311,12 @@ parse_args (argc, argv)
        case 's':
          link_info.strip = strip_all;
          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;
@@ -269,11 +340,15 @@ parse_args (argc, argv)
        case OPTION_TTEXT:
          set_section_start (".text", optarg);
          break;
+       case OPTION_TRADITIONAL_FORMAT:
+         config.traditional_format = true;
+         break;
        case OPTION_UR:
          link_info.relocateable = true;
          config.build_constructors = true;
          config.magic_demand_paged = false;
          config.text_read_only = false;
+         config.dynamic_link = false;
          break;
        case 'u':
          ldlang_add_undef (optarg);
@@ -294,6 +369,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;
@@ -306,8 +384,33 @@ parse_args (argc, argv)
        case 'y':
          add_ysym (optarg);
          break;
+       case '(':
+         if (ingroup)
+           {
+             fprintf (stderr,
+                      "%s: may not nest groups (--help for usage)\n",
+                      program_name);
+             xexit (1);
+           }
+         lang_enter_group ();
+         ingroup = 1;
+         break;
+       case ')':
+         if (! ingroup)
+           {
+             fprintf (stderr,
+                      "%s: group ended before it began (--help for usage)\n",
+                      program_name);
+             xexit (1);
+           }
+         lang_leave_group ();
+         ingroup = 0;
+         break;
        }
     }
+
+  if (ingroup)
+    lang_leave_group ();
 }
 
 /* Add the (colon-separated) elements of DIRLIST_PTR to the
@@ -325,7 +428,7 @@ set_default_dirlist (dirlist_ptr)
       if (p != NULL)
        *p = 0;
       if (*dirlist_ptr)
-       ldfile_add_library_path (dirlist_ptr);
+       ldfile_add_library_path (dirlist_ptr, true);
       if (p == NULL)
        break;
       *p = ':';
This page took 0.032936 seconds and 4 git commands to generate.