📄 read.c
字号:
obj_app_file (s);#endif } }}/* Handle the .appline pseudo-op. This is automatically generated by do_scrub_chars when a preprocessor # line comment is seen. This default definition may be overridden by the object or CPU specific pseudo-ops. */voids_app_line (ignore) int ignore ATTRIBUTE_UNUSED;{ int l; /* The given number is that of the next line. */ l = get_absolute_expression () - 1; if (l < 0) /* Some of the back ends can't deal with non-positive line numbers. Besides, it's silly. */ as_warn (_("Line numbers must be positive; line number %d rejected."), l + 1); else { new_logical_line ((char *) NULL, l);#ifdef LISTING if (listing) listing_source_line (l);#endif } demand_empty_rest_of_line ();}/* Handle the .end pseudo-op. Actually, the real work is done in read_a_source_file. */voids_end (ignore) int ignore ATTRIBUTE_UNUSED;{ if (flag_mri) { /* The MRI assembler permits the start symbol to follow .end, but we don't support that. */ SKIP_WHITESPACE (); if (!is_end_of_line[(unsigned char) *input_line_pointer] && *input_line_pointer != '*' && *input_line_pointer != '!') as_warn (_("start address not supported")); }}/* Handle the .err pseudo-op. */voids_err (ignore) int ignore ATTRIBUTE_UNUSED;{ as_bad (_(".err encountered")); demand_empty_rest_of_line ();}/* Handle the MRI fail pseudo-op. */voids_fail (ignore) int ignore ATTRIBUTE_UNUSED;{ offsetT temp; char *stop = NULL; char stopc; if (flag_mri) stop = mri_comment_field (&stopc); temp = get_absolute_expression (); if (temp >= 500) as_warn (_(".fail %ld encountered"), (long) temp); else as_bad (_(".fail %ld encountered"), (long) temp); demand_empty_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc);}voids_fill (ignore) int ignore ATTRIBUTE_UNUSED;{ expressionS rep_exp; long size = 1; register long fill = 0; char *p;#ifdef md_flush_pending_output md_flush_pending_output ();#endif get_known_segmented_expression (&rep_exp); if (*input_line_pointer == ',') { input_line_pointer++; size = get_absolute_expression (); if (*input_line_pointer == ',') { input_line_pointer++; fill = get_absolute_expression (); } } /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */#define BSD_FILL_SIZE_CROCK_8 (8) if (size > BSD_FILL_SIZE_CROCK_8) { as_warn (_(".fill size clamped to %d."), BSD_FILL_SIZE_CROCK_8); size = BSD_FILL_SIZE_CROCK_8; } if (size < 0) { as_warn (_("Size negative: .fill ignored.")); size = 0; } else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0) { if (rep_exp.X_add_number < 0) as_warn (_("Repeat < 0, .fill ignored")); size = 0; } if (size && !need_pass_2) { if (rep_exp.X_op == O_constant) { p = frag_var (rs_fill, (int) size, (int) size, (relax_substateT) 0, (symbolS *) 0, (offsetT) rep_exp.X_add_number, (char *) 0); } else { /* We don't have a constant repeat count, so we can't use rs_fill. We can get the same results out of rs_space, but its argument is in bytes, so we must multiply the repeat count by size. */ symbolS *rep_sym; rep_sym = make_expr_symbol (&rep_exp); if (size != 1) { expressionS size_exp; size_exp.X_op = O_constant; size_exp.X_add_number = size; rep_exp.X_op = O_multiply; rep_exp.X_add_symbol = rep_sym; rep_exp.X_op_symbol = make_expr_symbol (&size_exp); rep_exp.X_add_number = 0; rep_sym = make_expr_symbol (&rep_exp); } p = frag_var (rs_space, (int) size, (int) size, (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0); } memset (p, 0, (unsigned int) size); /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS. The following bizzare behaviour is to be compatible with above. I guess they tried to take up to 8 bytes from a 4-byte expression and they forgot to sign extend. Un*x Sux. */#define BSD_FILL_SIZE_CROCK_4 (4) md_number_to_chars (p, (valueT) fill, (size > BSD_FILL_SIZE_CROCK_4 ? BSD_FILL_SIZE_CROCK_4 : (int) size)); /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes) but emits no error message because it seems a legal thing to do. It is a degenerate case of .fill but could be emitted by a compiler. */ } demand_empty_rest_of_line ();}voids_globl (ignore) int ignore ATTRIBUTE_UNUSED;{ char *name; int c; symbolS *symbolP; char *stop = NULL; char stopc; if (flag_mri) stop = mri_comment_field (&stopc); do { name = input_line_pointer; c = get_symbol_end (); symbolP = symbol_find_or_make (name); S_SET_EXTERNAL (symbolP); *input_line_pointer = c; SKIP_WHITESPACE (); c = *input_line_pointer; if (c == ',') { input_line_pointer++; SKIP_WHITESPACE (); if (*input_line_pointer == '\n') c = '\n'; } } while (c == ','); demand_empty_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc);}/* Handle the MRI IRP and IRPC pseudo-ops. */voids_irp (irpc) int irpc;{ char *file; unsigned int line; sb s; const char *err; sb out; 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 (&out); err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0'); if (err != NULL) as_bad_where (file, line, "%s", err); sb_kill (&s); input_scrub_include_sb (&out, input_line_pointer, 1); sb_kill (&out); buffer_limit = input_scrub_next_buffer (&input_line_pointer);}/* Handle the .linkonce pseudo-op. This tells the assembler to mark the section to only be linked once. However, this is not supported by most object file formats. This takes an optional argument, which is what to do about duplicates. */voids_linkonce (ignore) int ignore ATTRIBUTE_UNUSED;{ enum linkonce_type type; SKIP_WHITESPACE (); type = LINKONCE_DISCARD; if (!is_end_of_line[(unsigned char) *input_line_pointer]) { char *s; char c; s = input_line_pointer; c = get_symbol_end (); if (strcasecmp (s, "discard") == 0) type = LINKONCE_DISCARD; else if (strcasecmp (s, "one_only") == 0) type = LINKONCE_ONE_ONLY; else if (strcasecmp (s, "same_size") == 0) type = LINKONCE_SAME_SIZE; else if (strcasecmp (s, "same_contents") == 0) type = LINKONCE_SAME_CONTENTS; else as_warn (_("unrecognized .linkonce type `%s'"), s); *input_line_pointer = c; }#ifdef obj_handle_link_once obj_handle_link_once (type);#else /* ! defined (obj_handle_link_once) */#ifdef BFD_ASSEMBLER { flagword flags; if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0) as_warn (_(".linkonce is not supported for this object file format")); flags = bfd_get_section_flags (stdoutput, now_seg); flags |= SEC_LINK_ONCE; switch (type) { default: abort (); case LINKONCE_DISCARD: flags |= SEC_LINK_DUPLICATES_DISCARD; break; case LINKONCE_ONE_ONLY: flags |= SEC_LINK_DUPLICATES_ONE_ONLY; break; case LINKONCE_SAME_SIZE: flags |= SEC_LINK_DUPLICATES_SAME_SIZE; break; case LINKONCE_SAME_CONTENTS: flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS; break; } if (!bfd_set_section_flags (stdoutput, now_seg, flags)) as_bad (_("bfd_set_section_flags: %s"), bfd_errmsg (bfd_get_error ())); }#else /* ! defined (BFD_ASSEMBLER) */ as_warn (_(".linkonce is not supported for this object file format"));#endif /* ! defined (BFD_ASSEMBLER) */#endif /* ! defined (obj_handle_link_once) */ demand_empty_rest_of_line ();}static voids_lcomm_internal (needs_align, bytes_p) /* 1 if this was a ".bss" directive, which may require a 3rd argument (alignment); 0 if it was an ".lcomm" (2 args only). */ int needs_align; /* 1 if the alignment value should be interpreted as the byte boundary, rather than the power of 2. */ int bytes_p;{ register char *name; register char c; register char *p; register int temp; register symbolS *symbolP; segT current_seg = now_seg; subsegT current_subseg = now_subseg; const int max_alignment = 15; int align = 0; segT bss_seg = bss_section; name = input_line_pointer; c = get_symbol_end (); p = input_line_pointer; *p = c; SKIP_WHITESPACE (); /* Accept an optional comma after the name. The comma used to be required, but Irix 5 cc does not generate it. */ if (*input_line_pointer == ',') { ++input_line_pointer; SKIP_WHITESPACE (); } if (*input_line_pointer == '\n') { as_bad (_("Missing size expression")); return; } if ((temp = get_absolute_expression ()) < 0) { as_warn (_("BSS length (%d.) <0! Ignored."), temp); ignore_rest_of_line (); return; }#if defined (TC_MIPS) || defined (TC_ALPHA) if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour || OUTPUT_FLAVOR == bfd_target_elf_flavour) { /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss. */ if (temp <= bfd_get_gp_size (stdoutput)) { bss_seg = subseg_new (".sbss", 1); seg_info (bss_seg)->bss = 1;#ifdef BFD_ASSEMBLER if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC)) as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));#endif } }#endif if (!needs_align) { TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align); /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */ if (align) record_alignment (bss_seg, align); } if (needs_align) { align = 0; SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad (_("Expected comma after size")); ignore_rest_of_line (); return; } input_line_pointer++; SKIP_WHITESPACE (); if (*input_line_pointer == '\n') { as_bad (_("Missing alignment")); return; } align = get_absolute_expression (); 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 > max_alignment) { align = max_alignment; as_warn (_("Alignment too large: %d. assumed."), align); } else if (align < 0) { align = 0; as_warn (_("Alignment negative. 0 assumed.")); } record_alignment (bss_seg, align); } else { /* Assume some objects may require alignment on some systems. */#if defined (TC_ALPHA) && ! defined (VMS) if (temp > 1) { align = ffs (temp) - 1; if (temp % (1 << align)) abort (); }#endif } *p = 0; symbolP = symbol_find_or_make (name); *p = c; if (#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \ || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))#ifdef BFD_ASSEMBLER (OUTPUT_FLAVOR != bfd_target_aout_flavour || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&#else (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&#endif#endif (S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0))) { char *pfrag; subseg_set (bss_seg, 1); if (align) frag_align (align, 0, 0); /* Detach from old frag. */ if (S_GET_SEGMENT (symbolP) == bss_seg) symbol_get_frag (symbolP)->fr_symbol = NULL; symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) temp, (char *) 0); *pfrag = 0; S_SET_SEGMENT (symbolP, bss_seg);#ifdef OBJ_COFF /* The symbol may already have been created with a preceding ".globl" directive -- be careful not to step on storage class in that case. Otherwise, set it to static. */ if (S_GET_STORAGE_CLASS (symbolP) != C_EXT) { S_SET_STORAGE_CLASS (symbolP, C_STAT); }#endif /* OBJ_COFF */#ifdef S_SET_SIZE S_SET_SIZE (symbolP, temp);#endif } else as_bad (_("Ignoring attempt to re-define symbol `%s'."), S_GET_NAME (symbolP)); subseg_set (current_seg, current_subseg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -