as.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,105 行 · 第 1/2 页

C
1,105
字号
#endif	  exit (EXIT_SUCCESS);	case OPTION_DEFSYM:	  {	    char *s;	    valueT i;	    struct defsym_list *n;	    for (s = optarg; *s != '\0' && *s != '='; s++)	      ;	    if (*s == '\0')	      as_fatal (_("bad defsym; format is --defsym name=value"));	    *s++ = '\0';#ifdef BFD_ASSEMBLER	    i = bfd_scan_vma (s, (const char **) NULL, 0);#else	    i = strtol (s, (char **) NULL, 0);#endif	    n = (struct defsym_list *) xmalloc (sizeof *n);	    n->next = defsyms;	    n->name = optarg;	    n->value = i;	    defsyms = n;	  }	  break;	case OPTION_INSTTBL:	case 't':	  {	    /* optarg is the name of the file containing the instruction	       formats, opcodes, register names, etc.  */	    struct itbl_file_list *n;	    if (optarg == NULL)	      {		as_warn (_("No file name following -t option\n"));		break;	      }	    n = (struct itbl_file_list *) xmalloc (sizeof *n);	    n->next = itbl_files;	    n->name = optarg;	    itbl_files = n;	    /* Parse the file and add the new instructions to our internal	       table.  If multiple instruction tables are specified, the	       information from this table gets appended onto the existing	       internal table.  */	    itbl_files->name = xstrdup (optarg);	    if (itbl_parse (itbl_files->name) != 0)	      {		fprintf (stderr, _("Failed to read instruction table %s\n"),			 itbl_files->name);		exit (EXIT_SUCCESS);	      }	  }	  break;	case OPTION_DEPFILE:	  start_dependencies (optarg);	  break;	case OPTION_GSTABS:	  debug_type = DEBUG_STABS;	  break;	case OPTION_GDWARF2:	  debug_type = DEBUG_DWARF2;	  break;	case 'J':	  flag_signed_overflow_ok = 1;	  break;#ifndef WORKING_DOT_WORD	case 'K':	  flag_warn_displacement = 1;	  break;#endif	case 'L':	  flag_keep_locals = 1;	  break;	case OPTION_LISTING_LHS_WIDTH:	  listing_lhs_width = atoi (optarg);	  if (listing_lhs_width_second < listing_lhs_width)	    listing_lhs_width_second = listing_lhs_width;	  break;	case OPTION_LISTING_LHS_WIDTH2:	  {	    int tmp = atoi (optarg);	    if (tmp > listing_lhs_width)	      listing_lhs_width_second = tmp;	  }	  break;	case OPTION_LISTING_RHS_WIDTH:	  listing_rhs_width = atoi (optarg);	  break;	case OPTION_LISTING_CONT_LINES:	  listing_lhs_cont_lines = atoi (optarg);	  break;	case 'M':	  flag_mri = 1;#ifdef TC_M68K	  flag_m68k_mri = 1;#endif	  break;	case 'R':	  flag_readonly_data_in_text = 1;	  break;	case 'W':	  flag_no_warnings = 1;	  break;	case OPTION_WARN:	  flag_no_warnings = 0;	  flag_fatal_warnings = 0;	  break;	case OPTION_WARN_FATAL:	  flag_no_warnings = 0;	  flag_fatal_warnings = 1;	  break;	case 'Z':	  flag_always_generate_output = 1;	  break;	case 'a':	  if (optarg)	    {	      if (md_parse_option (optc, optarg) != 0)		break;	      while (*optarg)		{		  switch (*optarg)		    {		    case 'c':		      listing |= LISTING_NOCOND;		      break;		    case 'd':		      listing |= LISTING_NODEBUG;		      break;		    case 'h':		      listing |= LISTING_HLL;		      break;		    case 'l':		      listing |= LISTING_LISTING;		      break;		    case 'm':		      listing |= LISTING_MACEXP;		      break;		    case 'n':		      listing |= LISTING_NOFORM;		      break;		    case 's':		      listing |= LISTING_SYMBOLS;		      break;		    case '=':		      listing_filename = xstrdup (optarg + 1);		      optarg += strlen (listing_filename);		      break;		    default:		      as_fatal (_("invalid listing option `%c'"), *optarg);		      break;		    }		  optarg++;		}	    }	  if (!listing)	    listing = LISTING_DEFAULT;	  break;	case 'D':	  /* DEBUG is implemented: it debugs different	     things from other people's assemblers.  */	  flag_debug = 1;	  break;	case 'f':	  flag_no_comments = 1;	  break;	case 'I':	  {			/* Include file directory.  */	    char *temp = xstrdup (optarg);	    add_include_dir (temp);	    break;	  }	case 'o':	  out_file_name = xstrdup (optarg);	  break;	case 'w':	  break;	case 'X':	  /* -X means treat warnings as errors.  */	  break;	}    }  free (shortopts);  free (longopts);  *pargc = new_argc;  *pargv = new_argv;}static long start_time;intmain (argc, argv)     int argc;     char **argv;{  int macro_alternate;  int macro_strip_at;  int keep_it;  start_time = get_run_time ();#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)  setlocale (LC_MESSAGES, "");#endif  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);  if (debug_memory)    {#ifdef BFD_ASSEMBLER      extern long _bfd_chunksize;      _bfd_chunksize = 64;#endif      chunksize = 64;    }#ifdef HOST_SPECIAL_INIT  HOST_SPECIAL_INIT (argc, argv);#endif  myname = argv[0];  xmalloc_set_program_name (myname);  START_PROGRESS (myname, 0);#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"#endif  out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;  hex_init ();#ifdef BFD_ASSEMBLER  bfd_init ();  bfd_set_error_program_name (myname);#endif#ifdef USE_EMULATIONS  select_emulation_mode (argc, argv);#endif  PROGRESS (1);  symbol_begin ();  frag_init ();  subsegs_begin ();  parse_args (&argc, &argv);  read_begin ();  input_scrub_begin ();  expr_begin ();  if (flag_print_statistics)    xatexit (dump_statistics);  macro_alternate = 0;  macro_strip_at = 0;#ifdef TC_I960  macro_strip_at = flag_mri;#endif#ifdef TC_A29K  /* For compatibility with the AMD 29K family macro assembler     specification.  */  macro_alternate = 1;  macro_strip_at = 1;#endif  macro_init (macro_alternate, flag_mri, macro_strip_at, macro_expr);  PROGRESS (1);#ifdef BFD_ASSEMBLER  output_file_create (out_file_name);  assert (stdoutput != 0);#endif#ifdef tc_init_after_args  tc_init_after_args ();#endif  itbl_init ();  /* Now that we have fully initialized, and have created the output     file, define any symbols requested by --defsym command line     arguments.  */  while (defsyms != NULL)    {      symbolS *sym;      struct defsym_list *next;      sym = symbol_new (defsyms->name, absolute_section, defsyms->value,			&zero_address_frag);      symbol_table_insert (sym);      next = defsyms->next;      free (defsyms);      defsyms = next;    }  PROGRESS (1);  /* Assemble it.  */  perform_an_assembly_pass (argc, argv);  cond_finish_check (-1);#ifdef md_end  md_end ();#endif  /* If we've been collecting dwarf2 .debug_line info, either for     assembly debugging or on behalf of the compiler, emit it now.  */  dwarf2_finish ();  if (seen_at_least_1_file ()      && (flag_always_generate_output || had_errors () == 0))    keep_it = 1;  else    keep_it = 0;#if defined (BFD_ASSEMBLER) || !defined (BFD)  /* This used to be done at the start of write_object_file in     write.c, but that caused problems when doing listings when     keep_it was zero.  This could probably be moved above md_end, but     I didn't want to risk the change.  */  subsegs_finish ();#endif  if (keep_it)    write_object_file ();#ifndef NO_LISTING  listing_print (listing_filename);#endif#ifndef OBJ_VMS /* does its own file handling */#ifndef BFD_ASSEMBLER  if (keep_it)#endif    output_file_close (out_file_name);#endif  if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0)    as_bad (_("%d warnings, treating warnings as errors"), had_warnings ());  if (had_errors () > 0 && ! flag_always_generate_output)    keep_it = 0;  if (!keep_it)    unlink (out_file_name);  input_scrub_end ();  END_PROGRESS (myname);  /* Use xexit instead of return, because under VMS environments they     may not place the same interpretation on the value given.  */  if (had_errors () > 0)    xexit (EXIT_FAILURE);  /* Only generate dependency file if assembler was successful.  */  print_dependencies ();  xexit (EXIT_SUCCESS);}static voiddump_statistics (){#ifdef HAVE_SBRK  char *lim = (char *) sbrk (0);#endif  long run_time = get_run_time () - start_time;  fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"),	   myname, run_time / 1000000, run_time % 1000000);#ifdef HAVE_SBRK  fprintf (stderr, _("%s: data size %ld\n"),	   myname, (long) (lim - (char *) &environ));#endif  subsegs_print_statistics (stderr);  write_print_statistics (stderr);  symbol_print_statistics (stderr);  read_print_statistics (stderr);#ifdef tc_print_statistics  tc_print_statistics (stderr);#endif#ifdef obj_print_statistics  obj_print_statistics (stderr);#endif}/* Here to attempt 1 pass over each input file.   We scan argv[*] looking for filenames or exactly "" which is   shorthand for stdin. Any argv that is NULL is not a file-name.   We set need_pass_2 TRUE if, after this, we still have unresolved   expressions of the form (unknown value)+-(unknown value).   Note the un*x semantics: there is only 1 logical input file, but it   may be a catenation of many 'physical' input files.  */static voidperform_an_assembly_pass (argc, argv)     int argc;     char **argv;{  int saw_a_file = 0;#ifdef BFD_ASSEMBLER  flagword applicable;#endif  need_pass_2 = 0;#ifndef BFD_ASSEMBLER#ifdef MANY_SEGMENTS  {    unsigned int i;    for (i = SEG_E0; i < SEG_UNKNOWN; i++)      segment_info[i].fix_root = 0;  }  /* Create the three fixed ones.  */  {    segT seg;#ifdef TE_APOLLO    seg = subseg_new (".wtext", 0);#else    seg = subseg_new (".text", 0);#endif    assert (seg == SEG_E0);    seg = subseg_new (".data", 0);    assert (seg == SEG_E1);    seg = subseg_new (".bss", 0);    assert (seg == SEG_E2);#ifdef TE_APOLLO    create_target_segments ();#endif  }#else /* not MANY_SEGMENTS */  text_fix_root = NULL;  data_fix_root = NULL;  bss_fix_root = NULL;#endif /* not MANY_SEGMENTS */#else /* BFD_ASSEMBLER */  /* Create the standard sections, and those the assembler uses     internally.  */  text_section = subseg_new (TEXT_SECTION_NAME, 0);  data_section = subseg_new (DATA_SECTION_NAME, 0);  bss_section = subseg_new (BSS_SECTION_NAME, 0);  /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed     to have relocs, otherwise we don't find out in time.  */  applicable = bfd_applicable_section_flags (stdoutput);  bfd_set_section_flags (stdoutput, text_section,			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC				       | SEC_CODE | SEC_READONLY));  bfd_set_section_flags (stdoutput, data_section,			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC				       | SEC_DATA));  bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);  seg_info (bss_section)->bss = 1;  subseg_new (BFD_ABS_SECTION_NAME, 0);  subseg_new (BFD_UND_SECTION_NAME, 0);  reg_section = subseg_new ("*GAS `reg' section*", 0);  expr_section = subseg_new ("*GAS `expr' section*", 0);#endif /* BFD_ASSEMBLER */  subseg_set (text_section, 0);  /* This may add symbol table entries, which requires having an open BFD,     and sections already created, in BFD_ASSEMBLER mode.  */  md_begin ();#ifdef obj_begin  obj_begin ();#endif  /* Skip argv[0].  */  argv++;  argc--;  while (argc--)    {      if (*argv)	{			/* Is it a file-name argument?  */	  PROGRESS (1);	  saw_a_file++;	  /* argv->"" if stdin desired, else->filename  */	  read_a_source_file (*argv);	}      argv++;			/* completed that argv  */    }  if (!saw_a_file)    read_a_source_file ("");}/* The interface between the macro code and gas expression handling.  */static intmacro_expr (emsg, idx, in, val)     const char *emsg;     int idx;     sb *in;     int *val;{  char *hold;  expressionS ex;  sb_terminate (in);  hold = input_line_pointer;  input_line_pointer = in->ptr + idx;  expression (&ex);  idx = input_line_pointer - in->ptr;  input_line_pointer = hold;  if (ex.X_op != O_constant)    as_bad ("%s", emsg);  *val = (int) ex.X_add_number;  return idx;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?