* lexsup.c (parse_args): Cast fopen result to PTR before storing
[external/binutils.git] / ld / lexsup.c
1 /* Parse options for the GNU linker.
2    Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
3
4 This file is part of GLD, the Gnu Linker.
5
6 GLD is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GLD is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GLD; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include <stdio.h>
23 #include <string.h>
24 #include "getopt.h"
25 #include "bfdlink.h"
26 #include "config.h"
27 #include "ld.h"
28 #include "ldmain.h"
29 #include "ldmisc.h"
30 #include "ldexp.h"
31 #include "ldlang.h"
32 #include "ldgram.h"
33 #include "ldlex.h"
34 #include "ldfile.h"
35 #include "ldver.h"
36
37 /* Somewhere above, sys/stat.h got included . . . . */
38 #if !defined(S_ISDIR) && defined(S_IFDIR)
39 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
40 #endif
41
42 /* Omit args to avoid the possibility of clashing with a system header
43    that might disagree about consts.  */
44 unsigned long strtoul ();
45
46 static void set_default_dirlist PARAMS ((char *dirlist_ptr));
47 static void set_section_start PARAMS ((char *sect, char *valstr));
48
49 /* WINDOWS_NT; declare additional functions */
50 static void set_subsystem PARAMS ((char *subsystem_type));
51 static void set_stack_heap PARAMS ((char *valstr, boolean for_heap));
52
53 void
54 parse_args (argc, argv)
55      int argc;
56      char **argv;
57 {
58   int ingroup = 0;
59
60   /* Starting the short option string with '-' is for programs that
61      expect options and other ARGV-elements in any order and that care about
62      the ordering of the two.  We describe each non-option ARGV-element
63      as if it were the argument of an option with character code 1.  */
64
65   const char *shortopts =
66     "-a:A:B::b:c:de:F::G:giL:l:Mm:NnO:o:R:rSsT:tu:VvXxY:y:()";
67
68   /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
69
70 #define OPTION_CALL_SHARED              150
71 #define OPTION_DEFSYM                   (OPTION_CALL_SHARED + 1)
72 #define OPTION_DYNAMIC_LINKER           (OPTION_DEFSYM + 1)
73 #define OPTION_EB                       (OPTION_DYNAMIC_LINKER + 1)
74 #define OPTION_EL                       (OPTION_EB + 1)
75 #define OPTION_HEAP                     (OPTION_EL + 1)
76 #define OPTION_EMBEDDED_RELOCS          (OPTION_HEAP + 1)
77 #define OPTION_EXPORT_DYNAMIC           (OPTION_EMBEDDED_RELOCS + 1)
78 #define OPTION_HELP                     (OPTION_EXPORT_DYNAMIC + 1)
79 #define OPTION_IGNORE                   (OPTION_HELP + 1)
80 #define OPTION_MAP                      (OPTION_IGNORE + 1)
81 #define OPTION_NO_KEEP_MEMORY           (OPTION_MAP + 1)
82 #define OPTION_NOINHIBIT_EXEC           (OPTION_NO_KEEP_MEMORY + 1)
83 #define OPTION_NON_SHARED               (OPTION_NOINHIBIT_EXEC + 1)
84 #define OPTION_OFORMAT                  (OPTION_NON_SHARED + 1)
85 #define OPTION_RELAX                    (OPTION_OFORMAT + 1)
86 #define OPTION_RETAIN_SYMBOLS_FILE      (OPTION_RELAX + 1)
87 #define OPTION_RPATH                    (OPTION_RETAIN_SYMBOLS_FILE + 1)
88 #define OPTION_SHARED                   (OPTION_RPATH + 1)
89 #define OPTION_SONAME                   (OPTION_SHARED + 1)
90 #define OPTION_SORT_COMMON              (OPTION_SONAME + 1)
91 #define OPTION_STACK                    (OPTION_SORT_COMMON + 1) /*WINDOWS_NT*/
92 #define OPTION_STATS                    (OPTION_STACK + 1)
93 #define OPTION_SUBSYSTEM                (OPTION_STATS + 1) /* WINDOWS_NT */
94 #define OPTION_TBSS                     (OPTION_SUBSYSTEM + 1)
95 #define OPTION_TDATA                    (OPTION_TBSS + 1)
96 #define OPTION_TTEXT                    (OPTION_TDATA + 1)
97 #define OPTION_TRADITIONAL_FORMAT       (OPTION_TTEXT + 1)
98 #define OPTION_UR                       (OPTION_TRADITIONAL_FORMAT + 1)
99 #define OPTION_VERBOSE                  (OPTION_UR + 1)
100 #define OPTION_VERSION                  (OPTION_VERBOSE + 1)
101 #define OPTION_WARN_COMMON              (OPTION_VERSION + 1)
102 #define OPTION_WARN_ONCE                (OPTION_WARN_COMMON + 1)
103 #define OPTION_SPLIT_BY_RELOC           (OPTION_WARN_ONCE + 1)
104 #define OPTION_SPLIT_BY_FILE            (OPTION_SPLIT_BY_RELOC + 1)
105 #define OPTION_WHOLE_ARCHIVE            (OPTION_SPLIT_BY_FILE + 1)
106 #define OPTION_BASE_FILE                (OPTION_WHOLE_ARCHIVE + 1)
107   static struct option longopts[] = {
108     {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
109     {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
110     {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
111     {"dc", no_argument, NULL, 'd'},
112     {"defsym", required_argument, NULL, OPTION_DEFSYM},
113     {"dll-verbose", no_argument, NULL, OPTION_VERSION}, /* Linux.  */
114     {"dn", no_argument, NULL, OPTION_NON_SHARED},
115     {"dp", no_argument, NULL, 'd'},
116     {"dy", no_argument, NULL, OPTION_CALL_SHARED},
117     {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
118     {"EB", no_argument, NULL, OPTION_EB},
119     {"EL", no_argument, NULL, OPTION_EL},
120     {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
121     {"end-group", no_argument, NULL, ')'},
122     {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
123     {"format", required_argument, NULL, 'b'},
124     {"heap", required_argument, NULL, OPTION_HEAP}, /* WINDOWS_NT */
125     {"help", no_argument, NULL, OPTION_HELP},
126     {"Map", required_argument, NULL, OPTION_MAP},
127     {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
128     {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
129     {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
130     {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
131     {"oformat", required_argument, NULL, OPTION_OFORMAT},
132     {"Qy", no_argument, NULL, OPTION_IGNORE},
133     {"qmagic", no_argument, NULL, OPTION_IGNORE}, /* Linux compatibility.  */
134     {"relax", no_argument, NULL, OPTION_RELAX},
135     {"retain-symbols-file", required_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE},
136     {"rpath", required_argument, NULL, OPTION_RPATH},
137     {"shared", no_argument, NULL, OPTION_SHARED},
138     {"soname", required_argument, NULL, OPTION_SONAME},
139     {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
140     {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
141     {"stack", required_argument, NULL, OPTION_STACK}, /* WINDOWS_NT */
142     {"start-group", no_argument, NULL, '('},
143     {"stats", no_argument, NULL, OPTION_STATS},
144     {"static", no_argument, NULL, OPTION_NON_SHARED},
145     {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, /* WINDOWS_NT */
146     {"Tbss", required_argument, NULL, OPTION_TBSS},
147     {"Tdata", required_argument, NULL, OPTION_TDATA},
148     {"Ttext", required_argument, NULL, OPTION_TTEXT},
149     {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
150     {"Ur", no_argument, NULL, OPTION_UR},
151     {"verbose", no_argument, NULL, OPTION_VERBOSE},
152     {"version", no_argument, NULL, OPTION_VERSION},
153     {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
154     {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
155     {"split-by-reloc", required_argument, NULL, OPTION_SPLIT_BY_RELOC},
156     {"split-by-file", no_argument, NULL, OPTION_SPLIT_BY_FILE},
157     {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
158     {"base-file", required_argument, NULL, OPTION_BASE_FILE},
159     {NULL, no_argument, NULL, 0}
160   };
161
162   while (1)
163     {
164       /* getopt_long_only is like getopt_long, but '-' as well as '--' can
165          indicate a long option.  */
166       int longind;
167       int optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
168
169       if (optc == -1)
170         break;
171
172       switch (optc)
173         {
174         default:
175           xexit (1);
176         case 1:                 /* File name.  */
177           lang_add_input_file (optarg, lang_input_file_is_file_enum,
178                                (char *) NULL);
179           break;
180
181         case OPTION_IGNORE:
182           break;
183         case 'a':
184           /* For HP/UX compatibility.  Actually -a shared should mean
185              ``use only shared libraries'' but, then, we don't
186              currently support shared libraries on HP/UX anyhow.  */
187           if (strcmp (optarg, "archive") == 0)
188             config.dynamic_link = false;
189           else if (strcmp (optarg, "shared") == 0
190                    || strcmp (optarg, "default") == 0)
191             config.dynamic_link = true;
192           else
193             einfo ("%P%F: unrecognized -a option `%s'\n", optarg);
194           break;
195         case 'A':
196           ldfile_add_arch (optarg);
197           break;
198         case 'b':
199           lang_add_target (optarg);
200           break;
201         case 'c':
202           ldfile_open_command_file (optarg);
203           parser_input = input_mri_script;
204           yyparse ();
205           break;
206         case OPTION_CALL_SHARED:
207           config.dynamic_link = true;
208           break;
209         case OPTION_NON_SHARED:
210           config.dynamic_link = false;
211           break;
212         case 'd':
213           command_line.force_common_definition = true;
214           break;
215         case OPTION_DEFSYM:
216           lex_redirect (optarg);
217           parser_input = input_defsym;
218           yyparse ();
219           break;
220         case OPTION_DYNAMIC_LINKER:
221           command_line.interpreter = optarg;
222           break;
223         case OPTION_EB:
224           command_line.endian = ENDIAN_BIG;
225           break;
226         case OPTION_EL:
227           command_line.endian = ENDIAN_LITTLE;
228           break;
229         case OPTION_EMBEDDED_RELOCS:
230           command_line.embedded_relocs = true;
231           break;
232         case OPTION_EXPORT_DYNAMIC:
233           command_line.export_dynamic = true;
234           break;
235         case 'e':
236           lang_add_entry (optarg, 1);
237           break;
238         case 'F':
239           /* Ignore.  */
240           break;
241         case 'G':
242           {
243             char *end;
244             g_switch_value = strtoul (optarg, &end, 0);
245             if (*end)
246               einfo ("%P%F: invalid number `%s'\n", optarg);
247           }
248           break;
249         case 'g':
250           /* Ignore.  */
251           break;
252         case OPTION_HEAP:  /* WINDOWS_NT */
253           link_info.stack_heap_parameters.heap_defined = true;
254           set_stack_heap (optarg, true);
255           break;
256         case OPTION_HELP:
257           help ();
258           xexit (0);
259           break;
260         case 'L':
261           ldfile_add_library_path (optarg, true);
262           break;
263         case 'l':
264           lang_add_input_file (optarg, lang_input_file_is_l_enum,
265                                (char *) NULL);
266           break;
267         case 'M':
268           config.map_filename = "-";
269           break;
270         case 'm':
271           /* Ignore.  Was handled in a pre-parse.   */
272           break;
273         case OPTION_MAP:
274           config.map_filename = optarg;
275           break;
276         case 'N':
277           config.text_read_only = false;
278           config.magic_demand_paged = false;
279           break;
280         case 'n':
281           config.magic_demand_paged = false;
282           break;
283         case OPTION_NO_KEEP_MEMORY:
284           link_info.keep_memory = false;
285           break;
286         case OPTION_NOINHIBIT_EXEC:
287           force_make_executable = true;
288           break;
289         case 'O':
290           /* FIXME "-O<non-digits> <value>" used to set the address of
291              section <non-digits>.  Was this for compatibility with
292              something, or can we create a new option to do that
293              (with a syntax similar to -defsym)?
294              getopt can't handle two args to an option without kludges.  */
295           set_default_dirlist (optarg);
296           break;
297         case 'o':
298           lang_add_output (optarg, 0); 
299           break;
300         case OPTION_OFORMAT:
301           lang_add_output_format (optarg, (char *) NULL, (char *) NULL, 0);
302           break;
303         case 'i':
304         case 'r':
305           link_info.relocateable = true;
306           config.build_constructors = false;
307           config.magic_demand_paged = false;
308           config.text_read_only = false;
309           config.dynamic_link = false;
310           break;
311         case 'R':
312           /* The GNU linker traditionally uses -R to mean to include
313              only the symbols from a file.  The Solaris linker uses -R
314              to set the path used by the runtime linker to find
315              libraries.  This is the GNU linker -rpath argument.  We
316              try to support both simultaneously by checking the file
317              named.  If it is a directory, rather than a regular file,
318              we assume -rpath was meant.  */
319           {
320             struct stat s;
321
322             if (stat (optarg, &s) >= 0
323                 && ! S_ISDIR (s.st_mode))
324               {
325                 lang_add_input_file (optarg,
326                                      lang_input_file_is_symbols_only_enum,
327                                      (char *) NULL);
328                 break;
329               }
330           }
331           /* Fall through.  */
332         case OPTION_RPATH:
333           if (command_line.rpath == NULL)
334             command_line.rpath = buystring (optarg);
335           else
336             {
337               char *buf;
338
339               buf = xmalloc (strlen (command_line.rpath)
340                              + strlen (optarg)
341                              + 2);
342               sprintf (buf, "%s:%s", command_line.rpath, optarg);
343               free (command_line.rpath);
344               command_line.rpath = buf;
345             }
346           break;
347         case OPTION_RELAX:
348           command_line.relax = true;
349           break;
350         case OPTION_RETAIN_SYMBOLS_FILE:
351           add_keepsyms_file (optarg);
352           break;
353         case 'S':
354           link_info.strip = strip_debugger;
355           break;
356         case 's':
357           link_info.strip = strip_all;
358           break;
359         case OPTION_SHARED:
360           link_info.shared = true;
361           break;
362         case OPTION_SONAME:
363           command_line.soname = optarg;
364           break;
365         case OPTION_SORT_COMMON:
366           config.sort_common = true;
367           break;
368         case OPTION_STACK:  /* WINDOWS_NT */
369           link_info.stack_heap_parameters.stack_defined = true;
370           set_stack_heap (optarg, false);
371           break;
372         case OPTION_STATS:
373           config.stats = true;
374           break;
375         case OPTION_SUBSYSTEM:  /* WINDOWS_NT */
376           set_subsystem (optarg);
377           break;
378         case 't':
379           trace_files = true;
380           break;
381         case 'T':
382           ldfile_open_command_file (optarg);
383           parser_input = input_script;
384           yyparse ();
385           break;
386         case OPTION_TBSS:
387           set_section_start (".bss", optarg);
388           break;
389         case OPTION_TDATA:
390           set_section_start (".data", optarg);
391           break;
392         case OPTION_TTEXT:
393           set_section_start (".text", optarg);
394           break;
395         case OPTION_TRADITIONAL_FORMAT:
396           config.traditional_format = true;
397           break;
398         case OPTION_UR:
399           link_info.relocateable = true;
400           config.build_constructors = true;
401           config.magic_demand_paged = false;
402           config.text_read_only = false;
403           config.dynamic_link = false;
404           break;
405         case 'u':
406           ldlang_add_undef (optarg);
407           break;
408         case OPTION_VERBOSE:
409           ldversion (1);
410           version_printed = true;
411           trace_file_tries = true;
412           break;
413         case 'v':
414           ldversion (0);
415           version_printed = true;
416           break;
417         case 'V':
418           ldversion (1);
419           version_printed = true;
420           break;
421         case OPTION_VERSION:
422           ldversion (0);
423           version_printed = true;
424           break;
425         case OPTION_WARN_COMMON:
426           config.warn_common = true;
427           break;
428         case OPTION_WARN_ONCE:
429           config.warn_once = true;
430           break;
431         case OPTION_WHOLE_ARCHIVE:
432           whole_archive = true;
433           break;
434         case OPTION_BASE_FILE:
435           link_info.base_file = (PTR) fopen (optarg,"w");
436           if (link_info.base_file == NULL)
437             {
438               fprintf (stderr, "%s: Can't open base file %s\n",
439                        program_name, optarg);
440               xexit (1);
441             }
442           break;
443         case 'X':
444           link_info.discard = discard_l;
445           break;
446         case 'x':
447           link_info.discard = discard_all;
448           break;
449         case 'Y':
450           set_default_dirlist (optarg);
451           break;
452         case 'y':
453           add_ysym (optarg);
454           break;
455         case OPTION_SPLIT_BY_RELOC:
456           config.split_by_reloc = atoi (optarg);
457           break; 
458         case OPTION_SPLIT_BY_FILE:
459           config.split_by_file = true;
460           break; 
461         case '(':
462           if (ingroup)
463             {
464               fprintf (stderr,
465                        "%s: may not nest groups (--help for usage)\n",
466                        program_name);
467               xexit (1);
468             }
469           lang_enter_group ();
470           ingroup = 1;
471           break;
472         case ')':
473           if (! ingroup)
474             {
475               fprintf (stderr,
476                        "%s: group ended before it began (--help for usage)\n",
477                        program_name);
478               xexit (1);
479             }
480           lang_leave_group ();
481           ingroup = 0;
482           break;
483         }
484     }
485
486   if (ingroup)
487     lang_leave_group ();
488 }
489
490 /* Add the (colon-separated) elements of DIRLIST_PTR to the
491    library search path.  */
492
493 static void
494 set_default_dirlist (dirlist_ptr)
495      char *dirlist_ptr;
496 {
497   char *p;
498
499   while (1)
500     {
501       p = strchr (dirlist_ptr, ':');
502       if (p != NULL)
503         *p = 0;
504       if (*dirlist_ptr)
505         ldfile_add_library_path (dirlist_ptr, true);
506       if (p == NULL)
507         break;
508       *p = ':';
509       dirlist_ptr = p + 1;
510     }
511 }
512
513 static void
514 set_section_start (sect, valstr)
515      char *sect, *valstr;
516 {
517   char *end;
518   unsigned long val = strtoul (valstr, &end, 16);
519   if (*end)
520     einfo ("%P%F: invalid hex number `%s'\n", valstr);
521   lang_section_start (sect, exp_intop (val));
522 }
523
524 /* WINDOWS_NT; added routines to get the subsystem type, heap and/or stack
525    parameters which may be input from the command line */
526 static void
527 set_subsystem (subsystem_type)
528   char *subsystem_type;
529 {
530   if (strcmp (subsystem_type, "native") == 0)
531     {
532       link_info.subsystem = native;
533     }
534   else if (strcmp (subsystem_type, "windows") == 0)
535     {
536       link_info.subsystem = windows;
537     }
538   else if (strcmp (subsystem_type, "console") == 0)
539     {
540       link_info.subsystem = console;
541     }
542   else if (strcmp (subsystem_type, "os2") == 0)
543     {
544       link_info.subsystem = os2;
545     }
546   else if (strcmp (subsystem_type, "posix") == 0)
547     {
548       link_info.subsystem = posix;
549     }
550   else
551     einfo ("%P%F: invalid subsystem type `%s'\n", subsystem_type);
552
553 }
554
555 static void
556 set_stack_heap (valstr, for_heap)
557   char *valstr;
558   boolean for_heap;
559 {
560   char *begin_commit, *end;
561   bfd_vma reserve = 0;
562   bfd_vma commit  = 0;
563
564   /* There may be two values passed in to the -stack or -heap switches like
565      this:
566        -stack 0x10000,0x100
567      where the first parameter is the stack (or heap) reserve and the second
568      is commit.  The second parameter is optional. */
569
570   /* get the reserve value */
571   reserve = strtoul (valstr, &begin_commit, 16);
572
573   if (strcmp (valstr, begin_commit) == 0)  
574     /* the reserve value couldn't be read */
575     einfo ("%P%F: invalid hex number for reserve[,commit] '%s'\n", valstr); 
576   else if (strcmp (begin_commit, "\0") != 0)  /* check for a commit value */
577     {
578      begin_commit += 1;  /* increment begin_commit to point past ',' */
579      commit = strtoul (begin_commit, &end, 16);
580      if (strcmp (end, begin_commit) == 0)
581        einfo ("%P%F: invalid hex number for commit '%s'\n", begin_commit);
582     }
583    
584   if (for_heap)
585    {
586     link_info.stack_heap_parameters.heap_reserve = reserve;     
587     link_info.stack_heap_parameters.heap_commit  = commit;     
588    }
589   else
590    {
591     link_info.stack_heap_parameters.stack_reserve = reserve;     
592     link_info.stack_heap_parameters.stack_commit  = commit;     
593    }
594
595 #if DUMP_INFO
596   printf ("reserve = %8x  commit = %8x\n", reserve, commit);
597 #endif
598 }