📄 read.c
字号:
ignore_rest_of_line (); }#ifdef md_after_pass_hook md_after_pass_hook ();#endif if (old_buffer) { free (buffer); bump_line_counters (); if (old_input != 0) { buffer = old_buffer; input_line_pointer = old_input; buffer_limit = old_limit; old_buffer = 0; goto contin; } } } quit:#ifdef md_cleanup md_cleanup ();#endif /* Close the input file. */ input_scrub_close ();#ifdef WARN_COMMENTS { if (warn_comment && found_comment) as_warn_where (found_comment_file, found_comment, "first comment found here"); }#endif}/* For most MRI pseudo-ops, the line actually ends at the first nonquoted space. This function looks for that point, stuffs a null in, and sets *STOPCP to the character that used to be there, and returns the location. Until I hear otherwise, I am going to assume that this is only true for the m68k MRI assembler. */char *mri_comment_field (stopcp) char *stopcp;{ char *s;#ifdef TC_M68K int inquote = 0; know (flag_m68k_mri); for (s = input_line_pointer; ((!is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t') || inquote); s++) { if (*s == '\'') inquote = !inquote; }#else for (s = input_line_pointer; !is_end_of_line[(unsigned char) *s]; s++) ;#endif *stopcp = *s; *s = '\0'; return s;}/* Skip to the end of an MRI comment field. */voidmri_comment_end (stop, stopc) char *stop; int stopc;{ know (flag_mri); input_line_pointer = stop; *stop = stopc; while (!is_end_of_line[(unsigned char) *input_line_pointer]) ++input_line_pointer;}voids_abort (ignore) int ignore ATTRIBUTE_UNUSED;{ as_fatal (_(".abort detected. Abandoning ship."));}/* Guts of .align directive. N is the power of two to which to align. FILL may be NULL, or it may point to the bytes of the fill pattern. LEN is the length of whatever FILL points to, if anything. MAX is the maximum number of characters to skip when doing the alignment, or 0 if there is no maximum. */static voiddo_align (n, fill, len, max) int n; char *fill; int len; int max;{#ifdef md_do_align md_do_align (n, fill, len, max, just_record_alignment);#endif /* Only make a frag if we HAVE to... */ if (n != 0 && !need_pass_2) { if (fill == NULL) { if (subseg_text_p (now_seg)) frag_align_code (n, max); else frag_align (n, 0, max); } else if (len <= 1) frag_align (n, *fill, max); else frag_align_pattern (n, fill, len, max); }#ifdef md_do_align just_record_alignment:#endif record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);}/* Handle the .align pseudo-op. A positive ARG is a default alignment (in bytes). A negative ARG is the negative of the length of the fill pattern. BYTES_P is non-zero if the alignment value should be interpreted as the byte boundary, rather than the power of 2. */static voids_align (arg, bytes_p) int arg; int bytes_p;{ register unsigned int align; char *stop = NULL; char stopc; offsetT fill = 0; int max; int fill_p; if (flag_mri) stop = mri_comment_field (&stopc); if (is_end_of_line[(unsigned char) *input_line_pointer]) { if (arg < 0) align = 0; else align = arg; /* Default value from pseudo-op table. */ } else { align = get_absolute_expression (); SKIP_WHITESPACE (); } if (bytes_p) { /* Convert to a power of 2. */ if (align != 0) { unsigned int i; for (i = 0; (align & 1) == 0; align >>= 1, ++i) ; if (align != 1) as_bad (_("Alignment not a power of 2")); align = i; } } if (align > 15) { align = 15; as_bad (_("Alignment too large: %u assumed"), align); } if (*input_line_pointer != ',') { fill_p = 0; max = 0; } else { ++input_line_pointer; if (*input_line_pointer == ',') fill_p = 0; else { fill = get_absolute_expression (); SKIP_WHITESPACE (); fill_p = 1; } if (*input_line_pointer != ',') max = 0; else { ++input_line_pointer; max = get_absolute_expression (); } } if (!fill_p) { if (arg < 0) as_warn (_("expected fill pattern missing")); do_align (align, (char *) NULL, 0, max); } else { int fill_len; if (arg >= 0) fill_len = 1; else fill_len = -arg; if (fill_len <= 1) { char fill_char; fill_char = fill; do_align (align, &fill_char, fill_len, max); } else { char ab[16]; if ((size_t) fill_len > sizeof ab) abort (); md_number_to_chars (ab, fill, fill_len); do_align (align, ab, fill_len, max); } } demand_empty_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc);}/* Handle the .align pseudo-op on machines where ".align 4" means align to a 4 byte boundary. */voids_align_bytes (arg) int arg;{ s_align (arg, 1);}/* Handle the .align pseudo-op on machines where ".align 4" means align to a 2**4 boundary. */voids_align_ptwo (arg) int arg;{ s_align (arg, 0);}voids_comm (ignore) int ignore ATTRIBUTE_UNUSED;{ register char *name; register char c; register char *p; offsetT temp; register symbolS *symbolP; char *stop = NULL; char stopc; if (flag_mri) stop = mri_comment_field (&stopc); name = input_line_pointer; c = get_symbol_end (); /* Just after name is now '\0'. */ p = input_line_pointer; *p = c; SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad (_("Expected comma after symbol-name: rest of line ignored.")); ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); return; } input_line_pointer++; /* skip ',' */ if ((temp = get_absolute_expression ()) < 0) { as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp); ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); return; } *p = 0; symbolP = symbol_find_or_make (name); *p = c; if (S_IS_DEFINED (symbolP) && !S_IS_COMMON (symbolP)) { as_bad (_("Ignoring attempt to re-define symbol `%s'."), S_GET_NAME (symbolP)); ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); return; } if (S_GET_VALUE (symbolP)) { if (S_GET_VALUE (symbolP) != (valueT) temp) as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) temp); } else { S_SET_VALUE (symbolP, (valueT) temp); S_SET_EXTERNAL (symbolP); }#ifdef OBJ_VMS { extern int flag_one; if (!temp || !flag_one) S_GET_OTHER(symbolP) = const_flag; }#endif /* not OBJ_VMS */ know (symbolP->sy_frag == &zero_address_frag); demand_empty_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc);} /* s_comm() *//* The MRI COMMON pseudo-op. We handle this by creating a common symbol with the appropriate name. We make s_space do the right thing by increasing the size. */voids_mri_common (small) int small ATTRIBUTE_UNUSED;{ char *name; char c; char *alc = NULL; symbolS *sym; offsetT align; char *stop = NULL; char stopc; if (!flag_mri) { s_comm (0); return; } stop = mri_comment_field (&stopc); SKIP_WHITESPACE (); name = input_line_pointer; if (!isdigit ((unsigned char) *name)) c = get_symbol_end (); else { do { ++input_line_pointer; } while (isdigit ((unsigned char) *input_line_pointer)); c = *input_line_pointer; *input_line_pointer = '\0'; if (line_label != NULL) { alc = (char *) xmalloc (strlen (S_GET_NAME (line_label)) + (input_line_pointer - name) + 1); sprintf (alc, "%s%s", name, S_GET_NAME (line_label)); name = alc; } } sym = symbol_find_or_make (name); *input_line_pointer = c; if (alc != NULL) free (alc); if (*input_line_pointer != ',') align = 0; else { ++input_line_pointer; align = get_absolute_expression (); } if (S_IS_DEFINED (sym) && !S_IS_COMMON (sym)) { as_bad (_("attempt to re-define symbol `%s'"), S_GET_NAME (sym)); ignore_rest_of_line (); mri_comment_end (stop, stopc); return; } S_SET_EXTERNAL (sym); mri_common_symbol = sym;#ifdef S_SET_ALIGN if (align != 0) S_SET_ALIGN (sym, align);#endif if (line_label != NULL) { expressionS exp; exp.X_op = O_symbol; exp.X_add_symbol = sym; exp.X_add_number = 0; symbol_set_value_expression (line_label, &exp); symbol_set_frag (line_label, &zero_address_frag); S_SET_SEGMENT (line_label, expr_section); } /* FIXME: We just ignore the small argument, which distinguishes COMMON and COMMON.S. I don't know what we can do about it. */ /* Ignore the type and hptype. */ if (*input_line_pointer == ',') input_line_pointer += 2; if (*input_line_pointer == ',') input_line_pointer += 2; demand_empty_rest_of_line (); mri_comment_end (stop, stopc);}voids_data (ignore) int ignore ATTRIBUTE_UNUSED;{ segT section; register int temp; temp = get_absolute_expression (); if (flag_readonly_data_in_text) { section = text_section; temp += 1000; } else section = data_section; subseg_set (section, (subsegT) temp);#ifdef OBJ_VMS const_flag = 0;#endif demand_empty_rest_of_line ();}/* Handle the .appfile pseudo-op. This is automatically generated by do_scrub_chars when a preprocessor # line comment is seen with a file name. This default definition may be overridden by the object or CPU specific pseudo-ops. This function is also the default definition for .file; the APPFILE argument is 1 for .appfile, 0 for .file. */voids_app_file (appfile) int appfile;{ register char *s; int length; /* Some assemblers tolerate immediately following '"'. */ if ((s = demand_copy_string (&length)) != 0) { /* If this is a fake .appfile, a fake newline was inserted into the buffer. Passing -2 to new_logical_line tells it to account for it. */ int may_omit = (!new_logical_line (s, appfile ? -2 : -1) && appfile); /* In MRI mode, the preprocessor may have inserted an extraneous backquote. */ if (flag_m68k_mri && *input_line_pointer == '\'' && is_end_of_line[(unsigned char) input_line_pointer[1]]) ++input_line_pointer; demand_empty_rest_of_line (); if (!may_omit) {#ifdef LISTING if (listing) listing_source_file (s);#endif register_dependency (s);#ifdef obj_app_file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -