Use EXIT_SUCCESS and EXIT_FAILURE in all exit calls.
[external/binutils.git] / gas / as.c
1 /* as.c - GAS main program.
2    Copyright (C) 1987, 1990, 1991, 1992, 1994 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS 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    GAS 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 GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21  * Main program for AS; a 32-bit assembler of GNU.
22  * Understands command arguments.
23  * Has a few routines that don't fit in other modules because they
24  * are shared.
25  *
26  *
27  *                      bugs
28  *
29  * : initialisers
30  *      Since no-one else says they will support them in future: I
31  * don't support them now.
32  *
33  */
34
35 #include "ansidecl.h"
36 #include "libiberty.h"
37
38 #define COMMON
39
40 #include "as.h"
41 #include "subsegs.h"
42 #include "output-file.h"
43
44 #include <signal.h>
45
46 #ifndef SIGTY
47 #ifdef __STDC__
48 #define SIGTY void
49 #else
50 #define SIGTY int
51 #endif /* __STDC__ */
52 #endif /* SIGTY */
53
54 #if 0
55 /* Not currently used.  */
56 static SIGTY got_sig PARAMS ((int sig));
57 #endif
58 static void perform_an_assembly_pass PARAMS ((int argc, char **argv));
59
60 int listing;                    /* true if a listing is wanted */
61
62 char *myname;                   /* argv[0] */
63 #ifdef BFD_ASSEMBLER
64 segT reg_section, expr_section;
65 segT text_section, data_section, bss_section;
66 #endif
67
68 \f
69 void
70 print_version_id ()
71 {
72   static int printed;
73   if (printed)
74     return;
75   printed = 1;
76
77   fprintf (stderr, "GNU assembler version %s (%s)", GAS_VERSION, TARGET_ALIAS);
78 #ifdef BFD_ASSEMBLER
79   fprintf (stderr, ", using BFD version %s", BFD_VERSION);
80 #endif
81   fprintf (stderr, "\n");
82 }
83
84 void
85 show_usage (stream)
86      FILE *stream;
87 {
88   fprintf (stream, "Usage: %s [option...] [asmfile...]\n", myname);
89
90   fprintf (stream, "\
91 Options:\n\
92 -a[sub-option...]       turn on listings\n\
93   Sub-options [default hls]:\n\
94   d     omit debugging directives\n\
95   h     include high-level source\n\
96   l     include assembly\n\
97   n     omit forms processing\n\
98   s     include symbols\n");
99   fprintf (stream, "\
100 -D                      produce assembler debugging messages\n\
101 -f                      skip whitespace and comment preprocessing\n\
102 --help                  show this message and exit\n\
103 -I DIR                  add DIR to search list for .include directives\n\
104 -J                      don't warn about signed overflow\n\
105 -K                      warn when differences altered for long displacements\n\
106 -L                      keep local symbols (starting with `L')\n");
107   fprintf (stream, "\
108 -nocpp                  ignored\n\
109 -o OBJFILE              name the object-file output OBJFILE (default a.out)\n\
110 -R                      fold data section into text section\n\
111 --statistics            print maximum bytes and total seconds used\n\
112 --version               print assembler version number and exit\n\
113 -W                      suppress warnings\n\
114 -w                      ignored\n\
115 -X                      ignored\n\
116 -Z                      generate object file even after errors\n");
117
118   md_show_usage (stream);
119 }
120
121 /*
122  * Since it is easy to do here we interpret the special arg "-"
123  * to mean "use stdin" and we set that argv[] pointing to "".
124  * After we have munged argv[], the only things left are source file
125  * name(s) and ""(s) denoting stdin. These file names are used
126  * (perhaps more than once) later.
127  *
128  * check for new machine-dep cmdline options in
129  * md_parse_option definitions in config/tc-*.c
130  */
131
132 void
133 parse_args (pargc, pargv)
134      int *pargc;
135      char ***pargv;
136 {
137   int old_argc, new_argc;
138   char **old_argv, **new_argv;
139
140   /* Starting the short option string with '-' is for programs that
141      expect options and other ARGV-elements in any order and that care about
142      the ordering of the two.  We describe each non-option ARGV-element
143      as if it were the argument of an option with character code 1.  */
144
145   char *shortopts;
146   extern CONST char *md_shortopts;
147   /* -v takes an argument on VMS, so we don't make it a generic option
148      in that case.  */
149 #ifdef OBJ_VMS
150   CONST char *std_shortopts = "-JKLRWZfa::DI:o:wX";
151 #else
152   /* Normal set of short options.  */
153   CONST char *std_shortopts = "-JKLRWZfa::DI:o:vwX";
154 #endif
155
156   struct option *longopts;
157   extern struct option md_longopts[];
158   extern size_t md_longopts_size;
159   static const struct option std_longopts[] = {
160 #define OPTION_HELP (OPTION_STD_BASE)
161     {"help", no_argument, NULL, OPTION_HELP},
162 #define OPTION_NOCPP (OPTION_STD_BASE + 1)
163     {"nocpp", no_argument, NULL, OPTION_NOCPP},
164 #define OPTION_STATISTICS (OPTION_STD_BASE + 2)
165     {"statistics", no_argument, NULL, OPTION_STATISTICS},
166 #define OPTION_VERSION (OPTION_STD_BASE + 3)
167     {"version", no_argument, NULL, OPTION_VERSION},
168 #define OPTION_DUMPCONFIG (OPTION_STD_BASE + 4)
169     {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG},
170   };
171
172   /* Construct the option lists from the standard list and the
173      target dependent list.  */
174   shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
175   longopts = (struct option *) xmalloc (sizeof (std_longopts) + md_longopts_size);
176   memcpy (longopts, std_longopts, sizeof (std_longopts));
177   memcpy ((char *) longopts + sizeof (std_longopts),
178           md_longopts, md_longopts_size);
179
180   /* Make a local copy of the old argv.  */
181   old_argc = *pargc;
182   old_argv = *pargv;
183
184   /* Initialize a new argv that contains no options.  */
185   new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1));
186   new_argv[0] = old_argv[0];
187   new_argc = 1;
188   new_argv[new_argc] = NULL;
189
190   while (1)
191     {
192       /* getopt_long_only is like getopt_long, but '-' as well as '--' can
193          indicate a long option.  */
194       int longind;
195       int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
196                                    &longind);
197
198       if (optc == -1)
199         break;
200
201       switch (optc)
202         {
203         default:
204           /* md_parse_option should return 1 if it recognizes optc,
205              0 if not.  */
206           if (md_parse_option (optc, optarg) == 0)
207             exit (EXIT_FAILURE);
208           break;
209
210         case '?':
211           exit (EXIT_FAILURE);
212
213         case 1:                 /* File name.  */
214           if (!strcmp (optarg, "-"))
215             optarg = "";
216           new_argv[new_argc++] = optarg;
217           new_argv[new_argc] = NULL;
218           break;
219
220         case OPTION_HELP:
221           show_usage (stdout);
222           exit (EXIT_SUCCESS);
223
224         case OPTION_NOCPP:
225           break;
226
227         case OPTION_STATISTICS:
228           flag_print_statistics = 1;
229           break;
230
231         case OPTION_VERSION:
232           print_version_id ();
233           exit (EXIT_SUCCESS);
234
235         case OPTION_DUMPCONFIG:
236           fprintf (stderr, "alias = %s\n", TARGET_ALIAS);
237           fprintf (stderr, "canonical = %s\n", TARGET_CANONICAL);
238           fprintf (stderr, "cpu-type = %s\n", TARGET_CPU);
239 #ifdef TARGET_OBJ_FORMAT
240           fprintf (stderr, "format = %s\n", TARGET_OBJ_FORMAT);
241 #endif
242 #ifdef TARGET_FORMAT
243           fprintf (stderr, "bfd-target = %s\n", TARGET_FORMAT);
244 #endif
245           exit (EXIT_SUCCESS);
246
247         case 'v':
248           print_version_id ();
249
250         case 'J':
251           flag_signed_overflow_ok = 1;
252           break;
253
254         case 'K':
255           flag_warn_displacement = 1;
256           break;
257
258         case 'L':
259           flag_keep_locals = 1;
260           break;
261
262         case 'R':
263           flag_readonly_data_in_text = 1;
264           break;
265
266         case 'W':
267           flag_no_warnings = 1;
268           break;
269
270         case 'Z':
271           flag_always_generate_output = 1;
272           break;
273
274         case 'a':
275           if (optarg)
276             {
277               while (*optarg)
278                 {
279                   switch (*optarg)
280                     {
281                     case 'd':
282                       listing |= LISTING_NODEBUG;
283                       break;
284                     case 'h':
285                       listing |= LISTING_HLL;
286                       break;
287                     case 'l':
288                       listing |= LISTING_LISTING;
289                       break;
290                     case 'n':
291                       listing |= LISTING_NOFORM;
292                       break;
293                     case 's':
294                       listing |= LISTING_SYMBOLS;
295                       break;
296                     default:
297                       as_fatal ("invalid listing option `%c'", *optarg);
298                       break;
299                     }
300                   optarg++;
301                 }
302             }
303           if (!listing)
304             listing = LISTING_DEFAULT;
305           break;
306
307         case 'D':
308           /* DEBUG is implemented: it debugs different */
309           /* things from other people's assemblers. */
310           flag_debug = 1;
311           break;
312
313         case 'f':
314           flag_no_comments = 1;
315           break;
316
317         case 'I':
318           {                     /* Include file directory */
319             char *temp = strdup (optarg);
320             if (!temp)
321               as_fatal ("virtual memory exhausted");
322             add_include_dir (temp);
323             break;
324           }
325
326         case 'o':
327           out_file_name = strdup (optarg);
328           if (!out_file_name)
329             as_fatal ("virtual memory exhausted");
330           break;
331
332         case 'w':
333           break;
334
335         case 'X':
336           /* -X means treat warnings as errors */
337           break;
338         }
339     }
340
341   free (shortopts);
342   free (longopts);
343
344   *pargc = new_argc;
345   *pargv = new_argv;
346 }
347
348 int 
349 main (argc, argv)
350      int argc;
351      char **argv;
352 {
353   int keep_it;
354   long start_time = get_run_time ();
355
356 #ifdef HOST_SPECIAL_INIT
357   HOST_SPECIAL_INIT (argc, argv);
358 #endif
359
360 #if 0 /* do we need any of this?? */
361   {
362     static const int sig[] = {SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
363     int a;
364
365     for (a = 0; sig[a] != 0; a++)
366       if (signal (sig[a], SIG_IGN) != SIG_IGN)
367         signal (sig[a], got_sig);
368   }
369 #endif
370
371   myname = argv[0];
372 #ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
373 #define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
374 #endif
375   out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
376
377 #ifdef BFD_ASSEMBLER
378   bfd_init ();
379 #endif
380
381   symbol_begin ();
382   subsegs_begin ();
383   read_begin ();
384   input_scrub_begin ();
385   frag_init ();
386   parse_args (&argc, &argv);
387
388 #ifdef BFD_ASSEMBLER
389   output_file_create (out_file_name);
390   assert (stdoutput != 0);
391 #endif
392
393 #ifdef tc_init_after_args
394   tc_init_after_args ();
395 #endif
396
397   perform_an_assembly_pass (argc, argv);        /* Assemble it. */
398 #ifdef TC_I960
399   brtab_emit ();
400 #endif
401
402   if (seen_at_least_1_file ()
403       && !((had_warnings () && flag_always_generate_output)
404            || had_errors () > 0))
405     keep_it = 1;
406   else
407     keep_it = 0;
408
409   if (keep_it)
410     write_object_file ();
411
412 #ifndef NO_LISTING
413   listing_print ("");
414 #endif
415
416 #ifndef OBJ_VMS /* does its own file handling */
417 #ifndef BFD_ASSEMBLER
418   if (keep_it)
419 #endif
420     output_file_close (out_file_name);
421 #endif
422
423   if (!keep_it)
424     unlink (out_file_name);
425
426   input_scrub_end ();
427 #ifdef md_end
428   md_end ();
429 #endif
430
431   if (flag_print_statistics)
432     {
433       extern char **environ;
434       char *lim = (char *) sbrk (0);
435       long run_time = get_run_time () - start_time;
436
437       fprintf (stderr, "%s: total time in assembly: %ld.%06ld\n",
438                myname, run_time / 1000000, run_time % 1000000);
439       fprintf (stderr, "%s: data size %ld\n",
440                myname, (long) (lim - (char *) &environ));
441     }
442
443   /* Use exit instead of return, because under VMS environments they
444      may not place the same interpretation on the value given.  */
445   if ((had_warnings () && flag_always_generate_output)
446       || had_errors () > 0)
447     exit (EXIT_FAILURE);
448   exit (EXIT_SUCCESS);
449 }
450 \f
451
452 /*                      perform_an_assembly_pass()
453  *
454  * Here to attempt 1 pass over each input file.
455  * We scan argv[*] looking for filenames or exactly "" which is
456  * shorthand for stdin. Any argv that is NULL is not a file-name.
457  * We set need_pass_2 TRUE if, after this, we still have unresolved
458  * expressions of the form (unknown value)+-(unknown value).
459  *
460  * Note the un*x semantics: there is only 1 logical input file, but it
461  * may be a catenation of many 'physical' input files.
462  */
463 static void 
464 perform_an_assembly_pass (argc, argv)
465      int argc;
466      char **argv;
467 {
468   int saw_a_file = 0;
469 #ifdef BFD_ASSEMBLER
470   flagword applicable;
471 #endif
472
473   need_pass_2 = 0;
474
475 #ifndef BFD_ASSEMBLER
476 #ifdef MANY_SEGMENTS
477   {
478     unsigned int i;
479     for (i = SEG_E0; i < SEG_UNKNOWN; i++)
480       segment_info[i].fix_root = 0;
481   }
482   /* Create the three fixed ones */
483   {
484     segT seg;
485
486 #ifdef TE_APOLLO
487     seg = subseg_new (".wtext", 0);
488 #else
489     seg = subseg_new (".text", 0);
490 #endif
491     assert (seg == SEG_E0);
492     seg = subseg_new (".data", 0);
493     assert (seg == SEG_E1);
494     seg = subseg_new (".bss", 0);
495     assert (seg == SEG_E2);
496 #ifdef TE_APOLLO
497     create_target_segments ();
498 #endif
499   }
500
501 #else /* not MANY_SEGMENTS */
502   text_fix_root = NULL;
503   data_fix_root = NULL;
504   bss_fix_root = NULL;
505 #endif /* not MANY_SEGMENTS */
506 #else /* BFD_ASSEMBLER */
507   /* Create the standard sections, and those the assembler uses
508      internally.  */
509   text_section = subseg_new (".text", 0);
510   data_section = subseg_new (".data", 0);
511   bss_section = subseg_new (".bss", 0);
512   /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
513      to have relocs, otherwise we don't find out in time. */
514   applicable = bfd_applicable_section_flags (stdoutput);
515   bfd_set_section_flags (stdoutput, text_section,
516                          applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
517                                        | SEC_CODE | SEC_READONLY));
518   /* @@ FIXME -- SEC_CODE seems to mean code only, rather than code possibly.*/
519   bfd_set_section_flags (stdoutput, data_section,
520                          applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC));
521   bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
522   seg_info (bss_section)->bss = 1;
523   subseg_new (BFD_ABS_SECTION_NAME, 0);
524   subseg_new (BFD_UND_SECTION_NAME, 0);
525   reg_section = subseg_new ("*GAS `reg' section*", 0);
526   expr_section = subseg_new ("*GAS `expr' section*", 0);
527
528 #endif /* BFD_ASSEMBLER */
529
530   subseg_set (text_section, 0);
531
532   /* This may add symbol table entries, which requires having an open BFD,
533      and sections already created, in BFD_ASSEMBLER mode.  */
534   md_begin ();
535
536   argv++;                       /* skip argv[0] */
537   argc--;                       /* skip argv[0] */
538   while (argc--)
539     {
540       if (*argv)
541         {                       /* Is it a file-name argument? */
542           saw_a_file++;
543           /* argv->"" if stdin desired, else->filename */
544           read_a_source_file (*argv);
545         }
546       argv++;                   /* completed that argv */
547     }
548   if (!saw_a_file)
549     read_a_source_file ("");
550 }                               /* perform_an_assembly_pass() */
551 \f
552 #if 0
553 /* This is not currently used.  */
554 static SIGTY
555 got_sig (sig)
556      int sig;
557 {
558   static here_before = 0;
559
560   as_bad ("Interrupted by signal %d", sig);
561   if (here_before++)
562     exit (EXIT_FAILURE);
563 #if 0 /* If SIGTY is void, this produces warnings.  */
564   return ((SIGTY) 0);
565 #endif
566 }
567 #endif
568
569 /* end of as.c */