]> Git Repo - binutils.git/blob - gas/as.c
* gas/hppa/reloc/reloc.exp: Minor fixes so that SOM & ELF can
[binutils.git] / gas / as.c
1 /* as.c - GAS main program.
2    Copyright (C) 1987, 1990, 1991, 1992 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 <stdio.h>
36 #include <string.h>
37
38 #ifdef _POSIX_SOURCE
39 #include <sys/types.h>          /* For pid_t in signal.h */
40 #endif
41 #include <signal.h>
42
43 #define COMMON
44
45 #include "as.h"
46 #include "config.h"
47 #include "subsegs.h"
48 #include "output-file.h"
49
50 #ifndef SIGTY
51 #ifdef __STDC__
52 #define SIGTY void
53 #else
54 #define SIGTY int
55 #endif /* __STDC__ */
56 #endif /* SIGTY */
57
58 #if 0
59 /* Not currently used.  */
60 static SIGTY got_sig PARAMS ((int sig));
61 #endif
62 static void perform_an_assembly_pass PARAMS ((int argc, char **argv));
63
64 #ifndef EXIT_SUCCESS
65 #define EXIT_SUCCESS 0
66 #define EXIT_FAILURE 1
67 #endif
68
69 int listing;                    /* true if a listing is wanted */
70
71 char *myname;                   /* argv[0] */
72 #ifdef BFD_ASSEMBLER
73 segT reg_section, expr_section;
74 segT text_section, data_section, bss_section;
75 #endif
76 \f
77 void
78 print_version_id ()
79 {
80   static int printed;
81   if (printed)
82     return;
83   printed = 1;
84
85   fprintf (stderr, "GNU assembler version %s (%s)", GAS_VERSION, TARGET_ALIAS);
86 #ifdef BFD_ASSEMBLER
87   fprintf (stderr, ", using BFD version %s", BFD_VERSION);
88 #endif
89   fprintf (stderr, "\n");
90 }
91
92 int 
93 main (argc, argv)
94      int argc;
95      char **argv;
96 {
97   int work_argc;                /* variable copy of argc */
98   char **work_argv;             /* variable copy of argv */
99   char *arg;                    /* an arg to program */
100   char a;                       /* an arg flag (after -) */
101
102 #if 0 /* do we need any of this?? */
103   {
104     static const int sig[] = {SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
105
106     for (a = 0; sig[a] != 0; a++)
107       if (signal (sig[a], SIG_IGN) != SIG_IGN)
108         signal (sig[a], got_sig);
109   }
110 #endif
111
112   myname = argv[0];
113   memset (flagseen, '\0', sizeof (flagseen));   /* aint seen nothing yet */
114 #ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
115 #define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
116 #endif
117   out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
118
119 #ifdef BFD_ASSEMBLER
120   bfd_init ();
121 #endif
122
123   symbol_begin ();
124   subsegs_begin ();
125   read_begin ();
126   input_scrub_begin ();
127   frag_init ();
128   /*
129    * Parse arguments, but we are only interested in flags.
130    * When we find a flag, we process it then make it's argv[] NULL.
131    * This helps any future argv[] scanners avoid what we processed.
132    * Since it is easy to do here we interpret the special arg "-"
133    * to mean "use stdin" and we set that argv[] pointing to "".
134    * After we have munged argv[], the only things left are source file
135    * name(s) and ""(s) denoting stdin. These file names are used
136    * (perhaps more than once) later.
137    */
138   /* FIXME-SOMEDAY this should use getopt. */
139   work_argc = argc - 1;         /* don't count argv[0] */
140   work_argv = argv + 1;         /* skip argv[0] */
141   for (; work_argc--; work_argv++)
142     {
143       arg = *work_argv;         /* work_argv points to this argument */
144
145       if (*arg != '-')          /* Filename. We need it later. */
146         continue;               /* Keep scanning args looking for flags. */
147       if (arg[1] == '-' && arg[2] == 0)
148         {
149           /* "--" as an argument means read STDIN */
150           /* on this scan, we don't want to think about filenames */
151           *work_argv = "";      /* Code that means 'use stdin'. */
152           continue;
153         }
154       /* This better be a switch. */
155       arg++;                    /*->letter. */
156
157       while ((a = *arg) != '\0')
158         {                       /* scan all the 1-char flags */
159           arg++;                /* arg->after letter. */
160           a &= 0x7F;            /* ascii only please */
161           flagseen[(unsigned char) a] = 1;
162           switch (a)
163             {
164             case 'a':
165               {
166                 int loop = 1;
167
168                 while (loop)
169                   {
170                     switch (*arg)
171                       {
172                       case 'l':
173                         listing |= LISTING_LISTING;
174                         arg++;
175                         break;
176                       case 's':
177                         listing |= LISTING_SYMBOLS;
178                         arg++;
179                         break;
180                       case 'h':
181                         listing |= LISTING_HLL;
182                         arg++;
183                         break;
184
185                       case 'n':
186                         listing |= LISTING_NOFORM;
187                         arg++;
188                         break;
189                       case 'd':
190                         listing |= LISTING_NODEBUG;
191                         arg++;
192                         break;
193                       default:
194                         if (!listing)
195                           listing = LISTING_DEFAULT;
196                         loop = 0;
197                         break;
198                       }
199                   }
200               }
201
202               break;
203
204
205             case 'f':
206               break;            /* -f means fast - no need for "app" preprocessor. */
207
208             case 'D':
209               /* DEBUG is implemented: it debugs different */
210               /* things to other people's assemblers. */
211               break;
212
213             case 'I':
214               {                 /* Include file directory */
215
216                 char *temp = NULL;
217                 if (*arg)
218                   {
219                     temp = strdup (arg);
220                     if (!temp)
221                       as_fatal ("virtual memory exhausted");
222                   }
223                 else if (work_argc)
224                   {
225                     *work_argv = NULL;
226                     work_argc--;
227                     temp = *++work_argv;
228                   }
229                 else
230                   as_warn ("%s: I expected a filename after -I", myname);
231                 add_include_dir (temp);
232                 arg = "";       /* Finished with this arg. */
233                 break;
234               }
235
236 #ifdef WARN_SIGNED_OVERFLOW_WORD
237               /* Don't warn about signed overflow.  */
238             case 'J':
239               break;
240 #endif
241
242 #ifndef WORKING_DOT_WORD
243             case 'K':
244               break;
245 #endif
246
247             case 'L':           /* -L means keep L* symbols */
248               break;
249
250             case 'o':
251               if (*arg)         /* Rest of argument is object file-name. */
252                 {
253                   out_file_name = strdup (arg);
254                   if (!out_file_name)
255                     as_fatal ("virtual memory exhausted");
256                 }
257               else if (work_argc)
258                 {               /* Want next arg for a file-name. */
259                   *work_argv = NULL;    /* This is not a file-name. */
260                   work_argc--;
261                   out_file_name = *++work_argv;
262                 }
263               else
264                 as_warn ("%s: I expected a filename after -o. \"%s\" assumed.",
265                          myname, out_file_name);
266               arg = "";         /* Finished with this arg. */
267               break;
268
269             case 'R':
270               /* -R means put data into text segment */
271 #ifdef NO_FOLD_DATA_AND_TEXT
272               as_warn ("-R option not supported on this target.");
273               flag_readonly_data_in_text = 0;
274               flagseen['R'] = 0;
275 #else
276               flag_readonly_data_in_text = 1;
277 #endif
278               break;
279
280             case 'v':
281 #ifdef  VMS
282               {
283                 extern char *compiler_version_string;
284                 compiler_version_string = arg;
285               }
286 #else /* not VMS */
287               if (*arg && strcmp (arg, "ersion"))
288                 {
289                   as_warn ("Unknown option `-v%s' ignored", arg);
290                   arg += strlen (arg);
291                   break;
292                 }
293
294               print_version_id ();
295 #endif /* not VMS */
296               while (*arg)
297                 arg++;          /* Skip the rest */
298               break;
299
300             case 'W':
301               /* -W means don't warn about things */
302               flag_suppress_warnings = 1;
303               break;
304
305             case 'w':
306             case 'X':
307               /* -X means treat warnings as errors */
308               break;
309             case 'Z':
310               /* -Z means attempt to generate object file even after errors. */
311               flag_always_generate_output = 1;
312               break;
313
314             default:
315               --arg;
316               if (md_parse_option (&arg, &work_argc, &work_argv) == 0)
317                 as_warn ("%s: I don't understand '%c' flag.", myname, a);
318               if (arg && *arg)
319                 arg++;
320               break;
321             }
322         }
323       /*
324        * We have just processed a "-..." arg, which was not a
325        * file-name. Smash it so the
326        * things that look for filenames won't ever see it.
327        *
328        * Whatever work_argv points to, it has already been used
329        * as part of a flag, so DON'T re-use it as a filename.
330        */
331       *work_argv = NULL;        /* NULL means 'not a file-name' */
332     }
333
334 #ifdef BFD_ASSEMBLER
335   output_file_create (out_file_name);
336   assert (stdoutput != 0);
337 #endif
338
339   /* Here with flags set up in flagseen[]. */
340   perform_an_assembly_pass (argc, argv);        /* Assemble it. */
341 #ifdef TC_I960
342   brtab_emit ();
343 #endif
344   if (seen_at_least_1_file ()
345       && !((had_warnings () && flag_always_generate_output)
346            || had_errors () > 0))
347     {
348       write_object_file ();     /* relax() addresses then emit object file */
349     }                           /* we also check in write_object_file() just before emit. */
350 #ifdef BFD_ASSEMBLER
351   else
352     {
353       output_file_close (out_file_name);
354       unlink (out_file_name);
355     }
356 #endif
357
358   input_scrub_end ();
359   md_end ();                    /* MACHINE.c */
360
361 #ifndef NO_LISTING
362   listing_print ("");
363 #endif
364
365   if ((had_warnings () && flagseen['Z'])
366       || had_errors () > 0)
367     return EXIT_FAILURE;
368   return EXIT_SUCCESS;
369 }
370 \f
371
372 /*                      perform_an_assembly_pass()
373  *
374  * Here to attempt 1 pass over each input file.
375  * We scan argv[*] looking for filenames or exactly "" which is
376  * shorthand for stdin. Any argv that is NULL is not a file-name.
377  * We set need_pass_2 TRUE if, after this, we still have unresolved
378  * expressions of the form (unknown value)+-(unknown value).
379  *
380  * Note the un*x semantics: there is only 1 logical input file, but it
381  * may be a catenation of many 'physical' input files.
382  */
383 static void 
384 perform_an_assembly_pass (argc, argv)
385      int argc;
386      char **argv;
387 {
388   int saw_a_file = 0;
389 #ifdef BFD_ASSEMBLER
390   flagword applicable;
391 #endif
392
393   need_pass_2 = 0;
394
395 #ifndef BFD_ASSEMBLER
396 #ifdef MANY_SEGMENTS
397   {
398     unsigned int i;
399     for (i = SEG_E0; i < SEG_UNKNOWN; i++)
400       segment_info[i].fix_root = 0;
401   }
402   /* Create the three fixed ones */
403   {
404     segT seg;
405
406     seg = subseg_new (".text", 0);
407     assert (seg == SEG_E0);
408     seg = subseg_new (".data", 0);
409     assert (seg == SEG_E1);
410     seg = subseg_new (".bss", 0);
411     assert (seg == SEG_E2);
412   }
413
414 #else /* not MANY_SEGMENTS */
415   text_fix_root = NULL;
416   data_fix_root = NULL;
417   bss_fix_root = NULL;
418 #endif /* not MANY_SEGMENTS */
419 #else /* BFD_ASSEMBLER */
420   /* Create the standard sections, and those the assembler uses
421      internally.  */
422   text_section = subseg_new (".text", 0);
423   data_section = subseg_new (".data", 0);
424   bss_section = subseg_new (".bss", 0);
425   /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
426      to have relocs, otherwise we don't find out in time. */
427   applicable = bfd_applicable_section_flags (stdoutput);
428   bfd_set_section_flags (stdoutput, text_section,
429                          applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
430                                        | SEC_CODE | SEC_READONLY));
431   /* @@ FIXME -- SEC_CODE seems to mean code only, rather than code possibly.*/
432   bfd_set_section_flags (stdoutput, data_section,
433                          applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC));
434   bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
435   subseg_new (BFD_ABS_SECTION_NAME, 0);
436   subseg_new (BFD_UND_SECTION_NAME, 0);
437   reg_section = subseg_new ("*GAS `reg' section*", 0);
438   expr_section = subseg_new ("*GAS `expr' section*", 0);
439
440 #endif /* BFD_ASSEMBLER */
441
442   subseg_set (text_section, 0);
443
444   /* This may add symbol table entries, which requires having an open BFD,
445      and sections already created, in BFD_ASSEMBLER mode.  */
446   md_begin ();
447
448   argv++;                       /* skip argv[0] */
449   argc--;                       /* skip argv[0] */
450   while (argc--)
451     {
452       if (*argv)
453         {                       /* Is it a file-name argument? */
454           saw_a_file++;
455           /* argv->"" if stdin desired, else->filename */
456           read_a_source_file (*argv);
457         }
458       argv++;                   /* completed that argv */
459     }
460   if (!saw_a_file)
461     read_a_source_file ("");
462 }                               /* perform_an_assembly_pass() */
463 \f
464 #if 0
465 /* This is not currently used.  */
466 static SIGTY
467 got_sig (sig)
468      int sig;
469 {
470   static here_before = 0;
471
472   as_bad ("Interrupted by signal %d", sig);
473   if (here_before++)
474     exit (EXIT_FAILURE);
475 #if 0 /* If SIGTY is void, this produces warnings.  */
476   return ((SIGTY) 0);
477 #endif
478 }
479 #endif
480
481 /* end of as.c */
This page took 0.051125 seconds and 4 git commands to generate.