📄 read.c
字号:
demand_empty_rest_of_line ();}voids_lcomm (needs_align) int needs_align;{ s_lcomm_internal (needs_align, 0);}voids_lcomm_bytes (needs_align) int needs_align;{ s_lcomm_internal (needs_align, 1);}voids_lsym (ignore) int ignore ATTRIBUTE_UNUSED;{ register char *name; register char c; register char *p; expressionS exp; register symbolS *symbolP; /* We permit ANY defined expression: BSD4.2 demands constants. */ name = input_line_pointer; c = get_symbol_end (); p = input_line_pointer; *p = c; SKIP_WHITESPACE (); if (*input_line_pointer != ',') { *p = 0; as_bad (_("Expected comma after name \"%s\""), name); *p = c; ignore_rest_of_line (); return; } input_line_pointer++; expression (&exp); if (exp.X_op != O_constant && exp.X_op != O_register) { as_bad (_("bad expression")); ignore_rest_of_line (); return; } *p = 0; symbolP = symbol_find_or_make (name); /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 && symbolP->sy_desc == 0) out of this test because coff doesn't have those fields, and I can't see when they'd ever be tripped. I don't think I understand why they were here so I may have introduced a bug. As recently as 1.37 didn't have this test anyway. xoxorich. */ if (S_GET_SEGMENT (symbolP) == undefined_section && S_GET_VALUE (symbolP) == 0) { /* The name might be an undefined .global symbol; be sure to keep the "external" bit. */ S_SET_SEGMENT (symbolP, (exp.X_op == O_constant ? absolute_section : reg_section)); S_SET_VALUE (symbolP, (valueT) exp.X_add_number); } else { as_bad (_("Symbol %s already defined"), name); } *p = c; demand_empty_rest_of_line ();}/* Read a line into an sb. */static intget_line_sb (line) sb *line;{ char quote1, quote2, inquote; if (input_line_pointer[-1] == '\n') bump_line_counters (); if (input_line_pointer >= buffer_limit) { buffer_limit = input_scrub_next_buffer (&input_line_pointer); if (buffer_limit == 0) return 0; } /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this code needs to be changed. */ if (!flag_m68k_mri) quote1 = '"'; else quote1 = '\0'; quote2 = '\0'; if (flag_m68k_mri) quote2 = '\'';#ifdef LEX_IS_STRINGQUOTE quote2 = '\'';#endif inquote = '\0'; while (!is_end_of_line[(unsigned char) *input_line_pointer] || (inquote != '\0' && *input_line_pointer != '\n')) { if (inquote == *input_line_pointer) inquote = '\0'; else if (inquote == '\0') { if (*input_line_pointer == quote1) inquote = quote1; else if (*input_line_pointer == quote2) inquote = quote2; } sb_add_char (line, *input_line_pointer++); } while (input_line_pointer < buffer_limit && is_end_of_line[(unsigned char) *input_line_pointer]) { if (input_line_pointer[-1] == '\n') bump_line_counters (); ++input_line_pointer; } return 1;}/* Define a macro. This is an interface to macro.c, which is shared between gas and gasp. */voids_macro (ignore) int ignore ATTRIBUTE_UNUSED;{ char *file; unsigned int line; sb s; sb label; const char *err; const char *name; as_where (&file, &line); sb_new (&s); while (!is_end_of_line[(unsigned char) *input_line_pointer]) sb_add_char (&s, *input_line_pointer++); sb_new (&label); if (line_label != NULL) sb_add_string (&label, S_GET_NAME (line_label)); err = define_macro (0, &s, &label, get_line_sb, &name); if (err != NULL) as_bad_where (file, line, "%s", err); else { if (line_label != NULL) { S_SET_SEGMENT (line_label, undefined_section); S_SET_VALUE (line_label, 0); symbol_set_frag (line_label, &zero_address_frag); } if (((NO_PSEUDO_DOT || flag_m68k_mri) && hash_find (po_hash, name) != NULL) || (!flag_m68k_mri && *name == '.' && hash_find (po_hash, name + 1) != NULL)) as_warn (_("attempt to redefine pseudo-op `%s' ignored"), name); } sb_kill (&s);}/* Handle the .mexit pseudo-op, which immediately exits a macro expansion. */voids_mexit (ignore) int ignore ATTRIBUTE_UNUSED;{ cond_exit_macro (macro_nest); buffer_limit = input_scrub_next_buffer (&input_line_pointer);}/* Switch in and out of MRI mode. */voids_mri (ignore) int ignore ATTRIBUTE_UNUSED;{ int on, old_flag; on = get_absolute_expression (); old_flag = flag_mri; if (on != 0) { flag_mri = 1;#ifdef TC_M68K flag_m68k_mri = 1;#endif macro_mri_mode (1); } else { flag_mri = 0;#ifdef TC_M68K flag_m68k_mri = 0;#endif macro_mri_mode (0); } /* Operator precedence changes in m68k MRI mode, so we need to update the operator rankings. */ expr_set_precedence ();#ifdef MRI_MODE_CHANGE if (on != old_flag) MRI_MODE_CHANGE (on);#endif demand_empty_rest_of_line ();}/* Handle changing the location counter. */static voiddo_org (segment, exp, fill) segT segment; expressionS *exp; int fill;{ if (segment != now_seg && segment != absolute_section) as_bad (_("invalid segment \"%s\"; segment \"%s\" assumed"), segment_name (segment), segment_name (now_seg)); if (now_seg == absolute_section) { if (fill != 0) as_warn (_("ignoring fill value in absolute section")); if (exp->X_op != O_constant) { as_bad (_("only constant offsets supported in absolute section")); exp->X_add_number = 0; } abs_section_offset = exp->X_add_number; } else { char *p; symbolS *sym = exp->X_add_symbol; offsetT off = exp->X_add_number * OCTETS_PER_BYTE; if (exp->X_op != O_constant && exp->X_op != O_symbol) { /* Handle complex expressions. */ sym = make_expr_symbol (exp); off = 0; } p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0); *p = fill; }}voids_org (ignore) int ignore ATTRIBUTE_UNUSED;{ register segT segment; expressionS exp; register long temp_fill;#ifdef md_flush_pending_output md_flush_pending_output ();#endif /* The m68k MRI assembler has a different meaning for .org. It means to create an absolute section at a given address. We can't support that--use a linker script instead. */ if (flag_m68k_mri) { as_bad (_("MRI style ORG pseudo-op not supported")); ignore_rest_of_line (); return; } /* Don't believe the documentation of BSD 4.2 AS. There is no such thing as a sub-segment-relative origin. Any absolute origin is given a warning, then assumed to be segment-relative. Any segmented origin expression ("foo+42") had better be in the right segment or the .org is ignored. BSD 4.2 AS warns if you try to .org backwards. We cannot because we never know sub-segment sizes when we are reading code. BSD will crash trying to emit negative numbers of filler bytes in certain .orgs. We don't crash, but see as-write for that code. Don't make frag if need_pass_2==1. */ segment = get_known_segmented_expression (&exp); if (*input_line_pointer == ',') { input_line_pointer++; temp_fill = get_absolute_expression (); } else temp_fill = 0; if (!need_pass_2) do_org (segment, &exp, temp_fill); demand_empty_rest_of_line ();}/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be called by the obj-format routine which handles section changing when in MRI mode. It will create a new section, and return it. It will set *TYPE to the section type: one of 'C' (code), 'D' (data), 'M' (mixed), or 'R' (romable). If BFD_ASSEMBLER is defined, the flags will be set in the section. */voids_mri_sect (type) char *type ATTRIBUTE_UNUSED;{#ifdef TC_M68K char *name; char c; segT seg; 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'; } name = xstrdup (name); *input_line_pointer = c; seg = subseg_new (name, 0); if (*input_line_pointer == ',') { int align; ++input_line_pointer; align = get_absolute_expression (); record_alignment (seg, align); } *type = 'C'; if (*input_line_pointer == ',') { c = *++input_line_pointer; c = toupper ((unsigned char) c); if (c == 'C' || c == 'D' || c == 'M' || c == 'R') *type = c; else as_bad (_("unrecognized section type")); ++input_line_pointer;#ifdef BFD_ASSEMBLER { flagword flags; flags = SEC_NO_FLAGS; if (*type == 'C') flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE; else if (*type == 'D' || *type == 'M') flags = SEC_ALLOC | SEC_LOAD | SEC_DATA; else if (*type == 'R') flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM; if (flags != SEC_NO_FLAGS) { if (!bfd_set_section_flags (stdoutput, seg, flags)) as_warn (_("error setting flags for \"%s\": %s"), bfd_section_name (stdoutput, seg), bfd_errmsg (bfd_get_error ())); } }#endif } /* Ignore the HP type. */ if (*input_line_pointer == ',') input_line_pointer += 2; demand_empty_rest_of_line ();#else /* ! TC_M68K */#ifdef TC_I960 char *name; char c; segT seg; SKIP_WHITESPACE (); name = input_line_pointer; c = get_symbol_end (); name = xstrdup (name); *input_line_pointer = c; seg = subseg_new (name, 0); if (*input_line_pointer != ',') *type = 'C'; else { char *sectype; ++input_line_pointer; SKIP_WHITESPACE (); sectype = input_line_pointer; c = get_symbol_end (); if (*sectype == '\0') *type = 'C'; else if (strcasecmp (sectype, "text") == 0) *type = 'C'; else if (strcasecmp (sectype, "data") == 0) *type = 'D'; else if (strcasecmp (sectype, "romdata") == 0) *type = 'R'; else as_warn (_("unrecognized section type `%s'"), sectype); *input_line_pointer = c; } if (*input_line_pointer == ',') { char *seccmd; ++input_line_pointer; SKIP_WHITESPACE (); seccmd = input_line_pointer; c = get_symbol_end (); if (strcasecmp (seccmd, "absolute") == 0) { as_bad (_("absolute sections are not supported")); *input_line_pointer = c; ignore_rest_of_line (); return; } else if (strcasecmp (seccmd, "align") == 0) { int align; *input_line_pointer = c; align = get_absolute_expression (); record_alignment (seg, align); } else { as_warn (_("unrecognized section command `%s'"), seccmd); *input_line_pointer = c; } } demand_empty_rest_of_line ();#else /* ! TC_I960 */ /* The MRI assembler seems to use different forms of .sect for different targets. */ as_bad ("MRI mode not supported for this target"); ignore_rest_of_line ();#endif /* ! TC_I960 */#endif /* ! TC_M68K */}/* Handle the .print pseudo-op. */voids_print (ignore) int ignore ATTRIBUTE_UNUSED;{ char *s; int len; s = demand_copy_C_string (&len); printf ("%s\n", s); demand_empty_rest_of_line ();}/* Handle the .purgem pseudo-op. */voids_purgem (ignore) int ignore ATTRIBUTE_UNUSED;{ if (is_it_end_of_statement
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -