diff options
Diffstat (limited to 'gas/read.c')
-rw-r--r-- | gas/read.c | 114 |
1 files changed, 86 insertions, 28 deletions
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MASK_CHAR ((int)(unsigned char)-1) #endif + /* This is the largest known floating point format (for now). It will grow when we do 4361 style flonums. */ @@ -44,6 +45,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif #include "obstack.h" +#include "listing.h" + + +#ifndef TC_START_LABEL +#define TC_START_LABEL(x,y) (x==':') +#endif /* The NOP_OPCODE is for the alignment fill value. * fill it a nop instruction so that the disassembler does not choke @@ -195,7 +202,8 @@ static const pseudo_typeS potable[] = /* err */ /* extend */ {"extern", s_ignore, 0}, /* We treat all undef as ext */ - {"appfile", s_app_file, 0}, + {"appfile", s_app_file, 1}, + {"appline", s_app_line, 0}, {"file", s_app_file, 0}, {"fill", s_fill, 0}, {"float", float_cons, 'f'}, @@ -405,7 +413,7 @@ read_a_source_file (name) * [In case of pseudo-op, s->'.'.] * Input_line_pointer->'\0' where c was. */ - if (c == ':') + if (TC_START_LABEL(c, input_line_pointer)) { colon (s); /* user-defined label */ *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */ @@ -828,8 +836,16 @@ s_data () demand_empty_rest_of_line (); } +/* Handle the .appfile pseudo-op. This is automatically generated by + do_scrub_next_char 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. */ + void -s_app_file () +s_app_file (appfile) + int appfile; { register char *s; int length; @@ -837,14 +853,41 @@ s_app_file () /* Some assemblers tolerate immediately following '"' */ if ((s = demand_copy_string (&length)) != 0) { - new_logical_line (s, -1); + /* 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. */ + new_logical_line (s, appfile ? -2 : -1); demand_empty_rest_of_line (); +#ifdef LISTING + if (listing) + listing_source_file (s); +#endif } #ifdef OBJ_COFF c_dot_file_symbol (s); #endif /* OBJ_COFF */ } /* s_app_file() */ +/* Handle the .appline pseudo-op. This is automatically generated by + do_scrub_next_char when a preprocessor # line comment is seen. + This default definition may be overridden by the object or CPU + specific pseudo-ops. */ + +void +s_app_line () +{ + int l; + + /* The given number is that of the next line. */ + l = get_absolute_expression () - 1; + new_logical_line ((char *) NULL, l); +#ifdef LISTING + if (listing) + listing_source_line (l); +#endif + demand_empty_rest_of_line (); +} + void s_fill () { @@ -943,8 +986,11 @@ s_lcomm (needs_align) 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 (); @@ -973,6 +1019,14 @@ s_lcomm (needs_align) return; } +#ifdef TC_MIPS +#ifdef OBJ_ECOFF + /* For MIPS ECOFF, small objects are put in .sbss. */ + if (temp <= bfd_get_gp_size (stdoutput)) + bss_seg = subseg_new (".sbss", 1); +#endif +#endif + if (needs_align) { align = 0; @@ -1001,7 +1055,7 @@ s_lcomm (needs_align) align = 0; as_warn ("Alignment negative. 0 assumed."); } - record_alignment (bss_section, align); + record_alignment (bss_seg, align); } /* if needs align */ *p = 0; @@ -1013,23 +1067,21 @@ s_lcomm (needs_align) S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0 && #endif /* OBJ_AOUT or OBJ_BOUT */ - (S_GET_SEGMENT (symbolP) == bss_section + (S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0))) { char *p; - segT current_seg = now_seg; - subsegT current_subseg = now_subseg; #ifdef BFD_ASSEMBLER - subseg_set (bss_section, 1); + subseg_set (bss_seg, 1); #else - subseg_new (bss_section, 1); + subseg_new (bss_seg, 1); #endif if (align) frag_align (align, 0); /* detach from old frag */ - if (S_GET_SEGMENT (symbolP) == bss_section) + if (S_GET_SEGMENT (symbolP) == bss_seg) symbolP->sy_frag->fr_symbol = NULL; symbolP->sy_frag = frag_now; @@ -1037,7 +1089,7 @@ s_lcomm (needs_align) temp, (char *)0); *p = 0; - S_SET_SEGMENT (symbolP, bss_section); + S_SET_SEGMENT (symbolP, bss_seg); #ifdef OBJ_COFF /* The symbol may already have been created with a preceding @@ -1048,19 +1100,19 @@ s_lcomm (needs_align) S_SET_STORAGE_CLASS (symbolP, C_STAT); } #endif /* OBJ_COFF */ -#ifdef BFD_ASSEMBLER - subseg_set (current_seg, current_subseg); -#else - subseg_new (current_seg, current_subseg); -#endif } else { as_bad ("Ignoring attempt to re-define symbol %s.", name); } - demand_empty_rest_of_line (); - return; +#ifdef BFD_ASSEMBLER + subseg_set (current_seg, current_subseg); +#else + subseg_new (current_seg, current_subseg); +#endif + + demand_empty_rest_of_line (); } /* s_lcomm() */ void @@ -1406,18 +1458,23 @@ pseudo_set (symbolP) && (S_GET_SEGMENT (exp.X_add_symbol) == S_GET_SEGMENT (exp.X_subtract_symbol))) { - if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag) + if (exp.X_add_symbol->sy_frag == exp.X_subtract_symbol->sy_frag) { - as_bad ("Unknown expression: symbols %s and %s are in different frags.", - S_GET_NAME (exp.X_add_symbol), S_GET_NAME (exp.X_subtract_symbol)); - need_pass_2++; + exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) - + S_GET_VALUE (exp.X_subtract_symbol); + goto abs; } - exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) - - S_GET_VALUE (exp.X_subtract_symbol); + as_bad ("Invalid expression: separation between symbols `%s'", + S_GET_NAME (exp.X_add_symbol)); + as_bad (" and `%s' may not be constant", + S_GET_NAME (exp.X_subtract_symbol)); + need_pass_2++; } else - as_bad ("Complex expression. Absolute segment assumed."); - goto abs; + { + as_bad ("Complex expression. Absolute segment assumed."); + goto abs; + } } else if (segment == absolute_section) { @@ -1785,6 +1842,7 @@ cons (nbytes) /* undefined_section, others */ { defalt: + md_number_to_chars (p, (long) 0, nbytes); #ifdef BFD_ASSEMBLER fix_new (frag_now, p - frag_now->fr_literal, nbytes, exp.X_add_symbol, exp.X_subtract_symbol, @@ -2051,7 +2109,7 @@ float_cons (float_type) /* Worker to do .float etc statements. */ err = md_atof (float_type, temp, &length); know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); know (length > 0); - if (*err) + if (err && *err) { as_bad ("Bad floating literal: %s", err); ignore_rest_of_line (); |