as.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* as.c - GAS main program.
  2. Copyright (C) 1987 Free Software Foundation, Inc.
  3. This file is part of GAS, the GNU Assembler.
  4. GAS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 1, or (at your option)
  7. any later version.
  8. GAS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GAS; see the file COPYING. If not, write to
  14. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  15. /*
  16. * Main program for AS; a 32-bit assembler of GNU.
  17. * Understands command arguments.
  18. * Has a few routines that don't fit in other modules because they
  19. * are shared.
  20. *
  21. *
  22. * bugs
  23. *
  24. * : initialisers
  25. * Since no-one else says they will support them in future: I
  26. * don't support them now.
  27. *
  28. */
  29. #define COMMON
  30. #include "as.h"
  31. #include "struc-symbol.h"
  32. #include "write.h"
  33. /* Warning! This may have some slightly strange side effects
  34. if you try to compile two or more assemblers in the same
  35. directory!
  36. */
  37. static char * gdb_symbol_file_name;
  38. char *myname; /* argv[0] */
  39. extern char version_string[];
  40. main(argc,argv)
  41. int argc;
  42. char **argv;
  43. {
  44. int work_argc; /* variable copy of argc */
  45. char **work_argv; /* variable copy of argv */
  46. char *arg; /* an arg to program */
  47. char a; /* an arg flag (after -) */
  48. char *stralloc(); /* Make a (safe) copy of a string. */
  49. long int gdb_begin();
  50. void symbol_begin();
  51. void read_begin();
  52. void write_object_file();
  53. myname=argv[0];
  54. bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  55. out_file_name = "a.out"; /* default .o file */
  56. symbol_begin(); /* symbols.c */
  57. subsegs_begin(); /* subsegs.c */
  58. read_begin(); /* read.c */
  59. md_begin(); /* MACHINE.c */
  60. input_scrub_begin(); /* input_scrub.c */
  61. gdb_symbol_file_name = 0;
  62. /*
  63. * Parse arguments, but we are only interested in flags.
  64. * When we find a flag, we process it then make it's argv[] NULL.
  65. * This helps any future argv[] scanners avoid what we processed.
  66. * Since it is easy to do here we interpret the special arg "-"
  67. * to mean "use stdin" and we set that argv[] pointing to "".
  68. * After we have munged argv[], the only things left are source file
  69. * name(s) and ""(s) denoting stdin. These file names are used
  70. * (perhaps more than once) later.
  71. */
  72. work_argc = argc-1; /* don't count argv[0] */
  73. work_argv = argv+1; /* skip argv[0] */
  74. for (;work_argc--;work_argv++) {
  75. arg = * work_argv; /* work_argv points to this argument */
  76. if (*arg!='-') /* Filename. We need it later. */
  77. continue; /* Keep scanning args looking for flags. */
  78. if (arg[1] == '-' && arg[2] == 0) {
  79. /* "--" as an argument means read STDIN */
  80. /* on this scan, we don't want to think about filenames */
  81. * work_argv = ""; /* Code that means 'use stdin'. */
  82. continue;
  83. }
  84. /* This better be a switch. */
  85. arg ++; /* -> letter. */
  86. while (a = * arg) {/* scan all the 1-char flags */
  87. arg ++; /* arg -> after letter. */
  88. a &= 0x7F; /* ascii only please */
  89. if (flagseen[a])
  90. as_warn("%s: Flag option -%c has already been seen!",myname,a);
  91. flagseen[a] = TRUE;
  92. switch (a) {
  93. case 'f':
  94. break; /* -f means fast - no need for "app" preprocessor. */
  95. case 'D':
  96. /* DEBUG is implemented: it debugs different */
  97. /* things to other people's assemblers. */
  98. break;
  99. case 'G': /* GNU AS switch: include gdbsyms. */
  100. if (*arg) /* Rest of argument is file-name. */
  101. gdb_symbol_file_name = stralloc (arg);
  102. else if (work_argc) { /* Next argument is file-name. */
  103. work_argc --;
  104. * work_argv = NULL; /* Not a source file-name. */
  105. gdb_symbol_file_name = * ++ work_argv;
  106. } else
  107. as_warn( "%s: I expected a filename after -G",myname);
  108. arg = ""; /* Finished with this arg. */
  109. break;
  110. #ifndef WORKING_DOT_WORD
  111. case 'k':
  112. break;
  113. #endif
  114. case 'L': /* -L means keep L* symbols */
  115. break;
  116. case 'o':
  117. if (*arg) /* Rest of argument is object file-name. */
  118. out_file_name = stralloc (arg);
  119. else if (work_argc) { /* Want next arg for a file-name. */
  120. * work_argv = NULL; /* This is not a file-name. */
  121. work_argc--;
  122. out_file_name = * ++ work_argv;
  123. } else
  124. as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  125. arg = ""; /* Finished with this arg. */
  126. break;
  127. case 'R':
  128. /* -R means put data into text segment */
  129. break;
  130. case 'v':
  131. #ifdef VMS
  132. {
  133. extern char *compiler_version_string;
  134. compiler_version_string = arg;
  135. }
  136. #else /* not VMS */
  137. fprintf(stderr,version_string);
  138. if(*arg && strcmp(arg,"ersion"))
  139. as_warn("Unknown -v option ignored");
  140. #endif
  141. while(*arg) arg++; /* Skip the rest */
  142. break;
  143. case 'W':
  144. /* -W means don't warn about things */
  145. break;
  146. default:
  147. --arg;
  148. if(md_parse_option(&arg,&work_argc,&work_argv)==0)
  149. as_warn("%s: I don't understand '%c' flag!",myname,a);
  150. if(arg && *arg)
  151. arg++;
  152. break;
  153. }
  154. }
  155. /*
  156. * We have just processed a "-..." arg, which was not a
  157. * file-name. Smash it so the
  158. * things that look for filenames won't ever see it.
  159. *
  160. * Whatever work_argv points to, it has already been used
  161. * as part of a flag, so DON'T re-use it as a filename.
  162. */
  163. *work_argv = NULL; /* NULL means 'not a file-name' */
  164. }
  165. if (gdb_begin(gdb_symbol_file_name) == 0)
  166. flagseen ['G'] = 0; /* Don't do any gdbsym stuff. */
  167. /* Here with flags set up in flagseen[]. */
  168. perform_an_assembly_pass(argc,argv); /* Assemble it. */
  169. if (seen_at_least_1_file())
  170. write_object_file();/* relax() addresses then emit object file */
  171. input_scrub_end();
  172. md_end(); /* MACHINE.c */
  173. #ifndef VMS
  174. exit(0); /* WIN */
  175. #else /* VMS */
  176. exit(1); /* WIN */
  177. #endif /* VMS */
  178. }
  179. /* perform_an_assembly_pass()
  180. *
  181. * Here to attempt 1 pass over each input file.
  182. * We scan argv[*] looking for filenames or exactly "" which is
  183. * shorthand for stdin. Any argv that is NULL is not a file-name.
  184. * We set need_pass_2 TRUE if, after this, we still have unresolved
  185. * expressions of the form (unknown value)+-(unknown value).
  186. *
  187. * Note the un*x semantics: there is only 1 logical input file, but it
  188. * may be a catenation of many 'physical' input files.
  189. */
  190. perform_an_assembly_pass (argc, argv)
  191. int argc;
  192. char ** argv;
  193. {
  194. char * buffer; /* Where each bufferful of lines will start. */
  195. void read_a_source_file();
  196. int saw_a_file = 0;
  197. text_fix_root = NULL;
  198. data_fix_root = NULL;
  199. need_pass_2 = FALSE;
  200. argv++; /* skip argv[0] */
  201. argc--; /* skip argv[0] */
  202. while (argc--) {
  203. if (*argv) { /* Is it a file-name argument? */
  204. /* argv -> "" if stdin desired, else -> filename */
  205. if (buffer = input_scrub_new_file (*argv) ) {
  206. saw_a_file++;
  207. read_a_source_file(buffer);
  208. }
  209. }
  210. argv++; /* completed that argv */
  211. }
  212. if(!saw_a_file)
  213. if(buffer = input_scrub_new_file("") )
  214. read_a_source_file(buffer);
  215. }
  216. /*
  217. * stralloc()
  218. *
  219. * Allocate memory for a new copy of a string. Copy the string.
  220. * Return the address of the new string. Die if there is any error.
  221. */
  222. char *
  223. stralloc (str)
  224. char * str;
  225. {
  226. register char * retval;
  227. register long int len;
  228. len = strlen (str) + 1;
  229. retval = xmalloc (len);
  230. (void)strcpy (retval, str);
  231. return (retval);
  232. }
  233. lose()
  234. {
  235. as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  236. }
  237. /* end: as.c */