1 /* read.c - read a source file -
3 Copyright (C) 1986, 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
22 change this a bit. But then, GNU isn't
23 spozed to run on your machine anyway.
24 (RMS is so shortsighted sometimes.)
27 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
28 /* This is the largest known floating point */
29 /* format (for now). It will grow when we */
30 /* do 4361 style flonums. */
33 /* Routines that read assembler source text to build spagetti in memory. */
34 /* Another group of these functions is in the as-expr.c module */
40 char *input_line_pointer
; /*->next char of source file to parse. */
43 #if BITS_PER_CHAR != 8
44 The following table is indexed by
[ (char) ] and will
break if
45 a
char does
not have exactly
256 states (hopefully
0:255!) !
48 const char /* used by is_... macros. our ctype[] */
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
52 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
53 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
54 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
55 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
56 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
57 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
70 * Out: 1 if this character ends a line.
73 char is_end_of_line
[256] = {
75 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
,99, _
, _
, 99, _
, _
,/* @abcdefghijklmno */
77 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
,99, _
, _
, _
, _
, _
, /* @abcdefghijklmno */
79 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
80 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
81 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
,99, _
, _
, _
, _
, /* 0123456789:;<=>? */
82 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
83 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
84 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
85 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
86 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
87 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
88 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
89 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
90 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
/* */
94 /* Functions private to this file. */
96 char line_comment_chars
[1];
97 char line_separator_chars
[1];
99 static char *buffer
; /* 1st char of each buffer of lines is here. */
100 static char *buffer_limit
; /*->1 + last char in buffer. */
102 static char *bignum_low
; /* Lowest char of bignum. */
103 static char *bignum_limit
; /* 1st illegal address of bignum. */
104 static char *bignum_high
; /* Highest char of bignum. */
105 /* May point to (bignum_start-1). */
106 /* Never >= bignum_limit. */
107 static char *old_buffer
= 0; /* JF a hack */
108 static char *old_input
;
109 static char *old_limit
;
111 /* Variables for handling include file directory list. */
113 char **include_dirs
; /* List of pointers to directories to
114 search for .include's */
115 int include_dir_count
; /* How many are in the list */
116 int include_dir_maxlen
= 1; /* Length of longest in list */
118 #ifndef WORKING_DOT_WORD
119 struct broken_word
*broken_words
;
120 int new_broken_words
= 0;
125 static char *demand_copy_string(int *lenP
);
126 int is_it_end_of_statement(void);
127 unsigned int next_char_of_string(void);
128 static segT
get_known_segmented_expression(expressionS
*expP
);
129 static void grow_bignum(void);
130 static void pobegin(void);
131 void stringer(int append_zero
);
135 static char *demand_copy_string();
136 int is_it_end_of_statement();
137 unsigned int next_char_of_string();
138 static segT
get_known_segmented_expression();
139 static void grow_bignum();
140 static void pobegin();
143 #endif /* not __STDC__ */
154 obj_read_begin_hook();
156 obstack_begin(¬es
, 5000);
157 obstack_begin(&cond_obstack
, 960);
159 #define BIGNUM_BEGIN_SIZE (16)
160 bignum_low
= xmalloc((long)BIGNUM_BEGIN_SIZE
);
161 bignum_limit
= bignum_low
+ BIGNUM_BEGIN_SIZE
;
163 /* Use machine dependent syntax */
164 for (p
= line_separator_chars
; *p
; p
++)
165 is_end_of_line
[*p
] = 1;
166 /* Use more. FIXME-SOMEDAY. */
169 /* set up pseudo-op tables */
171 struct hash_control
*
172 po_hash
= NULL
; /* use before set up: NULL->address error */
175 void s_gdbline(), s_gdblinetab();
176 void s_gdbbeg(), s_gdbblock(), s_gdbend(), s_gdbsym();
179 static const pseudo_typeS
182 { "abort", s_abort
, 0 },
183 { "align", s_align_ptwo
, 0 },
184 { "ascii", stringer
, 0 },
185 { "asciz", stringer
, 1 },
188 { "comm", s_comm
, 0 },
189 { "data", s_data
, 0 },
191 { "double", float_cons
, 'd' },
193 { "eject", listing_eject
, 0 }, /* Formfeed listing */
194 { "else", s_else
, 0 },
196 { "endif", s_endif
, 0 },
201 { "extern", s_ignore
, 0 }, /* We treat all undef as ext */
202 { "app-file", s_app_file
, 0 },
203 { "file", s_app_file
, 0 },
204 { "fill", s_fill
, 0 },
205 { "float", float_cons
, 'f' },
207 { "gdbbeg", s_gdbbeg
, 0 },
208 { "gdbblock", s_gdbblock
, 0 },
209 { "gdbend", s_gdbend
, 0 },
210 { "gdbsym", s_gdbsym
, 0 },
211 { "gdbline", s_gdbline
, 0 },
212 { "gdblinetab",s_gdblinetab
, 0 },
214 { "global", s_globl
, 0 },
215 { "globl", s_globl
, 0 },
216 { "hword", cons
, 2 },
218 { "ifdef", s_ifdef
, 0 },
219 { "ifeqs", s_ifeqs
, 0 },
220 { "ifndef", s_ifdef
, 1 },
221 { "ifnes", s_ifeqs
, 1 },
222 { "ifnotdef", s_ifdef
, 1 },
223 { "include", s_include
, 0 },
225 { "lcomm", s_lcomm
, 0 },
226 { "lflags", listing_flags
, 0 }, /* Listing flags */
227 { "list", listing_list
, 1 }, /* Turn listing on */
229 { "lsym", s_lsym
, 0 },
230 { "nolist", listing_list
, 0 }, /* Turn listing off */
231 { "octa", big_cons
, 16 },
233 { "psize", listing_psize
, 0 }, /* set paper size */
235 { "quad", big_cons
, 8 },
236 { "sbttl", listing_title
, 1 }, /* Subtitle of listing */
240 { "short", cons
, 2 },
241 { "single", float_cons
, 'f' },
243 { "space", s_space
, 0 },
245 { "text", s_text
, 0 },
246 { "title", listing_title
, 0 }, /* Listing title */
251 { NULL
} /* end sentinel */
254 static void pobegin() {
255 char *errtxt
; /* error text */
256 const pseudo_typeS
* pop
;
258 po_hash
= hash_new();
260 /* Do the target-specific pseudo ops. */
261 for (pop
= md_pseudo_table
; pop
->poc_name
; pop
++) {
262 errtxt
= hash_insert(po_hash
, pop
->poc_name
, (char *)pop
);
263 if (errtxt
&& *errtxt
) {
264 as_fatal("error constructing md pseudo-op table");
268 /* Now object specific. Skip any that were in the target table. */
269 for (pop
=obj_pseudo_table
; pop
->poc_name
; pop
++) {
270 errtxt
= hash_insert (po_hash
, pop
->poc_name
, (char *)pop
);
271 if (errtxt
&& *errtxt
) {
272 if (!strcmp (errtxt
, "exists")) {
273 #ifdef DIE_ON_OVERRIDES
274 as_fatal("pseudo op \".%s\" overridden.\n", pop
->poc_name
);
275 #endif /* DIE_ON_OVERRIDES */
276 continue; /* OK if target table overrides. */
278 as_fatal("error constructing obj pseudo-op table");
279 } /* if overridden */
283 /* Now portable ones. Skip any that we've seen already. */
284 for (pop
=potable
; pop
->poc_name
; pop
++) {
285 errtxt
= hash_insert (po_hash
, pop
->poc_name
, (char *)pop
);
286 if (errtxt
&& *errtxt
) {
287 if (!strcmp (errtxt
, "exists")) {
288 #ifdef DIE_ON_OVERRIDES
289 as_fatal("pseudo op \".%s\" overridden.\n", pop
->poc_name
);
290 #endif /* DIE_ON_OVERRIDES */
291 continue; /* OK if target table overrides. */
293 as_fatal("error constructing obj pseudo-op table");
294 } /* if overridden */
301 #define HANDLE_CONDITIONAL_ASSEMBLY() \
302 if (ignore_input ()) \
304 while (! is_end_of_line[*input_line_pointer++]) \
305 if (input_line_pointer == buffer_limit) \
311 /* read_a_source_file()
313 * We read the file, putting things into a web that
314 * represents what we have been reading.
316 void read_a_source_file(name
)
320 register char * s
; /* string of symbol, '\0' appended */
322 /* register struct frag * fragP; JF unused */ /* a frag we just made */
325 void gdb_block_beg();
326 void gdb_block_position();
327 void gdb_block_end();
328 void gdb_symbols_fixup();
331 buffer
= input_scrub_new_file(name
);
336 while ((buffer_limit
= input_scrub_next_buffer(&input_line_pointer
)) != 0) { /* We have another line to parse. */
337 know(buffer_limit
[-1] == '\n'); /* Must have a sentinel. */
338 contin
: /* JF this goto is my fault I admit it. Someone brave please re-write
339 the whole input section here? Pleeze??? */
340 while (input_line_pointer
< buffer_limit
) { /* We have more of this buffer to parse. */
343 * We now have input_line_pointer->1st char of next line.
344 * If input_line_pointer [-1] == '\n' then we just
345 * scanned another line: so bump line counters.
347 if (input_line_pointer
[-1] == '\n') {
348 bump_line_counters();
349 } /* just passed a newline */
354 * We are at the begining of a line, or similar place.
355 * We expect a well-formed assembler statement.
356 * A "symbol-name:" is a statement.
358 * Depending on what compiler is used, the order of these tests
359 * may vary to catch most common case 1st.
360 * Each test is independent of all other tests at the (top) level.
361 * PLEASE make a compiler that doesn't use this assembler.
362 * It is crufty to waste a compiler's time encoding things for this
363 * assembler, which then wastes more time decoding it.
364 * (And communicating via (linear) files is silly!
365 * If you must pass stuff, please pass a tree!)
367 if ((c
= *input_line_pointer
++) == '\t' || c
== ' ' || c
=='\f' || c
== 0) {
368 c
= *input_line_pointer
++;
370 know(c
!= ' '); /* No further leading whitespace. */
373 * C is the 1st significant character.
374 * Input_line_pointer points after that character.
376 if (is_name_beginner(c
)) { /* want user-defined label or pseudo/opcode */
377 HANDLE_CONDITIONAL_ASSEMBLY();
379 s
= --input_line_pointer
;
380 c
= get_symbol_end(); /* name's delimiter */
382 * C is character after symbol.
383 * That character's place in the input line is now '\0'.
384 * S points to the beginning of the symbol.
385 * [In case of pseudo-op, s->'.'.]
386 * Input_line_pointer->'\0' where c was.
389 colon(s
); /* user-defined label */
390 * input_line_pointer
++ = ':'; /* Put ':' back for error messages' sake. */
391 /* Input_line_pointer->after ':'. */
395 } else if (c
== '=' || input_line_pointer
[1] == '=') { /* JF deal with FOO=BAR */
397 demand_empty_rest_of_line();
398 } else { /* expect pseudo-op or machine instruction */
403 * WARNING: c has next char, which may be end-of-line.
404 * We lookup the pseudo-op table with s+1 because we
405 * already know that the pseudo-op begins with a '.'.
408 pop
= (pseudo_typeS
*) hash_find(po_hash
, s
+1);
410 /* Print the error msg now, while we still can */
412 as_bad("Unknown pseudo-op: `%s'",s
);
413 *input_line_pointer
= c
;
418 /* Put it back for error messages etc. */
419 *input_line_pointer
= c
;
420 /* The following skip of whitespace is compulsory. */
421 /* A well shaped space is sometimes all that separates keyword from operands. */
422 if (c
== ' ' || c
== '\t') {
423 input_line_pointer
++;
424 } /* Skip seperator after keyword. */
426 * Input_line is restored.
427 * Input_line_pointer->1st non-blank char
428 * after pseudo-operation.
431 ignore_rest_of_line();
434 (*pop
->poc_handler
)(pop
->poc_val
);
435 } /* if we have one */
436 } else { /* machine instruction */
437 /* WARNING: c has char, which may be end-of-line. */
438 /* Also: input_line_pointer->`\0` where c was. */
439 * input_line_pointer
= c
;
440 while (!is_end_of_line
[*input_line_pointer
]) {
441 input_line_pointer
++;
443 c
= *input_line_pointer
;
444 *input_line_pointer
= '\0';
445 md_assemble(s
); /* Assemble 1 instruction. */
446 *input_line_pointer
++ = c
;
447 /* We resume loop AFTER the end-of-line from this instruction */
452 } /* if (is_name_beginner(c) */
455 if (is_end_of_line
[c
]) {
457 } /* empty statement */
460 if (isdigit(c
)) { /* local label ("4:") */
461 HANDLE_CONDITIONAL_ASSEMBLY ();
464 #ifdef LOCAL_LABELS_DOLLAR
465 if (*input_line_pointer
=='$')
466 input_line_pointer
++;
468 if (* input_line_pointer
++ == ':')
474 as_bad("Spurious digit %d.", temp
);
475 input_line_pointer
-- ;
476 ignore_rest_of_line();
479 } /* local label ("4:") */
481 if (c
&& strchr(line_comment_chars
,c
)) { /* Its a comment. Better say APP or NO_APP */
487 extern char *scrub_string
,*scrub_last_string
;
489 bump_line_counters();
490 s
=input_line_pointer
;
491 if (strncmp(s
,"APP\n",4))
492 continue; /* We ignore it */
495 ends
=strstr(s
,"#NO_APP\n");
501 /* The end of the #APP wasn't in this buffer. We
502 keep reading in buffers until we find the #NO_APP
503 that goes with this #APP There is one. The specs
505 tmp_len
=buffer_limit
-s
;
506 tmp_buf
=xmalloc(tmp_len
);
507 bcopy(s
,tmp_buf
,tmp_len
);
509 new_tmp
= input_scrub_next_buffer(&buffer
);
513 buffer_limit
= new_tmp
;
514 input_line_pointer
= buffer
;
515 ends
= strstr(buffer
,"#NO_APP\n");
519 num
=buffer_limit
-buffer
;
521 tmp_buf
= xrealloc(tmp_buf
, tmp_len
+ num
);
522 bcopy(buffer
,tmp_buf
+tmp_len
,num
);
526 input_line_pointer
= ends
? ends
+8 : NULL
;
532 input_line_pointer
=ends
+8;
534 new_buf
=xmalloc(100);
539 scrub_last_string
= ends
;
543 ch
= do_scrub_next_char(scrub_from_string
, scrub_to_string
);
546 if (new_tmp
==new_buf
+new_length
) {
547 new_buf
=xrealloc(new_buf
,new_length
+100);
548 new_tmp
=new_buf
+new_length
;
556 old_input
=input_line_pointer
;
557 old_limit
=buffer_limit
;
559 input_line_pointer
=new_buf
;
560 buffer_limit
=new_tmp
;
564 HANDLE_CONDITIONAL_ASSEMBLY();
566 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
567 input_line_pointer
--; /* Report unknown char as ignored. */
568 ignore_rest_of_line();
569 } /* while (input_line_pointer<buffer_limit) */
571 bump_line_counters();
572 if (old_input
!= 0) {
574 input_line_pointer
=old_input
;
575 buffer_limit
=old_limit
;
580 } /* while (more buffers to scan) */
581 input_scrub_close(); /* Close the input file */
583 } /* read_a_source_file() */
586 as_fatal(".abort detected. Abandoning ship.");
589 /* For machines where ".align 4" means align to a 4 byte boundary. */
590 void s_align_bytes(arg
)
593 register unsigned int temp
;
594 register long temp_fill
;
596 unsigned long max_alignment
= 1 << 15;
598 if (is_end_of_line
[*input_line_pointer
])
599 temp
= arg
; /* Default value from pseudo-op table */
601 temp
= get_absolute_expression ();
603 if (temp
> max_alignment
) {
604 as_bad("Alignment too large: %d. assumed.", temp
= max_alignment
);
608 * For the sparc, `.align (1<<n)' actually means `.align n'
609 * so we have to convert it.
612 for (i
= 0; (temp
& 1) == 0; temp
>>= 1, ++i
)
616 as_bad("Alignment not a power of 2");
619 if (*input_line_pointer
== ',') {
620 input_line_pointer
++;
621 temp_fill
= get_absolute_expression ();
625 /* Only make a frag if we HAVE to. . . */
626 if (temp
&& ! need_pass_2
)
627 frag_align(temp
, (int)temp_fill
);
629 demand_empty_rest_of_line();
630 } /* s_align_bytes() */
632 /* For machines where ".align 4" means align to 2**4 boundary. */
633 void s_align_ptwo() {
635 register long temp_fill
;
636 long max_alignment
= 15;
638 temp
= get_absolute_expression ();
639 if (temp
> max_alignment
)
640 as_bad("Alignment too large: %d. assumed.", temp
= max_alignment
);
642 as_bad("Alignment negative. 0 assumed.");
645 if (*input_line_pointer
== ',') {
646 input_line_pointer
++;
647 temp_fill
= get_absolute_expression ();
650 /* Only make a frag if we HAVE to. . . */
651 if (temp
&& ! need_pass_2
)
652 frag_align (temp
, (int)temp_fill
);
654 record_alignment(now_seg
, temp
);
656 demand_empty_rest_of_line();
657 } /* s_align_ptwo() */
664 register symbolS
* symbolP
;
666 name
= input_line_pointer
;
667 c
= get_symbol_end();
668 /* just after name is now '\0' */
669 p
= input_line_pointer
;
672 if (*input_line_pointer
!= ',') {
673 as_bad("Expected comma after symbol-name: rest of line ignored.");
674 ignore_rest_of_line();
677 input_line_pointer
++; /* skip ',' */
678 if ((temp
= get_absolute_expression()) < 0) {
679 as_warn(".COMMon length (%d.) <0! Ignored.", temp
);
680 ignore_rest_of_line();
684 symbolP
= symbol_find_or_make(name
);
686 if (S_IS_DEFINED(symbolP
)) {
687 as_bad("Ignoring attempt to re-define symbol");
688 ignore_rest_of_line();
691 if (S_GET_VALUE(symbolP
)) {
692 if (S_GET_VALUE(symbolP
) != temp
)
693 as_bad("Length of .comm \"%s\" is already %d. Not changed to %d.",
695 S_GET_VALUE(symbolP
),
698 S_SET_VALUE(symbolP
, temp
);
699 S_SET_EXTERNAL(symbolP
);
703 symbolP
->sy_other
= const_flag
;
705 know(symbolP
->sy_frag
== &zero_address_frag
);
706 demand_empty_rest_of_line();
714 temp
= get_absolute_expression ();
716 subseg_new (SEG_E1
, (subsegT
)temp
);
718 subseg_new (SEG_DATA
, (subsegT
)temp
);
724 demand_empty_rest_of_line();
731 /* Some assemblers tolerate immediately following '"' */
732 if ((s
= demand_copy_string(&length
)) != 0) {
733 new_logical_line(s
, -1);
734 demand_empty_rest_of_line();
737 c_dot_file_symbol(s
);
738 #endif /* OBJ_COFF */
744 register long temp_fill
;
747 if (get_absolute_expression_and_terminator(& temp_repeat
) != ',') {
748 input_line_pointer
--; /* Backup over what was not a ','. */
749 as_bad("Expect comma after rep-size in .fill:");
750 ignore_rest_of_line();
753 if (get_absolute_expression_and_terminator(& temp_size
) != ',') {
754 input_line_pointer
--; /* Backup over what was not a ','. */
755 as_bad("Expected comma after size in .fill");
756 ignore_rest_of_line();
760 * This is to be compatible with BSD 4.2 AS, not for any rational reason.
762 #define BSD_FILL_SIZE_CROCK_8 (8)
763 if (temp_size
> BSD_FILL_SIZE_CROCK_8
) {
764 as_bad(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8
);
765 temp_size
= BSD_FILL_SIZE_CROCK_8
;
766 } if (temp_size
< 0) {
767 as_warn("Size negative: .fill ignored.");
769 } else if (temp_repeat
<= 0) {
770 as_warn("Repeat < 0, .fill ignored");
773 temp_fill
= get_absolute_expression ();
774 if (temp_size
&& !need_pass_2
) {
775 p
= frag_var(rs_fill
, (int)temp_size
, (int)temp_size
, (relax_substateT
)0, (symbolS
*)0, temp_repeat
, (char *)0);
776 bzero (p
, (int)temp_size
);
778 * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
779 * The following bizzare behaviour is to be compatible with above.
780 * I guess they tried to take up to 8 bytes from a 4-byte expression
781 * and they forgot to sign extend. Un*x Sux.
783 #define BSD_FILL_SIZE_CROCK_4 (4)
784 md_number_to_chars (p
, temp_fill
, temp_size
> BSD_FILL_SIZE_CROCK_4
? BSD_FILL_SIZE_CROCK_4
: (int)temp_size
);
786 * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
787 * but emits no error message because it seems a legal thing to do.
788 * It is a degenerate case of .fill but could be emitted by a compiler.
791 demand_empty_rest_of_line();
800 temp
= get_absolute_expression ();
802 as_warn("Block number <0. Ignored.");
803 else if (flagseen
['G'])
804 gdb_block_beg ((long) temp
, frag_now
, (long)(obstack_next_free(& frags
) - frag_now
->fr_literal
));
805 demand_empty_rest_of_line ();
811 register int position
;
814 if (get_absolute_expression_and_terminator (&temp
) != ',') {
815 as_bad("expected comma before position in .gdbblock");
816 --input_line_pointer
;
817 ignore_rest_of_line ();
820 position
= get_absolute_expression ();
822 gdb_block_position ((long) temp
, (long) position
);
823 demand_empty_rest_of_line ();
831 temp
= get_absolute_expression ();
833 as_warn("Block number <0. Ignored.");
834 else if (flagseen
['G'])
835 gdb_block_end ((long) temp
, frag_now
, (long)(obstack_next_free(& frags
) - frag_now
->fr_literal
));
836 demand_empty_rest_of_line ();
845 register symbolS
* symbolP
;
848 name
= input_line_pointer
;
849 c
= get_symbol_end();
850 p
= input_line_pointer
;
851 symbolP
= symbol_find_or_make(name
);
854 if (* input_line_pointer
!= ',') {
855 as_bad("Expected comma after name");
856 ignore_rest_of_line();
859 input_line_pointer
++;
860 if ((temp
= get_absolute_expression ()) < 0) {
861 as_bad("Bad GDB symbol file offset (%d.) <0! Ignored.", temp
);
862 ignore_rest_of_line();
866 gdb_symbols_fixup (symbolP
, (long)temp
);
867 demand_empty_rest_of_line ();
876 if (get_absolute_expression_and_terminator(&file_number
) != ',') {
877 as_bad("expected comman after filenum in .gdbline");
878 ignore_rest_of_line();
881 lineno
=get_absolute_expression();
883 gdb_line(file_number
,lineno
);
884 demand_empty_rest_of_line();
894 if (get_absolute_expression_and_terminator(&file_number
) != ',') {
895 as_bad("expected comma after filenum in .gdblinetab");
896 ignore_rest_of_line();
899 offset
=get_absolute_expression();
901 gdb_line_tab(file_number
,offset
);
902 demand_empty_rest_of_line();
909 register symbolS
* symbolP
;
912 name
= input_line_pointer
;
913 c
= get_symbol_end();
914 symbolP
= symbol_find_or_make(name
);
915 * input_line_pointer
= c
;
917 S_SET_EXTERNAL(symbolP
);
919 input_line_pointer
++;
921 if (*input_line_pointer
=='\n')
925 demand_empty_rest_of_line();
928 void s_lcomm(needs_align
)
929 int needs_align
; /* 1 if this was a ".bss" directive, which may require
930 * a 3rd argument (alignment).
931 * 0 if it was an ".lcomm" (2 args only)
938 register symbolS
* symbolP
;
939 const int max_alignment
= 15;
942 name
= input_line_pointer
;
943 c
= get_symbol_end();
944 p
= input_line_pointer
;
947 if (*input_line_pointer
!= ',') {
948 as_bad("Expected comma after name");
949 ignore_rest_of_line();
953 ++input_line_pointer
;
955 if (*input_line_pointer
== '\n') {
956 as_bad("Missing size expression");
960 if ((temp
= get_absolute_expression ()) < 0) {
961 as_warn("BSS length (%d.) <0! Ignored.", temp
);
962 ignore_rest_of_line();
969 if (*input_line_pointer
!= ',') {
970 as_bad("Expected comma after size");
971 ignore_rest_of_line();
974 input_line_pointer
++;
976 if (*input_line_pointer
== '\n') {
977 as_bad("Missing alignment");
980 align
= get_absolute_expression ();
981 if (align
> max_alignment
){
982 align
= max_alignment
;
983 as_warn("Alignment too large: %d. assumed.", align
);
984 } else if (align
< 0) {
986 as_warn("Alignment negative. 0 assumed.");
989 #define SEG_BSS SEG_E2
990 record_alignment(SEG_E2
, align
);
992 record_alignment(SEG_BSS
, align
);
994 } /* if needs align */
997 symbolP
= symbol_find_or_make(name
);
1001 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1002 S_GET_OTHER(symbolP
) == 0 &&
1003 S_GET_DESC(symbolP
) == 0 &&
1004 #endif /* OBJ_AOUT or OBJ_BOUT */
1005 (((S_GET_SEGMENT(symbolP
) == SEG_BSS
) && (S_GET_VALUE(symbolP
) == local_bss_counter
))
1006 || (!S_IS_DEFINED(symbolP
) && S_GET_VALUE(symbolP
) == 0))) {
1009 align
= ~ ((~0) << align
); /* Convert to a mask */
1011 (local_bss_counter
+ align
) & (~align
);
1014 S_SET_VALUE(symbolP
,local_bss_counter
);
1015 S_SET_SEGMENT(symbolP
, SEG_BSS
);
1017 /* The symbol may already have been created with a preceding
1018 * ".globl" directive -- be careful not to step on storage
1019 * class in that case. Otherwise, set it to static.
1021 if (S_GET_STORAGE_CLASS(symbolP
) != C_EXT
){
1022 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1024 #endif /* OBJ_COFF */
1025 symbolP
->sy_frag
= & bss_address_frag
;
1026 local_bss_counter
+= temp
;
1028 as_bad("Ignoring attempt to re-define symbol from %d. to %d.",
1029 S_GET_VALUE(symbolP
), local_bss_counter
);
1031 demand_empty_rest_of_line();
1049 register char *name
;
1052 register segT segment
;
1054 register symbolS
*symbolP
;
1056 /* we permit ANY defined expression: BSD4.2 demands constants */
1057 name
= input_line_pointer
;
1058 c
= get_symbol_end();
1059 p
= input_line_pointer
;
1062 if (* input_line_pointer
!= ',') {
1064 as_bad("Expected comma after name \"%s\"", name
);
1066 ignore_rest_of_line();
1069 input_line_pointer
++;
1070 segment
= expression(& exp
);
1071 if (segment
!= SEG_ABSOLUTE
1072 #ifdef MANY_SEGMENTS
1073 && ! ( segment
>= SEG_E0
&& segment
<= SEG_UNKNOWN
)
1075 && segment
!= SEG_DATA
1076 && segment
!= SEG_TEXT
1077 && segment
!= SEG_BSS
1079 && segment
!= SEG_REGISTER
) {
1080 as_bad("Bad expression: %s", segment_name(segment
));
1081 ignore_rest_of_line();
1085 symbolP
= symbol_find_or_make(name
);
1087 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0
1088 && symbolP->sy_desc == 0) out of this test
1089 because coff doesn't have those fields, and I
1090 can't see when they'd ever be tripped. I don't
1091 think I understand why they were here so I may
1092 have introduced a bug. As recently as 1.37 didn't
1093 have this test anyway. xoxorich. */
1095 if (S_GET_SEGMENT(symbolP
) == SEG_UNKNOWN
1096 && S_GET_VALUE(symbolP
) == 0) {
1097 /* The name might be an undefined .global symbol; be
1098 sure to keep the "external" bit. */
1099 S_SET_SEGMENT(symbolP
, segment
);
1100 S_SET_VALUE(symbolP
, (valueT
)(exp
.X_add_number
));
1102 as_bad("Symbol %s already defined", name
);
1105 demand_empty_rest_of_line();
1109 register segT segment
;
1111 register long temp_fill
;
1114 * Don't believe the documentation of BSD 4.2 AS.
1115 * There is no such thing as a sub-segment-relative origin.
1116 * Any absolute origin is given a warning, then assumed to be segment-relative.
1117 * Any segmented origin expression ("foo+42") had better be in the right
1118 * segment or the .org is ignored.
1120 * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
1121 * never know sub-segment sizes when we are reading code.
1122 * BSD will crash trying to emit -ve numbers of filler bytes in certain
1123 * .orgs. We don't crash, but see as-write for that code.
1126 * Don't make frag if need_pass_2==1.
1128 segment
= get_known_segmented_expression(&exp
);
1129 if (*input_line_pointer
== ',') {
1130 input_line_pointer
++;
1131 temp_fill
= get_absolute_expression ();
1134 if (! need_pass_2
) {
1135 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
1136 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1137 segment_name(segment
), segment_name(now_seg
));
1138 p
= frag_var (rs_org
, 1, 1, (relax_substateT
)0, exp
. X_add_symbol
,
1139 exp
. X_add_number
, (char *)0);
1141 } /* if (ok to make frag) */
1142 demand_empty_rest_of_line();
1146 register char *name
;
1147 register char delim
;
1148 register char *end_name
;
1149 register symbolS
*symbolP
;
1152 * Especial apologies for the random logic:
1153 * this just grew, and could be parsed much more simply!
1156 name
= input_line_pointer
;
1157 delim
= get_symbol_end();
1158 end_name
= input_line_pointer
;
1162 if (*input_line_pointer
!= ',') {
1164 as_bad("Expected comma after name \"%s\"", name
);
1166 ignore_rest_of_line();
1170 input_line_pointer
++;
1173 if (name
[0]=='.' && name
[1]=='\0') {
1174 /* Turn '. = mumble' into a .org mumble */
1175 register segT segment
;
1179 segment
= get_known_segmented_expression(& exp
);
1182 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
1183 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1184 segment_name(segment
),
1185 segment_name (now_seg
));
1186 ptr
= frag_var(rs_org
, 1, 1, (relax_substateT
)0, exp
.X_add_symbol
,
1187 exp
.X_add_number
, (char *)0);
1189 } /* if (ok to make frag) */
1195 if ((symbolP
= symbol_find(name
)) == NULL
1196 && (symbolP
= md_undefined_symbol(name
)) == NULL
) {
1197 symbolP
= symbol_new(name
,
1200 &zero_address_frag
);
1202 /* "set" symbols are local unless otherwise specified. */
1203 SF_SET_LOCAL(symbolP
);
1204 #endif /* OBJ_COFF */
1206 } /* make a new symbol */
1208 symbol_table_insert(symbolP
);
1211 pseudo_set(symbolP
);
1212 demand_empty_rest_of_line();
1217 register long temp_fill
;
1220 /* Just like .fill, but temp_size = 1 */
1221 if (get_absolute_expression_and_terminator(& temp_repeat
) == ',') {
1222 temp_fill
= get_absolute_expression ();
1224 input_line_pointer
--; /* Backup over what was not a ','. */
1227 if (temp_repeat
<= 0) {
1228 as_warn("Repeat < 0, .space ignored");
1229 ignore_rest_of_line();
1232 if (! need_pass_2
) {
1233 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
)0, (symbolS
*)0,
1234 temp_repeat
, (char *)0);
1237 demand_empty_rest_of_line();
1245 temp
= get_absolute_expression ();
1246 #ifdef MANY_SEGMENTS
1247 subseg_new (SEG_E0
, (subsegT
)temp
);
1249 subseg_new (SEG_TEXT
, (subsegT
)temp
);
1251 demand_empty_rest_of_line();
1255 /*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1257 void demand_empty_rest_of_line() {
1259 if (is_end_of_line
[*input_line_pointer
]) {
1260 input_line_pointer
++;
1262 ignore_rest_of_line();
1264 /* Return having already swallowed end-of-line. */
1265 } /* Return pointing just after end-of-line. */
1268 ignore_rest_of_line() /* For suspect lines: gives warning. */
1270 if (! is_end_of_line
[* input_line_pointer
])
1272 if (isprint(*input_line_pointer
))
1273 as_bad("Rest of line ignored. First ignored character is `%c'.",
1274 *input_line_pointer
);
1276 as_bad("Rest of line ignored. First ignored character valued 0x%x.",
1277 *input_line_pointer
);
1278 while (input_line_pointer
< buffer_limit
1279 && ! is_end_of_line
[* input_line_pointer
])
1281 input_line_pointer
++;
1284 input_line_pointer
++; /* Return pointing just after end-of-line. */
1285 know(is_end_of_line
[input_line_pointer
[-1]]);
1291 * In: Pointer to a symbol.
1292 * Input_line_pointer->expression.
1294 * Out: Input_line_pointer->just after any whitespace after expression.
1295 * Tried to set symbol to value of expression.
1296 * Will change symbols type, value, and frag;
1297 * May set need_pass_2 == 1.
1300 pseudo_set (symbolP
)
1304 register segT segment
;
1305 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1307 #endif /* OBJ_AOUT or OBJ_BOUT */
1309 know(symbolP
); /* NULL pointer is logic error. */
1310 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1311 ext
=S_IS_EXTERNAL(symbolP
);
1312 #endif /* OBJ_AOUT or OBJ_BOUT */
1314 if ((segment
= expression(& exp
)) == SEG_ABSENT
)
1316 as_bad("Missing expression: absolute 0 assumed");
1317 exp
. X_seg
= SEG_ABSOLUTE
;
1318 exp
. X_add_number
= 0;
1324 as_bad("%s number invalid. Absolute 0 assumed.",
1325 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1326 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1327 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1328 ext
? S_SET_EXTERNAL(symbolP
) :
1329 S_CLEAR_EXTERNAL(symbolP
);
1330 #endif /* OBJ_AOUT or OBJ_BOUT */
1331 S_SET_VALUE(symbolP
, 0);
1332 symbolP
->sy_frag
= & zero_address_frag
;
1336 as_warn("No expression: Using absolute 0");
1337 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1338 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1339 ext
? S_SET_EXTERNAL(symbolP
) :
1340 S_CLEAR_EXTERNAL(symbolP
);
1341 #endif /* OBJ_AOUT or OBJ_BOUT */
1342 S_SET_VALUE(symbolP
, 0);
1343 symbolP
->sy_frag
= & zero_address_frag
;
1346 case SEG_DIFFERENCE
:
1347 if (exp
.X_add_symbol
&& exp
.X_subtract_symbol
1348 && (S_GET_SEGMENT(exp
.X_add_symbol
) ==
1349 S_GET_SEGMENT(exp
.X_subtract_symbol
))) {
1350 if (exp
.X_add_symbol
->sy_frag
!= exp
.X_subtract_symbol
->sy_frag
) {
1351 as_bad("Unknown expression: symbols %s and %s are in different frags.",
1352 S_GET_NAME(exp
.X_add_symbol
), S_GET_NAME(exp
.X_subtract_symbol
));
1355 exp
.X_add_number
+=S_GET_VALUE(exp
.X_add_symbol
) -
1356 S_GET_VALUE(exp
.X_subtract_symbol
);
1358 as_bad("Complex expression. Absolute segment assumed.");
1360 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1361 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1362 ext
? S_SET_EXTERNAL(symbolP
) :
1363 S_CLEAR_EXTERNAL(symbolP
);
1364 #endif /* OBJ_AOUT or OBJ_BOUT */
1365 S_SET_VALUE(symbolP
, exp
.X_add_number
);
1366 symbolP
->sy_frag
= & zero_address_frag
;
1370 #ifdef MANY_SEGMENTS
1371 S_SET_SEGMENT(symbolP
, segment
);
1374 case SEG_DATA
: S_SET_SEGMENT(symbolP
, SEG_DATA
); break;
1375 case SEG_TEXT
: S_SET_SEGMENT(symbolP
, SEG_TEXT
); break;
1376 case SEG_BSS
: S_SET_SEGMENT(symbolP
, SEG_BSS
); break;
1377 default: as_fatal("failed sanity check.");
1378 } /* switch on segment */
1380 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1382 S_SET_EXTERNAL(symbolP
);
1384 S_CLEAR_EXTERNAL(symbolP
);
1386 #endif /* OBJ_AOUT or OBJ_BOUT */
1388 S_SET_VALUE(symbolP
, exp
.X_add_number
+ S_GET_VALUE(exp
.X_add_symbol
));
1389 symbolP
->sy_frag
= exp
. X_add_symbol
->sy_frag
;
1392 case SEG_PASS1
: /* Not an error. Just try another pass. */
1393 symbolP
->sy_forward
=exp
.X_add_symbol
;
1394 as_bad("Unknown expression");
1395 know(need_pass_2
== 1);
1399 symbolP
->sy_forward
=exp
.X_add_symbol
;
1400 /* as_warn("unknown symbol"); */
1401 /* need_pass_2 = 1; */
1412 * CONStruct more frag of .bytes, or .words etc.
1413 * Should need_pass_2 be 1 then emit no frag(s).
1414 * This understands EXPRESSIONS, as opposed to big_cons().
1418 * This has a split personality. We use expression() to read the
1419 * value. We can detect if the value won't fit in a byte or word.
1420 * But we can't detect if expression() discarded significant digits
1421 * in the case of a long. Not worth the crocks required to fix it.
1424 /* worker to do .byte etc statements */
1425 /* clobbers input_line_pointer, checks */
1428 register unsigned int nbytes
; /* 1=.byte, 2=.word, 4=.long */
1431 register long mask
; /* High-order bits we will left-truncate, */
1432 /* but includes sign bit also. */
1433 register long get
; /* what we get */
1434 register long use
; /* get after truncation. */
1435 register long unmask
; /* what bits we will store */
1437 register segT segment
;
1441 * Input_line_pointer->1st char after pseudo-op-code and could legally
1442 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1444 /* JF << of >= number of bits in the object is undefined. In particular
1445 SPARC (Sun 4) has problems */
1447 if (nbytes
>=sizeof(long)) {
1450 mask
= ~0 << (BITS_PER_CHAR
* nbytes
); /* Don't store these bits. */
1451 } /* bigger than a long */
1453 unmask
= ~mask
; /* Do store these bits. */
1456 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1457 mask
= ~ (unmask
>> 1); /* Includes sign bit now. */
1461 * The following awkward logic is to parse ZERO or more expressions,
1462 * comma seperated. Recall an expression includes its leading &
1463 * trailing blanks. We fake a leading ',' if there is (supposed to
1464 * be) a 1st expression, and keep demanding 1 expression for each ','.
1466 if (is_it_end_of_statement()) {
1467 c
= 0; /* Skip loop. */
1468 input_line_pointer
++; /* Matches end-of-loop 'correction'. */
1471 } /* if the end else fake it */
1475 #ifdef WANT_BITFIELDS
1476 unsigned int bits_available
= BITS_PER_CHAR
* nbytes
;
1477 /* used for error messages and rescanning */
1478 char *hold
= input_line_pointer
;
1479 #endif /* WANT_BITFIELDS */
1481 /* At least scan over the expression. */
1482 segment
= expression(&exp
);
1484 #ifdef WANT_BITFIELDS
1485 /* Some other assemblers, (eg, asm960), allow
1486 bitfields after ".byte" as w:x,y:z, where w and
1487 y are bitwidths and x and y are values. They
1488 then pack them all together. We do a little
1489 better in that we allow them in words, longs,
1490 etc. and we'll pack them in target byte order
1493 The rules are: pack least significat bit first,
1494 if a field doesn't entirely fit, put it in the
1495 next unit. Overflowing the bitfield is
1496 explicitly *not* even a warning. The bitwidth
1497 should be considered a "mask".
1499 FIXME-SOMEDAY: If this is considered generally
1500 useful, this logic should probably be reworked.
1503 if (*input_line_pointer
== ':') { /* bitfields */
1507 unsigned long width
;
1509 if (*input_line_pointer
!= ':') {
1510 input_line_pointer
= hold
;
1512 } /* next piece is not a bitfield */
1514 /* In the general case, we can't allow
1515 full expressions with symbol
1516 differences and such. The relocation
1517 entries for symbols not defined in this
1518 assembly would require arbitrary field
1519 widths, positions, and masks which most
1520 of our current object formats don't
1523 In the specific case where a symbol
1524 *is* defined in this assembly, we
1525 *could* build fixups and track it, but
1526 this could lead to confusion for the
1527 backends. I'm lazy. I'll take any
1528 SEG_ABSOLUTE. I think that means that
1529 you can use a previous .set or
1530 .equ type symbol. xoxorich. */
1532 if (segment
== SEG_ABSENT
) {
1533 as_warn("Using a bit field width of zero.");
1534 exp
.X_add_number
= 0;
1535 segment
= SEG_ABSOLUTE
;
1536 } /* implied zero width bitfield */
1538 if (segment
!= SEG_ABSOLUTE
) {
1539 *input_line_pointer
= '\0';
1540 as_bad("Field width \"%s\" too complex for a bitfield.\n", hold
);
1541 *input_line_pointer
= ':';
1542 demand_empty_rest_of_line();
1546 if ((width
= exp
.X_add_number
) > (BITS_PER_CHAR
* nbytes
)) {
1547 as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1548 width
, nbytes
, (BITS_PER_CHAR
* nbytes
));
1549 width
= BITS_PER_CHAR
* nbytes
;
1552 if (width
> bits_available
) {
1553 /* FIXME-SOMEDAY: backing up and
1554 reparsing is wasteful */
1555 input_line_pointer
= hold
;
1556 exp
.X_add_number
= value
;
1560 hold
= ++input_line_pointer
; /* skip ':' */
1562 if ((segment
= expression(&exp
)) != SEG_ABSOLUTE
) {
1563 char cache
= *input_line_pointer
;
1565 *input_line_pointer
= '\0';
1566 as_bad("Field value \"%s\" too complex for a bitfield.\n", hold
);
1567 *input_line_pointer
= cache
;
1568 demand_empty_rest_of_line();
1572 value
|= (~(-1 << width
) & exp
.X_add_number
)
1573 << ((BITS_PER_CHAR
* nbytes
) - bits_available
);
1575 if ((bits_available
-= width
) == 0
1576 || is_it_end_of_statement()
1577 || *input_line_pointer
!= ',') {
1579 } /* all the bitfields we're gonna get */
1581 hold
= ++input_line_pointer
;
1582 segment
= expression(&exp
);
1583 } /* forever loop */
1585 exp
.X_add_number
= value
;
1586 segment
= SEG_ABSOLUTE
;
1587 } /* if looks like a bitfield */
1588 #endif /* WANT_BITFIELDS */
1590 if (!need_pass_2
) { /* Still worthwhile making frags. */
1592 /* Don't call this if we are going to junk this pass anyway! */
1593 know(segment
!= SEG_PASS1
);
1595 if (segment
== SEG_DIFFERENCE
&& exp
.X_add_symbol
== NULL
) {
1596 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1597 S_GET_NAME(exp
.X_subtract_symbol
),
1598 segment_name(S_GET_SEGMENT(exp
.X_subtract_symbol
)));
1599 segment
= SEG_ABSOLUTE
;
1600 /* Leave exp . X_add_number alone. */
1602 p
= frag_more(nbytes
);
1605 as_bad("%s number invalid. Absolute 0 assumed.",
1606 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1607 md_number_to_chars (p
, (long)0, nbytes
);
1611 as_warn("0 assumed for missing expression");
1612 exp
. X_add_number
= 0;
1613 know(exp
. X_add_symbol
== NULL
);
1614 /* fall into SEG_ABSOLUTE */
1616 get
= exp
. X_add_number
;
1618 if ((get
& mask
) && (get
& mask
) != mask
)
1619 { /* Leading bits contain both 0s & 1s. */
1620 as_warn("Value 0x%x truncated to 0x%x.", get
, use
);
1622 md_number_to_chars (p
, use
, nbytes
); /* put bytes in right order. */
1625 case SEG_DIFFERENCE
:
1626 #ifndef WORKING_DOT_WORD
1628 struct broken_word
*x
;
1630 x
=(struct broken_word
*)xmalloc(sizeof(struct broken_word
));
1631 x
->next_broken_word
=broken_words
;
1634 x
->word_goes_here
=p
;
1636 x
->add
=exp
.X_add_symbol
;
1637 x
->sub
=exp
.X_subtract_symbol
;
1638 x
->addnum
=exp
.X_add_number
;
1643 /* Else Fall through into. . . */
1648 fix_new_ns32k (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1649 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1650 exp
. X_add_number
, 0, 0, 2, 0, 0);
1652 fix_new (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1653 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1654 exp
. X_add_number
, 0, RELOC_32
);
1655 #endif /* TC_NS32K */
1657 } /* switch(segment) */
1658 } /* if (!need_pass_2) */
1659 c
= *input_line_pointer
++;
1660 } /* while(c==',') */
1661 input_line_pointer
--; /* Put terminator back into stream. */
1662 demand_empty_rest_of_line();
1668 * CONStruct more frag(s) of .quads, or .octa etc.
1669 * Makes 0 or more new frags.
1670 * If need_pass_2 == 1, generate no frag.
1671 * This understands only bignums, not expressions. Cons() understands
1674 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1676 * This creates objects with struct obstack_control objs, destroying
1677 * any context objs held about a partially completed object. Beware!
1680 * I think it sucks to have 2 different types of integers, with 2
1681 * routines to read them, store them etc.
1682 * It would be nicer to permit bignums in expressions and only
1683 * complain if the result overflowed. However, due to "efficiency"...
1685 /* worker to do .quad etc statements */
1686 /* clobbers input_line_pointer, checks */
1688 /* 8=.quad 16=.octa ... */
1690 void big_cons(nbytes
)
1691 register int nbytes
;
1693 register char c
; /* input_line_pointer->c. */
1695 register long length
; /* Number of chars in an object. */
1696 register int digit
; /* Value of 1 digit. */
1697 register int carry
; /* For multi-precision arithmetic. */
1698 register int work
; /* For multi-precision arithmetic. */
1699 register char * p
; /* For multi-precision arithmetic. */
1701 extern char hex_value
[]; /* In hex_value.c. */
1704 * The following awkward logic is to parse ZERO or more strings,
1705 * comma seperated. Recall an expression includes its leading &
1706 * trailing blanks. We fake a leading ',' if there is (supposed to
1707 * be) a 1st expression, and keep demanding 1 expression for each ','.
1709 if (is_it_end_of_statement())
1711 c
= 0; /* Skip loop. */
1715 c
= ','; /* Do loop. */
1716 -- input_line_pointer
;
1720 ++ input_line_pointer
;
1722 c
= * input_line_pointer
;
1723 /* C contains 1st non-blank character of what we hope is a number. */
1726 c
= * ++ input_line_pointer
;
1727 if (c
== 'x' || c
=='X')
1729 c
= * ++ input_line_pointer
;
1742 * This feature (?) is here to stop people worrying about
1743 * mysterious zero constants: which is what they get when
1744 * they completely omit digits.
1746 if (hex_value
[c
] >= radix
) {
1747 as_bad("Missing digits. 0 assumed.");
1749 bignum_high
= bignum_low
- 1; /* Start constant with 0 chars. */
1750 for(; (digit
= hex_value
[c
]) < radix
; c
= * ++ input_line_pointer
)
1752 /* Multiply existing number by radix, then add digit. */
1754 for (p
=bignum_low
; p
<= bignum_high
; p
++)
1756 work
= (*p
& MASK_CHAR
) * radix
+ carry
;
1757 *p
= work
& MASK_CHAR
;
1758 carry
= work
>> BITS_PER_CHAR
;
1763 * bignum_high
= carry
& MASK_CHAR
;
1764 know((carry
& ~ MASK_CHAR
) == 0);
1767 length
= bignum_high
- bignum_low
+ 1;
1768 if (length
> nbytes
)
1770 as_warn("Most significant bits truncated in integer constant.");
1774 register long leading_zeroes
;
1776 for(leading_zeroes
= nbytes
- length
;
1786 p
= frag_more (nbytes
);
1787 bcopy (bignum_low
, p
, (int)nbytes
);
1789 /* C contains character after number. */
1791 c
= * input_line_pointer
;
1792 /* C contains 1st non-blank character after number. */
1794 demand_empty_rest_of_line();
1797 /* Extend bignum by 1 char. */
1798 static void grow_bignum() {
1799 register long length
;
1802 if (bignum_high
>= bignum_limit
)
1804 length
= bignum_limit
- bignum_low
;
1805 bignum_low
= xrealloc(bignum_low
, length
+ length
);
1806 bignum_high
= bignum_low
+ length
;
1807 bignum_limit
= bignum_low
+ length
+ length
;
1809 } /* grow_bignum(); */
1814 * CONStruct some more frag chars of .floats .ffloats etc.
1815 * Makes 0 or more new frags.
1816 * If need_pass_2 == 1, no frags are emitted.
1817 * This understands only floating literals, not expressions. Sorry.
1819 * A floating constant is defined by atof_generic(), except it is preceded
1820 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1821 * reading, I decided to be incompatible. This always tries to give you
1822 * rounded bits to the precision of the pseudo-op. Former AS did premature
1823 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1824 * a choice of 2 flavours of noise according to which of 2 floating-point
1825 * scanners you directed AS to use.
1827 * In: input_line_pointer->whitespace before, or '0' of flonum.
1831 void /* JF was static, but can't be if VAX.C is goning to use it */
1832 float_cons(float_type
) /* Worker to do .float etc statements. */
1833 /* Clobbers input_line-pointer, checks end-of-line. */
1834 register int float_type
; /* 'f':.ffloat ... 'F':.float ... */
1838 int length
; /* Number of chars in an object. */
1839 register char * err
; /* Error from scanning floating literal. */
1840 char temp
[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
];
1843 * The following awkward logic is to parse ZERO or more strings,
1844 * comma seperated. Recall an expression includes its leading &
1845 * trailing blanks. We fake a leading ',' if there is (supposed to
1846 * be) a 1st expression, and keep demanding 1 expression for each ','.
1848 if (is_it_end_of_statement())
1850 c
= 0; /* Skip loop. */
1851 ++ input_line_pointer
; /*->past termintor. */
1855 c
= ','; /* Do loop. */
1859 /* input_line_pointer->1st char of a flonum (we hope!). */
1861 /* Skip any 0{letter} that may be present. Don't even check if the
1862 * letter is legal. Someone may invent a "z" format and this routine
1863 * has no use for such information. Lusers beware: you get
1864 * diagnostics if your input is ill-conditioned.
1867 if (input_line_pointer
[0]=='0' && isalpha(input_line_pointer
[1]))
1868 input_line_pointer
+=2;
1870 err
= md_atof (float_type
, temp
, &length
);
1871 know(length
<= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
);
1875 as_bad("Bad floating literal: %s", err
);
1876 ignore_rest_of_line();
1877 /* Input_line_pointer->just after end-of-line. */
1878 c
= 0; /* Break out of loop. */
1884 p
= frag_more (length
);
1885 bcopy (temp
, p
, length
);
1888 c
= * input_line_pointer
++;
1889 /* C contains 1st non-white character after number. */
1890 /* input_line_pointer->just after terminator (c). */
1893 -- input_line_pointer
; /*->terminator (is not ','). */
1894 demand_empty_rest_of_line();
1895 } /* float_cons() */
1900 * We read 0 or more ',' seperated, double-quoted strings.
1902 * Caller should have checked need_pass_2 is FALSE because we don't check it.
1906 void stringer(append_zero
) /* Worker to do .ascii etc statements. */
1907 /* Checks end-of-line. */
1908 register int append_zero
; /* 0: don't append '\0', else 1 */
1910 /* register char * p; JF unused */
1911 /* register int length; JF unused */ /* Length of string we read, excluding */
1912 /* trailing '\0' implied by closing quote. */
1913 /* register char * where; JF unused */
1914 /* register fragS * fragP; JF unused */
1915 register unsigned int c
;
1918 * The following awkward logic is to parse ZERO or more strings,
1919 * comma seperated. Recall a string expression includes spaces
1920 * before the opening '\"' and spaces after the closing '\"'.
1921 * We fake a leading ',' if there is (supposed to be)
1922 * a 1st, expression. We keep demanding expressions for each
1925 if (is_it_end_of_statement())
1927 c
= 0; /* Skip loop. */
1928 ++ input_line_pointer
; /* Compensate for end of loop. */
1932 c
= ','; /* Do loop. */
1934 while (c
== ',' || c
== '<' || c
== '"' ) {
1936 switch (*input_line_pointer
) {
1938 ++input_line_pointer
; /*->1st char of string. */
1939 while (is_a_char(c
= next_char_of_string())) {
1940 FRAG_APPEND_1_CHAR(c
);
1943 FRAG_APPEND_1_CHAR(0);
1945 know(input_line_pointer
[-1] == '\"');
1948 input_line_pointer
++;
1949 c
=get_single_number();
1950 FRAG_APPEND_1_CHAR(c
);
1951 if(*input_line_pointer
!= '>') {
1952 as_bad("Expected <nn>");
1954 input_line_pointer
++;
1957 input_line_pointer
++;
1961 c
= *input_line_pointer
;
1964 demand_empty_rest_of_line();
1967 /* FIXME-SOMEDAY: I had trouble here on characters with the
1968 high bits set. We'll probably also have trouble with
1969 multibyte chars, wide chars, etc. Also be careful about
1970 returning values bigger than 1 byte. xoxorich. */
1972 unsigned int next_char_of_string() {
1973 register unsigned int c
;
1975 c
= *input_line_pointer
++ & CHAR_MASK
;
1982 switch (c
= *input_line_pointer
++) {
2011 break; /* As itself. */
2025 for (number
= 0; isdigit(c
); c
= *input_line_pointer
++) {
2026 number
= number
* 8 + c
- '0';
2030 --input_line_pointer
;
2034 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2035 as_warn("Unterminated string: Newline inserted.");
2041 #ifdef ONLY_STANDARD_ESCAPES
2042 as_bad("Bad escaped character in string, '?' assumed");
2044 #endif /* ONLY_STANDARD_ESCAPES */
2047 } /* switch on escaped char */
2052 } /* switch on char */
2054 } /* next_char_of_string() */
2057 get_segmented_expression (expP
)
2058 register expressionS
* expP
;
2060 register segT retval
;
2062 if ((retval
= expression(expP
)) == SEG_PASS1
|| retval
== SEG_ABSENT
|| retval
== SEG_BIG
)
2064 as_bad("Expected address expression: absolute 0 assumed");
2065 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
2066 expP
->X_add_number
= 0;
2067 expP
->X_add_symbol
= expP
->X_subtract_symbol
= 0;
2069 return (retval
); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
2072 static segT
get_known_segmented_expression(expP
)
2073 register expressionS
*expP
;
2075 register segT retval
;
2076 register char * name1
;
2077 register char * name2
;
2079 if ((retval
= get_segmented_expression (expP
)) == SEG_UNKNOWN
)
2081 name1
= expP
->X_add_symbol
? S_GET_NAME(expP
->X_add_symbol
) : "";
2082 name2
= expP
->X_subtract_symbol
?
2083 S_GET_NAME(expP
->X_subtract_symbol
) :
2087 as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2092 as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
2093 name1
? name1
: name2
);
2095 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
2096 expP
->X_add_number
= 0;
2097 expP
->X_add_symbol
= expP
->X_subtract_symbol
= NULL
;
2099 #ifndef MANY_SEGMENTS
2100 know(retval
== SEG_ABSOLUTE
|| retval
== SEG_DATA
|| retval
== SEG_TEXT
|| retval
== SEG_BSS
|| retval
== SEG_DIFFERENCE
);
2104 } /* get_known_segmented_expression() */
2108 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
2109 get_absolute_expression ()
2114 if ((s
= expression(& exp
)) != SEG_ABSOLUTE
)
2116 if (s
!= SEG_ABSENT
)
2118 as_bad("Bad Absolute Expression, absolute 0 assumed.");
2120 exp
. X_add_number
= 0;
2122 return (exp
. X_add_number
);
2125 char /* return terminator */
2126 get_absolute_expression_and_terminator(val_pointer
)
2127 long * val_pointer
; /* return value of expression */
2129 * val_pointer
= get_absolute_expression ();
2130 return (* input_line_pointer
++);
2134 * demand_copy_C_string()
2136 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2137 * Give a warning if that happens.
2140 demand_copy_C_string (len_pointer
)
2145 if ((s
= demand_copy_string(len_pointer
)) != 0)
2149 for (len
= * len_pointer
;
2158 as_bad("This string may not contain \'\\0\'");
2166 * demand_copy_string()
2168 * Demand string, but return a safe (=private) copy of the string.
2169 * Return NULL if we can't read a string here.
2171 static char *demand_copy_string(lenP
)
2174 register unsigned int c
;
2180 if (*input_line_pointer
== '\"') {
2181 input_line_pointer
++; /* Skip opening quote. */
2183 while (is_a_char(c
= next_char_of_string())) {
2184 obstack_1grow(¬es
, c
);
2187 /* JF this next line is so demand_copy_C_string will return a null
2188 termanated string. */
2189 obstack_1grow(¬es
,'\0');
2190 retval
=obstack_finish(¬es
);
2192 as_warn("Missing string");
2194 ignore_rest_of_line();
2198 } /* demand_copy_string() */
2201 * is_it_end_of_statement()
2203 * In: Input_line_pointer->next character.
2205 * Do: Skip input_line_pointer over all whitespace.
2207 * Out: 1 if input_line_pointer->end-of-line.
2209 int is_it_end_of_statement() {
2211 return (is_end_of_line
[* input_line_pointer
]);
2212 } /* is_it_end_of_statement() */
2214 void equals(sym_name
)
2217 register symbolS
*symbolP
; /* symbol we are working with */
2219 input_line_pointer
++;
2220 if (*input_line_pointer
=='=')
2221 input_line_pointer
++;
2223 while(*input_line_pointer
==' ' || *input_line_pointer
=='\t')
2224 input_line_pointer
++;
2226 if (sym_name
[0]=='.' && sym_name
[1]=='\0') {
2227 /* Turn '. = mumble' into a .org mumble */
2228 register segT segment
;
2232 segment
= get_known_segmented_expression(& exp
);
2233 if (! need_pass_2
) {
2234 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
2235 as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
2236 segment_name(segment
),
2237 segment_name(now_seg
));
2238 p
= frag_var(rs_org
, 1, 1, (relax_substateT
)0, exp
.X_add_symbol
,
2239 exp
.X_add_number
, (char *)0);
2241 } /* if (ok to make frag) */
2243 symbolP
=symbol_find_or_make(sym_name
);
2244 pseudo_set(symbolP
);
2248 /* .include -- include a file at this point. */
2260 filename
= demand_copy_string(&i
);
2261 demand_empty_rest_of_line();
2262 path
= xmalloc(i
+ include_dir_maxlen
+ 5 /* slop */);
2263 for (i
= 0; i
< include_dir_count
; i
++) {
2264 strcpy(path
, include_dirs
[i
]);
2266 strcat(path
, filename
);
2267 if (0 != (try = fopen(path
, "r")))
2276 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2277 newbuf
= input_scrub_include_file (path
, input_line_pointer
);
2278 buffer_limit
= input_scrub_next_buffer (&input_line_pointer
);
2281 void add_include_dir(path
)
2286 if (include_dir_count
== 0)
2288 include_dirs
= (char **)xmalloc (2 * sizeof (*include_dirs
));
2289 include_dirs
[0] = "."; /* Current dir */
2290 include_dir_count
= 2;
2294 include_dir_count
++;
2295 include_dirs
= (char **) realloc(include_dirs
,
2296 include_dir_count
*sizeof (*include_dirs
));
2299 include_dirs
[include_dir_count
-1] = path
; /* New one */
2302 if (i
> include_dir_maxlen
)
2303 include_dir_maxlen
= i
;
2304 } /* add_include_dir() */
2309 extern char is_end_of_line
[];
2311 while (!is_end_of_line
[*input_line_pointer
]) {
2312 ++input_line_pointer
;
2314 ++input_line_pointer
;