1 /* read.c - read a source file -
2 Copyright (C) 1986, 1987, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* static const char rcsid[] = "$Id$"; */
22 #define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
23 change this a bit. But then, GNU isn't
24 spozed to run on your machine anyway.
25 (RMS is so shortsighted sometimes.)
28 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
29 /* This is the largest known floating point */
30 /* format (for now). It will grow when we */
31 /* do 4361 style flonums. */
34 /* Routines that read assembler source text to build spagetti in memory. */
35 /* Another group of these functions is in the as-expr.c module */
41 char *input_line_pointer; /*->next char of source file to parse. */
44 #if BITS_PER_CHAR != 8
45 The following table is indexed by [ (char) ] and will break if
46 a char does not have exactly 256 states (hopefully 0:255!) !
49 const char /* used by is_... macros. our ctype[] */
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
53 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
54 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
55 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
56 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
57 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
58 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
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,
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
71 * Out: 1 if this character ends a line.
74 char is_end_of_line [256] = {
76 _, _, _, _, _, _, _, _, _, _,99, _, _, 99, _, _,/* @abcdefghijklmno */
78 _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, _, /* @abcdefghijklmno */
80 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
81 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
82 _, _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, /* 0123456789:;<=>? */
83 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
84 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
85 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
86 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
87 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
88 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
89 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
90 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
91 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ /* */
95 /* Functions private to this file. */
97 char line_comment_chars[1];
98 char line_separator_chars[1];
100 static char *buffer; /* 1st char of each buffer of lines is here. */
101 static char *buffer_limit; /*->1 + last char in buffer. */
103 static char *bignum_low; /* Lowest char of bignum. */
104 static char *bignum_limit; /* 1st illegal address of bignum. */
105 static char *bignum_high; /* Highest char of bignum. */
106 /* May point to (bignum_start-1). */
107 /* Never >= bignum_limit. */
108 static char *old_buffer = 0; /* JF a hack */
109 static char *old_input;
110 static char *old_limit;
112 /* Variables for handling include file directory list. */
114 char **include_dirs; /* List of pointers to directories to
115 search for .include's */
116 int include_dir_count; /* How many are in the list */
117 int include_dir_maxlen = 1; /* Length of longest in list */
119 #ifndef WORKING_DOT_WORD
120 struct broken_word *broken_words;
121 int new_broken_words = 0;
126 static char *demand_copy_string(int *lenP);
127 static int is_it_end_of_statement(void);
128 static unsigned int next_char_of_string(void);
129 static segT get_known_segmented_expression(expressionS *expP);
130 static void grow_bignum(void);
131 static void pobegin(void);
132 static void stringer(int append_zero);
136 static char *demand_copy_string();
137 static int is_it_end_of_statement();
138 static unsigned int next_char_of_string();
139 static segT get_known_segmented_expression();
140 static void grow_bignum();
141 static void pobegin();
142 static void stringer();
144 #endif /* __STDC__ */
153 obj_read_begin_hook();
155 obstack_begin(¬es, 5000);
156 /* Start off assuming that we won't need more than 20 levels
157 of .if/.endif; if we need more, we can always get it. */
158 obstack_begin (&cond_obstack, 20);
159 /* We start life accepting input. */
160 obstack_1grow (&cond_obstack, 1);
162 #define BIGNUM_BEGIN_SIZE (16)
163 bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);
164 bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
166 /* Use machine dependent syntax */
167 for (p = line_separator_chars; *p; p++)
168 is_end_of_line[*p] = 1;
169 /* Use more. FIXME-SOMEDAY. */
172 /* set up pseudo-op tables */
174 struct hash_control *
175 po_hash = NULL; /* use before set up: NULL->address error */
178 void s_gdbline(), s_gdblinetab();
179 void s_gdbbeg(), s_gdbblock(), s_gdbend(), s_gdbsym();
182 static const pseudo_typeS
185 { "abort", s_abort, 0 },
186 { "align", s_align_ptwo, 0 },
187 { "ascii", stringer, 0 },
188 { "asciz", stringer, 1 },
191 { "comm", s_comm, 0 },
192 { "data", s_data, 0 },
194 { "double", float_cons, 'd' },
196 { "eject", s_ignore, 0 }, /* Formfeed listing */
197 { "else", s_else, 0 },
199 { "endif", s_endif, 0 },
204 { "extern", s_ignore, 0 }, /* We treat all undef as ext */
205 { "app-file", s_app_file, 0 },
206 { "file", s_app_file, 0 },
207 { "fill", s_fill, 0 },
208 { "float", float_cons, 'f' },
210 { "gdbbeg", s_gdbbeg, 0 },
211 { "gdbblock", s_gdbblock, 0 },
212 { "gdbend", s_gdbend, 0 },
213 { "gdbsym", s_gdbsym, 0 },
214 { "gdbline", s_gdbline, 0 },
215 { "gdblinetab",s_gdblinetab, 0 },
217 { "global", s_globl, 0 },
218 { "globl", s_globl, 0 },
219 { "hword", cons, 2 },
221 { "ifdef", s_ifdef, 0 },
222 { "ifeqs", s_ifeqs, 0 },
223 { "ifndef", s_ifdef, 1 },
224 { "ifnes", s_ifeqs, 1 },
225 { "ifnotdef", s_ifdef, 1 },
226 { "include", s_include, 0 },
228 { "lcomm", s_lcomm, 0 },
229 { "lflags", s_ignore, 0 }, /* Listing flags */
230 { "list", s_ignore, 0 }, /* Turn listing on */
232 { "lsym", s_lsym, 0 },
233 { "nolist", s_ignore, 0 }, /* Turn listing off */
234 { "octa", big_cons, 16 },
237 { "quad", big_cons, 8 },
238 { "sbttl", s_ignore, 0 }, /* Subtitle of listing */
242 { "short", cons, 2 },
243 { "single", float_cons, 'f' },
245 { "space", s_space, 0 },
247 { "text", s_text, 0 },
248 { "title", s_ignore, 0 }, /* Listing title */
253 { NULL} /* end sentinel */
256 static void pobegin() {
257 char * errtxt; /* error text */
258 const pseudo_typeS * pop;
260 po_hash = hash_new();
262 /* Do the target-specific pseudo ops. */
263 for (pop=md_pseudo_table; pop->poc_name; pop++) {
264 errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
265 if (errtxt && *errtxt) {
266 as_fatal("error constructing md pseudo-op table");
270 /* Now object specific. Skip any that were in the target table. */
271 for (pop=obj_pseudo_table; pop->poc_name; pop++) {
272 errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
273 if (errtxt && *errtxt) {
274 if (!strcmp (errtxt, "exists")) {
275 #ifdef DIE_ON_OVERRIDES
276 as_fatal("pseudo op \".%s\" overridden.\n", pop->poc_name);
277 #endif /* DIE_ON_OVERRIDES */
278 continue; /* OK if target table overrides. */
280 as_fatal("error constructing obj pseudo-op table");
281 } /* if overridden */
285 /* Now portable ones. Skip any that we've seen already. */
286 for (pop=potable; pop->poc_name; pop++) {
287 errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
288 if (errtxt && *errtxt) {
289 if (!strcmp (errtxt, "exists")) {
290 #ifdef DIE_ON_OVERRIDES
291 as_fatal("pseudo op \".%s\" overridden.\n", pop->poc_name);
292 #endif /* DIE_ON_OVERRIDES */
293 continue; /* OK if target table overrides. */
295 as_fatal("error constructing obj pseudo-op table");
296 } /* if overridden */
303 #define HANDLE_CONDITIONAL_ASSEMBLY() \
304 if (ignore_input ()) \
306 while (! is_end_of_line[*input_line_pointer++]) \
307 if (input_line_pointer == buffer_limit) \
312 /* read_a_source_file()
314 * We read the file, putting things into a web that
315 * represents what we have been reading.
317 void read_a_source_file(name)
321 register char * s; /* string of symbol, '\0' appended */
323 /* register struct frag * fragP; JF unused */ /* a frag we just made */
326 void gdb_block_beg();
327 void gdb_block_position();
328 void gdb_block_end();
329 void gdb_symbols_fixup();
332 buffer = input_scrub_new_file(name);
334 while ((buffer_limit = input_scrub_next_buffer(&input_line_pointer)) != 0) { /* We have another line to parse. */
335 know(buffer_limit[-1] == '\n'); /* Must have a sentinel. */
336 contin: /* JF this goto is my fault I admit it. Someone brave please re-write
337 the whole input section here? Pleeze??? */
338 while (input_line_pointer < buffer_limit) { /* We have more of this buffer to parse. */
340 * We now have input_line_pointer->1st char of next line.
341 * If input_line_pointer [-1] == '\n' then we just
342 * scanned another line: so bump line counters.
344 if (input_line_pointer[-1] == '\n') {
345 bump_line_counters();
346 } /* just passed a newline */
348 * We are at the begining of a line, or similar place.
349 * We expect a well-formed assembler statement.
350 * A "symbol-name:" is a statement.
352 * Depending on what compiler is used, the order of these tests
353 * may vary to catch most common case 1st.
354 * Each test is independent of all other tests at the (top) level.
355 * PLEASE make a compiler that doesn't use this assembler.
356 * It is crufty to waste a compiler's time encoding things for this
357 * assembler, which then wastes more time decoding it.
358 * (And communicating via (linear) files is silly!
359 * If you must pass stuff, please pass a tree!)
361 if ((c = *input_line_pointer++) == '\t' || c == ' ' || c=='\f') {
362 c = *input_line_pointer++;
364 know(c != ' '); /* No further leading whitespace. */
366 * C is the 1st significant character.
367 * Input_line_pointer points after that character.
369 if (is_name_beginner(c)) { /* want user-defined label or pseudo/opcode */
370 HANDLE_CONDITIONAL_ASSEMBLY();
372 s = --input_line_pointer;
373 c = get_symbol_end(); /* name's delimiter */
375 * C is character after symbol.
376 * That character's place in the input line is now '\0'.
377 * S points to the beginning of the symbol.
378 * [In case of pseudo-op, s->'.'.]
379 * Input_line_pointer->'\0' where c was.
382 colon(s); /* user-defined label */
383 * input_line_pointer ++ = ':'; /* Put ':' back for error messages' sake. */
384 /* Input_line_pointer->after ':'. */
386 } else if (c == '=' || input_line_pointer[1] == '=') { /* JF deal with FOO=BAR */
388 demand_empty_rest_of_line();
389 } else { /* expect pseudo-op or machine instruction */
394 * WARNING: c has next char, which may be end-of-line.
395 * We lookup the pseudo-op table with s+1 because we
396 * already know that the pseudo-op begins with a '.'.
399 pop = (pseudo_typeS *) hash_find(po_hash, s+1);
401 /* Print the error msg now, while we still can */
403 as_bad("Unknown pseudo-op: `%s'",s);
404 *input_line_pointer = c;
409 /* Put it back for error messages etc. */
410 *input_line_pointer = c;
411 /* The following skip of whitespace is compulsory. */
412 /* A well shaped space is sometimes all that separates keyword from operands. */
413 if (c == ' ' || c == '\t') {
414 input_line_pointer++;
415 } /* Skip seperator after keyword. */
417 * Input_line is restored.
418 * Input_line_pointer->1st non-blank char
419 * after pseudo-operation.
422 ignore_rest_of_line();
425 (*pop->poc_handler)(pop->poc_val);
426 } /* if we have one */
427 } else { /* machine instruction */
428 /* WARNING: c has char, which may be end-of-line. */
429 /* Also: input_line_pointer->`\0` where c was. */
430 * input_line_pointer = c;
431 while (!is_end_of_line[*input_line_pointer]) {
432 input_line_pointer++;
434 c = *input_line_pointer;
435 *input_line_pointer = '\0';
436 md_assemble(s); /* Assemble 1 instruction. */
437 *input_line_pointer++ = c;
438 /* We resume loop AFTER the end-of-line from this instruction */
442 } /* if (is_name_beginner(c) */
445 if (is_end_of_line [c]) {
447 } /* empty statement */
449 if (isdigit(c)) { /* local label ("4:") */
450 HANDLE_CONDITIONAL_ASSEMBLY ();
453 #ifdef LOCAL_LABELS_DOLLAR
454 if (*input_line_pointer=='$')
455 input_line_pointer++;
457 if (* input_line_pointer ++ == ':')
463 as_bad("Spurious digit %d.", temp);
464 input_line_pointer -- ;
465 ignore_rest_of_line();
468 } /* local label ("4:") */
470 if (c && strchr(line_comment_chars,c)) { /* Its a comment. Better say APP or NO_APP */
476 extern char *scrub_string,*scrub_last_string;
478 bump_line_counters();
479 s=input_line_pointer;
480 if (strncmp(s,"APP\n",4))
481 continue; /* We ignore it */
484 ends=strstr(s,"#NO_APP\n");
490 /* The end of the #APP wasn't in this buffer. We
491 keep reading in buffers until we find the #NO_APP
492 that goes with this #APP There is one. The specs
494 tmp_len=buffer_limit-s;
495 tmp_buf=xmalloc(tmp_len);
496 bcopy(s,tmp_buf,tmp_len);
498 new_tmp = input_scrub_next_buffer(&buffer);
502 buffer_limit = new_tmp;
503 input_line_pointer = buffer;
504 ends = strstr(buffer,"#NO_APP\n");
508 num=buffer_limit-buffer;
510 tmp_buf = xrealloc(tmp_buf, tmp_len + num);
511 bcopy(buffer,tmp_buf+tmp_len,num);
515 input_line_pointer= ends ? ends+8 : NULL;
521 input_line_pointer=ends+8;
523 new_buf=xmalloc(100);
528 scrub_last_string = ends;
532 ch = do_scrub_next_char(scrub_from_string, scrub_to_string);
535 if (new_tmp==new_buf+new_length) {
536 new_buf=xrealloc(new_buf,new_length+100);
537 new_tmp=new_buf+new_length;
545 old_input=input_line_pointer;
546 old_limit=buffer_limit;
548 input_line_pointer=new_buf;
549 buffer_limit=new_tmp;
553 HANDLE_CONDITIONAL_ASSEMBLY();
555 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
556 input_line_pointer--; /* Report unknown char as ignored. */
557 ignore_rest_of_line();
558 } /* while (input_line_pointer<buffer_limit) */
560 bump_line_counters();
561 if (old_input != 0) {
563 input_line_pointer=old_input;
564 buffer_limit=old_limit;
569 } /* while (more buffers to scan) */
570 input_scrub_close(); /* Close the input file */
571 } /* read_a_source_file() */
574 as_fatal(".abort detected. Abandoning ship.");
577 /* For machines where ".align 4" means align to a 4 byte boundary. */
578 void s_align_bytes(arg)
581 register unsigned int temp;
582 register long temp_fill;
584 unsigned long max_alignment = 1 << 15;
586 if (is_end_of_line[*input_line_pointer])
587 temp = arg; /* Default value from pseudo-op table */
589 temp = get_absolute_expression ();
591 if (temp > max_alignment) {
592 as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
596 * For the sparc, `.align (1<<n)' actually means `.align n'
597 * so we have to convert it.
600 for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
604 as_bad("Alignment not a power of 2");
607 if (*input_line_pointer == ',') {
608 input_line_pointer ++;
609 temp_fill = get_absolute_expression ();
613 /* Only make a frag if we HAVE to. . . */
614 if (temp && ! need_pass_2)
615 frag_align(temp, (int)temp_fill);
617 demand_empty_rest_of_line();
618 } /* s_align_bytes() */
620 /* For machines where ".align 4" means align to 2**4 boundary. */
621 void s_align_ptwo() {
623 register long temp_fill;
624 long max_alignment = 15;
626 temp = get_absolute_expression ();
627 if (temp > max_alignment)
628 as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
630 as_bad("Alignment negative. 0 assumed.");
633 if (*input_line_pointer == ',') {
634 input_line_pointer ++;
635 temp_fill = get_absolute_expression ();
638 /* Only make a frag if we HAVE to. . . */
639 if (temp && ! need_pass_2)
640 frag_align (temp, (int)temp_fill);
642 record_alignment(now_seg, temp);
644 demand_empty_rest_of_line();
645 } /* s_align_ptwo() */
652 register symbolS * symbolP;
654 name = input_line_pointer;
655 c = get_symbol_end();
656 /* just after name is now '\0' */
657 p = input_line_pointer;
660 if (*input_line_pointer != ',') {
661 as_bad("Expected comma after symbol-name: rest of line ignored.");
662 ignore_rest_of_line();
665 input_line_pointer ++; /* skip ',' */
666 if ((temp = get_absolute_expression()) < 0) {
667 as_warn(".COMMon length (%d.) <0! Ignored.", temp);
668 ignore_rest_of_line();
672 symbolP = symbol_find_or_make(name);
674 if (S_IS_DEFINED(symbolP)) {
675 as_bad("Ignoring attempt to re-define symbol");
676 ignore_rest_of_line();
679 if (S_GET_VALUE(symbolP)) {
680 if (S_GET_VALUE(symbolP) != temp)
681 as_bad("Length of .comm \"%s\" is already %d. Not changed to %d.",
683 S_GET_VALUE(symbolP),
686 S_SET_VALUE(symbolP, temp);
687 S_SET_EXTERNAL(symbolP);
691 symbolP->sy_other = const_flag;
693 know(symbolP->sy_frag == &zero_address_frag);
694 demand_empty_rest_of_line();
702 temp = get_absolute_expression ();
703 subseg_new (SEG_DATA, (subsegT)temp);
707 demand_empty_rest_of_line();
714 /* Some assemblers tolerate immediately following '"' */
715 if ((s = demand_copy_string(&length)) != 0) {
716 new_logical_line(s, -1);
717 demand_empty_rest_of_line();
720 c_dot_file_symbol(s);
721 #endif /* OBJ_COFF */
727 register long temp_fill;
730 if (get_absolute_expression_and_terminator(& temp_repeat) != ',') {
731 input_line_pointer --; /* Backup over what was not a ','. */
732 as_bad("Expect comma after rep-size in .fill:");
733 ignore_rest_of_line();
736 if (get_absolute_expression_and_terminator(& temp_size) != ',') {
737 input_line_pointer --; /* Backup over what was not a ','. */
738 as_bad("Expected comma after size in .fill");
739 ignore_rest_of_line();
743 * This is to be compatible with BSD 4.2 AS, not for any rational reason.
745 #define BSD_FILL_SIZE_CROCK_8 (8)
746 if (temp_size > BSD_FILL_SIZE_CROCK_8) {
747 as_bad(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
748 temp_size = BSD_FILL_SIZE_CROCK_8 ;
749 } if (temp_size < 0) {
750 as_warn("Size negative: .fill ignored.");
752 } else if (temp_repeat <= 0) {
753 as_warn("Repeat < 0, .fill ignored");
756 temp_fill = get_absolute_expression ();
757 if (temp_size && !need_pass_2) {
758 p = frag_var(rs_fill, (int)temp_size, (int)temp_size, (relax_substateT)0, (symbolS *)0, temp_repeat, (char *)0);
759 bzero (p, (int)temp_size);
761 * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
762 * The following bizzare behaviour is to be compatible with above.
763 * I guess they tried to take up to 8 bytes from a 4-byte expression
764 * and they forgot to sign extend. Un*x Sux.
766 #define BSD_FILL_SIZE_CROCK_4 (4)
767 md_number_to_chars (p, temp_fill, temp_size > BSD_FILL_SIZE_CROCK_4 ? BSD_FILL_SIZE_CROCK_4 : (int)temp_size);
769 * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
770 * but emits no error message because it seems a legal thing to do.
771 * It is a degenerate case of .fill but could be emitted by a compiler.
774 demand_empty_rest_of_line();
783 temp = get_absolute_expression ();
785 as_warn("Block number <0. Ignored.");
786 else if (flagseen ['G'])
787 gdb_block_beg ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
788 demand_empty_rest_of_line ();
794 register int position;
797 if (get_absolute_expression_and_terminator (&temp) != ',') {
798 as_bad("expected comma before position in .gdbblock");
799 --input_line_pointer;
800 ignore_rest_of_line ();
803 position = get_absolute_expression ();
805 gdb_block_position ((long) temp, (long) position);
806 demand_empty_rest_of_line ();
814 temp = get_absolute_expression ();
816 as_warn("Block number <0. Ignored.");
817 else if (flagseen ['G'])
818 gdb_block_end ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
819 demand_empty_rest_of_line ();
828 register symbolS * symbolP;
831 name = input_line_pointer;
832 c = get_symbol_end();
833 p = input_line_pointer;
834 symbolP = symbol_find_or_make(name);
837 if (* input_line_pointer != ',') {
838 as_bad("Expected comma after name");
839 ignore_rest_of_line();
842 input_line_pointer ++;
843 if ((temp = get_absolute_expression ()) < 0) {
844 as_bad("Bad GDB symbol file offset (%d.) <0! Ignored.", temp);
845 ignore_rest_of_line();
849 gdb_symbols_fixup (symbolP, (long)temp);
850 demand_empty_rest_of_line ();
859 if (get_absolute_expression_and_terminator(&file_number) != ',') {
860 as_bad("expected comman after filenum in .gdbline");
861 ignore_rest_of_line();
864 lineno=get_absolute_expression();
866 gdb_line(file_number,lineno);
867 demand_empty_rest_of_line();
877 if (get_absolute_expression_and_terminator(&file_number) != ',') {
878 as_bad("expected comma after filenum in .gdblinetab");
879 ignore_rest_of_line();
882 offset=get_absolute_expression();
884 gdb_line_tab(file_number,offset);
885 demand_empty_rest_of_line();
892 register symbolS * symbolP;
895 name = input_line_pointer;
896 c = get_symbol_end();
897 symbolP = symbol_find_or_make(name);
898 * input_line_pointer = c;
900 S_SET_EXTERNAL(symbolP);
902 input_line_pointer++;
904 if (*input_line_pointer=='\n')
908 demand_empty_rest_of_line();
911 void s_lcomm(needs_align)
912 int needs_align; /* 1 if this was a ".bss" directive, which may require
913 * a 3rd argument (alignment).
914 * 0 if it was an ".lcomm" (2 args only)
921 register symbolS * symbolP;
922 const int max_alignment = 15;
925 name = input_line_pointer;
926 c = get_symbol_end();
927 p = input_line_pointer;
930 if (* input_line_pointer != ',') {
931 as_bad("Expected comma after name");
932 ignore_rest_of_line();
935 input_line_pointer ++;
937 if (*input_line_pointer == '\n') {
938 as_bad("Missing size expression");
942 if ((temp = get_absolute_expression ()) < 0) {
943 as_warn("BSS length (%d.) <0! Ignored.", temp);
944 ignore_rest_of_line();
951 if (*input_line_pointer != ',') {
952 as_bad("Expected comma after size");
953 ignore_rest_of_line();
956 input_line_pointer++;
958 if (*input_line_pointer == '\n') {
959 as_bad("Missing alignment");
962 align = get_absolute_expression ();
963 if (align > max_alignment){
964 align = max_alignment;
965 as_warn("Alignment too large: %d. assumed.", align);
966 } else if (align < 0) {
968 as_warn("Alignment negative. 0 assumed.");
971 record_alignment(SEG_BSS, align);
972 } /* if needs align */
975 symbolP = symbol_find_or_make(name);
978 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
979 S_GET_OTHER(symbolP) == 0 &&
980 S_GET_DESC(symbolP) == 0 &&
981 #endif /* OBJ_AOUT or OBJ_BOUT */
982 (((S_GET_SEGMENT(symbolP) == SEG_BSS) && (S_GET_VALUE(symbolP) == local_bss_counter))
983 || (!S_IS_DEFINED(symbolP) && S_GET_VALUE(symbolP) == 0))) {
986 align = ~ ((~0) << align); /* Convert to a mask */
988 (local_bss_counter + align) & (~align);
991 S_SET_VALUE(symbolP,local_bss_counter);
992 S_SET_SEGMENT(symbolP, SEG_BSS);
994 /* The symbol may already have been created with a preceding
995 * ".globl" directive -- be careful not to step on storage
996 * class in that case. Otherwise, set it to static.
998 if (S_GET_STORAGE_CLASS(symbolP) != C_EXT){
999 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1001 #endif /* OBJ_COFF */
1002 symbolP->sy_frag = & bss_address_frag;
1003 local_bss_counter += temp;
1005 as_bad("Ignoring attempt to re-define symbol from %d. to %d.",
1006 S_GET_VALUE(symbolP), local_bss_counter);
1008 demand_empty_rest_of_line();
1026 register char *name;
1029 register segT segment;
1031 register symbolS *symbolP;
1033 /* we permit ANY defined expression: BSD4.2 demands constants */
1034 name = input_line_pointer;
1035 c = get_symbol_end();
1036 p = input_line_pointer;
1039 if (* input_line_pointer != ',') {
1041 as_bad("Expected comma after name \"%s\"", name);
1043 ignore_rest_of_line();
1046 input_line_pointer ++;
1047 segment = expression(& exp);
1048 if (segment != SEG_ABSOLUTE
1049 && segment != SEG_DATA
1050 && segment != SEG_TEXT
1051 && segment != SEG_BSS
1052 && segment != SEG_REGISTER) {
1053 as_bad("Bad expression: %s", segment_name(segment));
1054 ignore_rest_of_line();
1058 symbolP = symbol_find_or_make(name);
1060 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0
1061 && symbolP->sy_desc == 0) out of this test
1062 because coff doesn't have those fields, and I
1063 can't see when they'd ever be tripped. I don't
1064 think I understand why they were here so I may
1065 have introduced a bug. As recently as 1.37 didn't
1066 have this test anyway. xoxorich. */
1068 if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN
1069 && S_GET_VALUE(symbolP) == 0) {
1070 /* The name might be an undefined .global symbol; be
1071 sure to keep the "external" bit. */
1072 S_SET_SEGMENT(symbolP, segment);
1073 S_SET_VALUE(symbolP, (valueT)(exp.X_add_number));
1075 as_bad("Symbol %s already defined", name);
1078 demand_empty_rest_of_line();
1082 register segT segment;
1084 register long temp_fill;
1087 * Don't believe the documentation of BSD 4.2 AS.
1088 * There is no such thing as a sub-segment-relative origin.
1089 * Any absolute origin is given a warning, then assumed to be segment-relative.
1090 * Any segmented origin expression ("foo+42") had better be in the right
1091 * segment or the .org is ignored.
1093 * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
1094 * never know sub-segment sizes when we are reading code.
1095 * BSD will crash trying to emit -ve numbers of filler bytes in certain
1096 * .orgs. We don't crash, but see as-write for that code.
1099 * Don't make frag if need_pass_2==1.
1101 segment = get_known_segmented_expression(&exp);
1102 if (*input_line_pointer == ',') {
1103 input_line_pointer ++;
1104 temp_fill = get_absolute_expression ();
1107 if (! need_pass_2) {
1108 if (segment != now_seg && segment != SEG_ABSOLUTE)
1109 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1110 segment_name(segment), segment_name(now_seg));
1111 p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
1112 exp . X_add_number, (char *)0);
1114 } /* if (ok to make frag) */
1115 demand_empty_rest_of_line();
1119 register char *name;
1120 register char delim;
1121 register char *end_name;
1122 register symbolS *symbolP;
1125 * Especial apologies for the random logic:
1126 * this just grew, and could be parsed much more simply!
1129 name = input_line_pointer;
1130 delim = get_symbol_end();
1131 end_name = input_line_pointer;
1135 if (*input_line_pointer != ',') {
1137 as_bad("Expected comma after name \"%s\"", name);
1139 ignore_rest_of_line();
1143 input_line_pointer ++;
1146 if (name[0]=='.' && name[1]=='\0') {
1147 /* Turn '. = mumble' into a .org mumble */
1148 register segT segment;
1152 segment = get_known_segmented_expression(& exp);
1155 if (segment != now_seg && segment != SEG_ABSOLUTE)
1156 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1157 segment_name(segment),
1158 segment_name (now_seg));
1159 ptr = frag_var(rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
1160 exp.X_add_number, (char *)0);
1162 } /* if (ok to make frag) */
1168 if ((symbolP = symbol_find(name)) == NULL
1169 && (symbolP = md_undefined_symbol(name)) == NULL) {
1170 symbolP = symbol_new(name,
1173 &zero_address_frag);
1175 /* "set" symbols are local unless otherwise specified. */
1176 SF_SET_LOCAL(symbolP);
1177 #endif /* OBJ_COFF */
1179 } /* make a new symbol */
1181 symbol_table_insert(symbolP);
1184 pseudo_set(symbolP);
1185 demand_empty_rest_of_line();
1190 register long temp_fill;
1193 /* Just like .fill, but temp_size = 1 */
1194 if (get_absolute_expression_and_terminator(& temp_repeat) == ',') {
1195 temp_fill = get_absolute_expression ();
1197 input_line_pointer --; /* Backup over what was not a ','. */
1200 if (temp_repeat <= 0) {
1201 as_warn("Repeat < 0, .space ignored");
1202 ignore_rest_of_line();
1205 if (! need_pass_2) {
1206 p = frag_var (rs_fill, 1, 1, (relax_substateT)0, (symbolS *)0,
1207 temp_repeat, (char *)0);
1210 demand_empty_rest_of_line();
1218 temp = get_absolute_expression ();
1219 subseg_new (SEG_TEXT, (subsegT)temp);
1220 demand_empty_rest_of_line();
1224 /*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1226 void demand_empty_rest_of_line() {
1228 if (is_end_of_line [*input_line_pointer]) {
1229 input_line_pointer++;
1231 ignore_rest_of_line();
1233 /* Return having already swallowed end-of-line. */
1234 } /* Return pointing just after end-of-line. */
1237 ignore_rest_of_line() /* For suspect lines: gives warning. */
1239 if (! is_end_of_line [* input_line_pointer])
1241 if (isprint(*input_line_pointer))
1242 as_bad("Rest of line ignored. First ignored character is `%c'.",
1243 *input_line_pointer);
1245 as_bad("Rest of line ignored. First ignored character valued 0x%x.",
1246 *input_line_pointer);
1247 while (input_line_pointer < buffer_limit
1248 && ! is_end_of_line [* input_line_pointer])
1250 input_line_pointer ++;
1253 input_line_pointer ++; /* Return pointing just after end-of-line. */
1254 know(is_end_of_line [input_line_pointer [-1]]);
1260 * In: Pointer to a symbol.
1261 * Input_line_pointer->expression.
1263 * Out: Input_line_pointer->just after any whitespace after expression.
1264 * Tried to set symbol to value of expression.
1265 * Will change symbols type, value, and frag;
1266 * May set need_pass_2 == 1.
1269 pseudo_set (symbolP)
1273 register segT segment;
1274 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1276 #endif /* OBJ_AOUT or OBJ_BOUT */
1278 know(symbolP); /* NULL pointer is logic error. */
1279 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1280 ext=S_IS_EXTERNAL(symbolP);
1281 #endif /* OBJ_AOUT or OBJ_BOUT */
1283 if ((segment = expression(& exp)) == SEG_ABSENT)
1285 as_bad("Missing expression: absolute 0 assumed");
1286 exp . X_seg = SEG_ABSOLUTE;
1287 exp . X_add_number = 0;
1293 as_bad("%s number invalid. Absolute 0 assumed.",
1294 exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
1295 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
1296 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1297 ext ? S_SET_EXTERNAL(symbolP) :
1298 S_CLEAR_EXTERNAL(symbolP);
1299 #endif /* OBJ_AOUT or OBJ_BOUT */
1300 S_SET_VALUE(symbolP, 0);
1301 symbolP->sy_frag = & zero_address_frag;
1305 as_warn("No expression: Using absolute 0");
1306 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
1307 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1308 ext ? S_SET_EXTERNAL(symbolP) :
1309 S_CLEAR_EXTERNAL(symbolP);
1310 #endif /* OBJ_AOUT or OBJ_BOUT */
1311 S_SET_VALUE(symbolP, 0);
1312 symbolP->sy_frag = & zero_address_frag;
1315 case SEG_DIFFERENCE:
1316 if (exp.X_add_symbol && exp.X_subtract_symbol
1317 && (S_GET_SEGMENT(exp.X_add_symbol) ==
1318 S_GET_SEGMENT(exp.X_subtract_symbol))) {
1319 if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag) {
1320 as_bad("Unknown expression: symbols %s and %s are in different frags.",
1321 S_GET_NAME(exp.X_add_symbol), S_GET_NAME(exp.X_subtract_symbol));
1324 exp.X_add_number+=S_GET_VALUE(exp.X_add_symbol) -
1325 S_GET_VALUE(exp.X_subtract_symbol);
1327 as_bad("Complex expression. Absolute segment assumed.");
1329 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
1330 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1331 ext ? S_SET_EXTERNAL(symbolP) :
1332 S_CLEAR_EXTERNAL(symbolP);
1333 #endif /* OBJ_AOUT or OBJ_BOUT */
1334 S_SET_VALUE(symbolP, exp.X_add_number);
1335 symbolP->sy_frag = & zero_address_frag;
1342 case SEG_DATA: S_SET_SEGMENT(symbolP, SEG_DATA); break;
1343 case SEG_TEXT: S_SET_SEGMENT(symbolP, SEG_TEXT); break;
1344 case SEG_BSS: S_SET_SEGMENT(symbolP, SEG_BSS); break;
1346 } /* switch on segment */
1348 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1350 S_SET_EXTERNAL(symbolP);
1352 S_CLEAR_EXTERNAL(symbolP);
1354 #endif /* OBJ_AOUT or OBJ_BOUT */
1356 S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol));
1357 symbolP->sy_frag = exp . X_add_symbol->sy_frag;
1360 case SEG_PASS1: /* Not an error. Just try another pass. */
1361 symbolP->sy_forward=exp.X_add_symbol;
1362 as_bad("Unknown expression");
1363 know(need_pass_2 == 1);
1367 symbolP->sy_forward=exp.X_add_symbol;
1368 /* as_warn("unknown symbol"); */
1369 /* need_pass_2 = 1; */
1381 * CONStruct more frag of .bytes, or .words etc.
1382 * Should need_pass_2 be 1 then emit no frag(s).
1383 * This understands EXPRESSIONS, as opposed to big_cons().
1387 * This has a split personality. We use expression() to read the
1388 * value. We can detect if the value won't fit in a byte or word.
1389 * But we can't detect if expression() discarded significant digits
1390 * in the case of a long. Not worth the crocks required to fix it.
1393 /* worker to do .byte etc statements */
1394 /* clobbers input_line_pointer, checks */
1397 register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
1400 register long mask; /* High-order bits we will left-truncate, */
1401 /* but includes sign bit also. */
1402 register long get; /* what we get */
1403 register long use; /* get after truncation. */
1404 register long unmask; /* what bits we will store */
1406 register segT segment;
1410 * Input_line_pointer->1st char after pseudo-op-code and could legally
1411 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1413 /* JF << of >= number of bits in the object is undefined. In particular
1414 SPARC (Sun 4) has problems */
1416 if (nbytes>=sizeof(long)) {
1419 mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
1420 } /* bigger than a long */
1422 unmask = ~mask; /* Do store these bits. */
1425 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1426 mask = ~ (unmask >> 1); /* Includes sign bit now. */
1430 * The following awkward logic is to parse ZERO or more expressions,
1431 * comma seperated. Recall an expression includes its leading &
1432 * trailing blanks. We fake a leading ',' if there is (supposed to
1433 * be) a 1st expression, and keep demanding 1 expression for each ','.
1435 if (is_it_end_of_statement()) {
1436 c = 0; /* Skip loop. */
1437 input_line_pointer++; /* Matches end-of-loop 'correction'. */
1440 } /* if the end else fake it */
1444 unsigned int bits_available = BITS_PER_CHAR * nbytes;
1445 /* used for error messages and rescanning */
1446 char *hold = input_line_pointer;
1448 /* At least scan over the expression. */
1449 segment = expression(&exp);
1451 #ifdef WANT_BITFIELDS
1452 /* Some other assemblers, (eg, asm960), allow
1453 bitfields after ".byte" as w:x,y:z, where w and
1454 y are bitwidths and x and y are values. They
1455 then pack them all together. We do a little
1456 better in that we allow them in words, longs,
1457 etc. and we'll pack them in target byte order
1460 The rules are: pack least significat bit first,
1461 if a field doesn't entirely fit, put it in the
1462 next unit. Overflowing the bitfield is
1463 explicitly *not* even a warning. The bitwidth
1464 should be considered a "mask".
1466 FIXME-SOMEDAY: If this is considered generally
1467 useful, this logic should probably be reworked.
1470 if (*input_line_pointer == ':') { /* bitfields */
1474 unsigned long width;
1476 if (*input_line_pointer != ':') {
1477 input_line_pointer = hold;
1479 } /* next piece is not a bitfield */
1481 /* In the general case, we can't allow
1482 full expressions with symbol
1483 differences and such. The relocation
1484 entries for symbols not defined in this
1485 assembly would require arbitrary field
1486 widths, positions, and masks which most
1487 of our current object formats don't
1490 In the specific case where a symbol
1491 *is* defined in this assembly, we
1492 *could* build fixups and track it, but
1493 this could lead to confusion for the
1494 backends. I'm lazy. I'll take any
1495 SEG_ABSOLUTE. I think that means that
1496 you can use a previous .set or
1497 .equ type symbol. xoxorich. */
1499 if (segment == SEG_ABSENT) {
1500 as_warn("Using a bit field width of zero.");
1501 exp.X_add_number = 0;
1502 segment = SEG_ABSOLUTE;
1503 } /* implied zero width bitfield */
1505 if (segment != SEG_ABSOLUTE) {
1506 *input_line_pointer = '\0';
1507 as_bad("Field width \"%s\" too complex for a bitfield.\n", hold);
1508 *input_line_pointer = ':';
1509 demand_empty_rest_of_line();
1513 if ((width = exp.X_add_number) > (BITS_PER_CHAR * nbytes)) {
1514 as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1515 width, nbytes, (BITS_PER_CHAR * nbytes));
1516 width = BITS_PER_CHAR * nbytes;
1519 if (width > bits_available) {
1520 /* FIXME-SOMEDAY: backing up and
1521 reparsing is wasteful */
1522 input_line_pointer = hold;
1523 exp.X_add_number = value;
1527 hold = ++input_line_pointer; /* skip ':' */
1529 if ((segment = expression(&exp)) != SEG_ABSOLUTE) {
1530 char cache = *input_line_pointer;
1532 *input_line_pointer = '\0';
1533 as_bad("Field value \"%s\" too complex for a bitfield.\n", hold);
1534 *input_line_pointer = cache;
1535 demand_empty_rest_of_line();
1539 value |= (~(-1 << width) & exp.X_add_number)
1540 << ((BITS_PER_CHAR * nbytes) - bits_available);
1542 if ((bits_available -= width) == 0
1543 || is_it_end_of_statement()
1544 || *input_line_pointer != ',') {
1546 } /* all the bitfields we're gonna get */
1548 hold = ++input_line_pointer;
1549 segment = expression(&exp);
1550 } /* forever loop */
1552 exp.X_add_number = value;
1553 segment = SEG_ABSOLUTE;
1554 } /* if looks like a bitfield */
1555 #endif /* WANT_BITFIELDS */
1557 if (!need_pass_2) { /* Still worthwhile making frags. */
1559 /* Don't call this if we are going to junk this pass anyway! */
1560 know(segment != SEG_PASS1);
1562 if (segment == SEG_DIFFERENCE && exp.X_add_symbol == NULL) {
1563 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1564 S_GET_NAME(exp.X_subtract_symbol),
1565 segment_name(S_GET_SEGMENT(exp.X_subtract_symbol)));
1566 segment = SEG_ABSOLUTE;
1567 /* Leave exp . X_add_number alone. */
1569 p = frag_more(nbytes);
1572 as_bad("%s number invalid. Absolute 0 assumed.",
1573 exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
1574 md_number_to_chars (p, (long)0, nbytes);
1578 as_warn("0 assumed for missing expression");
1579 exp . X_add_number = 0;
1580 know(exp . X_add_symbol == NULL);
1581 /* fall into SEG_ABSOLUTE */
1583 get = exp . X_add_number;
1585 if ((get & mask) && (get & mask) != mask)
1586 { /* Leading bits contain both 0s & 1s. */
1587 as_warn("Value x%x truncated to x%x.", get, use);
1589 md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
1592 case SEG_DIFFERENCE:
1593 #ifndef WORKING_DOT_WORD
1595 struct broken_word *x;
1597 x=(struct broken_word *)xmalloc(sizeof(struct broken_word));
1598 x->next_broken_word=broken_words;
1601 x->word_goes_here=p;
1603 x->add=exp.X_add_symbol;
1604 x->sub=exp.X_subtract_symbol;
1605 x->addnum=exp.X_add_number;
1610 /* Else Fall through into. . . */
1617 fix_new_ns32k (frag_now, p - frag_now->fr_literal, nbytes,
1618 exp . X_add_symbol, exp . X_subtract_symbol,
1619 exp . X_add_number, 0, 0, 2, 0, 0);
1621 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1622 exp . X_add_symbol, exp . X_subtract_symbol,
1623 exp . X_add_number, 0, RELOC_32);
1624 #endif /* TC_NS32K */
1630 } /* switch(segment) */
1631 } /* if (!need_pass_2) */
1632 c = *input_line_pointer++;
1633 } /* while(c==',') */
1634 input_line_pointer--; /* Put terminator back into stream. */
1635 demand_empty_rest_of_line();
1641 * CONStruct more frag(s) of .quads, or .octa etc.
1642 * Makes 0 or more new frags.
1643 * If need_pass_2 == 1, generate no frag.
1644 * This understands only bignums, not expressions. Cons() understands
1647 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1649 * This creates objects with struct obstack_control objs, destroying
1650 * any context objs held about a partially completed object. Beware!
1653 * I think it sucks to have 2 different types of integers, with 2
1654 * routines to read them, store them etc.
1655 * It would be nicer to permit bignums in expressions and only
1656 * complain if the result overflowed. However, due to "efficiency"...
1658 /* worker to do .quad etc statements */
1659 /* clobbers input_line_pointer, checks */
1661 /* 8=.quad 16=.octa ... */
1663 void big_cons(nbytes)
1664 register int nbytes;
1666 register char c; /* input_line_pointer->c. */
1668 register long length; /* Number of chars in an object. */
1669 register int digit; /* Value of 1 digit. */
1670 register int carry; /* For multi-precision arithmetic. */
1671 register int work; /* For multi-precision arithmetic. */
1672 register char * p; /* For multi-precision arithmetic. */
1674 extern char hex_value[]; /* In hex_value.c. */
1677 * The following awkward logic is to parse ZERO or more strings,
1678 * comma seperated. Recall an expression includes its leading &
1679 * trailing blanks. We fake a leading ',' if there is (supposed to
1680 * be) a 1st expression, and keep demanding 1 expression for each ','.
1682 if (is_it_end_of_statement())
1684 c = 0; /* Skip loop. */
1688 c = ','; /* Do loop. */
1689 -- input_line_pointer;
1693 ++ input_line_pointer;
1695 c = * input_line_pointer;
1696 /* C contains 1st non-blank character of what we hope is a number. */
1699 c = * ++ input_line_pointer;
1700 if (c == 'x' || c=='X')
1702 c = * ++ input_line_pointer;
1715 * This feature (?) is here to stop people worrying about
1716 * mysterious zero constants: which is what they get when
1717 * they completely omit digits.
1719 if (hex_value[c] >= radix) {
1720 as_bad("Missing digits. 0 assumed.");
1722 bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
1723 for(; (digit = hex_value [c]) < radix; c = * ++ input_line_pointer)
1725 /* Multiply existing number by radix, then add digit. */
1727 for (p=bignum_low; p <= bignum_high; p++)
1729 work = (*p & MASK_CHAR) * radix + carry;
1730 *p = work & MASK_CHAR;
1731 carry = work >> BITS_PER_CHAR;
1736 * bignum_high = carry & MASK_CHAR;
1737 know((carry & ~ MASK_CHAR) == 0);
1740 length = bignum_high - bignum_low + 1;
1741 if (length > nbytes)
1743 as_warn("Most significant bits truncated in integer constant.");
1747 register long leading_zeroes;
1749 for(leading_zeroes = nbytes - length;
1759 p = frag_more (nbytes);
1760 bcopy (bignum_low, p, (int)nbytes);
1762 /* C contains character after number. */
1764 c = * input_line_pointer;
1765 /* C contains 1st non-blank character after number. */
1767 demand_empty_rest_of_line();
1770 /* Extend bignum by 1 char. */
1771 static void grow_bignum() {
1772 register long length;
1775 if (bignum_high >= bignum_limit)
1777 length = bignum_limit - bignum_low;
1778 bignum_low = xrealloc(bignum_low, length + length);
1779 bignum_high = bignum_low + length;
1780 bignum_limit = bignum_low + length + length;
1782 } /* grow_bignum(); */
1787 * CONStruct some more frag chars of .floats .ffloats etc.
1788 * Makes 0 or more new frags.
1789 * If need_pass_2 == 1, no frags are emitted.
1790 * This understands only floating literals, not expressions. Sorry.
1792 * A floating constant is defined by atof_generic(), except it is preceded
1793 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1794 * reading, I decided to be incompatible. This always tries to give you
1795 * rounded bits to the precision of the pseudo-op. Former AS did premature
1796 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1797 * a choice of 2 flavours of noise according to which of 2 floating-point
1798 * scanners you directed AS to use.
1800 * In: input_line_pointer->whitespace before, or '0' of flonum.
1804 void /* JF was static, but can't be if VAX.C is goning to use it */
1805 float_cons(float_type) /* Worker to do .float etc statements. */
1806 /* Clobbers input_line-pointer, checks end-of-line. */
1807 register int float_type; /* 'f':.ffloat ... 'F':.float ... */
1811 int length; /* Number of chars in an object. */
1812 register char * err; /* Error from scanning floating literal. */
1813 char temp [MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
1816 * The following awkward logic is to parse ZERO or more strings,
1817 * comma seperated. Recall an expression includes its leading &
1818 * trailing blanks. We fake a leading ',' if there is (supposed to
1819 * be) a 1st expression, and keep demanding 1 expression for each ','.
1821 if (is_it_end_of_statement())
1823 c = 0; /* Skip loop. */
1824 ++ input_line_pointer; /*->past termintor. */
1828 c = ','; /* Do loop. */
1832 /* input_line_pointer->1st char of a flonum (we hope!). */
1834 /* Skip any 0{letter} that may be present. Don't even check if the
1835 * letter is legal. Someone may invent a "z" format and this routine
1836 * has no use for such information. Lusers beware: you get
1837 * diagnostics if your input is ill-conditioned.
1840 if (input_line_pointer[0]=='0' && isalpha(input_line_pointer[1]))
1841 input_line_pointer+=2;
1843 err = md_atof (float_type, temp, &length);
1844 know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
1848 as_bad("Bad floating literal: %s", err);
1849 ignore_rest_of_line();
1850 /* Input_line_pointer->just after end-of-line. */
1851 c = 0; /* Break out of loop. */
1857 p = frag_more (length);
1858 bcopy (temp, p, length);
1861 c = * input_line_pointer ++;
1862 /* C contains 1st non-white character after number. */
1863 /* input_line_pointer->just after terminator (c). */
1866 -- input_line_pointer; /*->terminator (is not ','). */
1867 demand_empty_rest_of_line();
1868 } /* float_cons() */
1873 * We read 0 or more ',' seperated, double-quoted strings.
1875 * Caller should have checked need_pass_2 is FALSE because we don't check it.
1877 static void stringer(append_zero) /* Worker to do .ascii etc statements. */
1878 /* Checks end-of-line. */
1879 register int append_zero; /* 0: don't append '\0', else 1 */
1881 /* register char * p; JF unused */
1882 /* register int length; JF unused */ /* Length of string we read, excluding */
1883 /* trailing '\0' implied by closing quote. */
1884 /* register char * where; JF unused */
1885 /* register fragS * fragP; JF unused */
1886 register unsigned int c;
1889 * The following awkward logic is to parse ZERO or more strings,
1890 * comma seperated. Recall a string expression includes spaces
1891 * before the opening '\"' and spaces after the closing '\"'.
1892 * We fake a leading ',' if there is (supposed to be)
1893 * a 1st, expression. We keep demanding expressions for each
1896 if (is_it_end_of_statement())
1898 c = 0; /* Skip loop. */
1899 ++ input_line_pointer; /* Compensate for end of loop. */
1903 c = ','; /* Do loop. */
1905 for (; c == ','; c = *input_line_pointer++) {
1907 if (*input_line_pointer == '\"') {
1908 ++input_line_pointer; /*->1st char of string. */
1909 while (is_a_char(c = next_char_of_string())) {
1910 FRAG_APPEND_1_CHAR(c);
1913 FRAG_APPEND_1_CHAR(0);
1915 know(input_line_pointer [-1] == '\"');
1917 as_warn("Expected \"-ed string");
1921 --input_line_pointer;
1922 demand_empty_rest_of_line();
1925 /* FIXME-SOMEDAY: I had trouble here on characters with the
1926 high bits set. We'll probably also have trouble with
1927 multibyte chars, wide chars, etc. Also be careful about
1928 returning values bigger than 1 byte. xoxorich. */
1930 static unsigned int next_char_of_string() {
1931 register unsigned int c;
1933 c = *input_line_pointer++ & CHAR_MASK;
1940 switch (c = *input_line_pointer++) {
1969 break; /* As itself. */
1983 for (number = 0; isdigit(c); c = *input_line_pointer++) {
1984 number = number * 8 + c - '0';
1988 --input_line_pointer;
1992 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
1993 as_warn("Unterminated string: Newline inserted.");
1999 #ifdef ONLY_STANDARD_ESCAPES
2000 as_bad("Bad escaped character in string, '?' assumed");
2002 #endif /* ONLY_STANDARD_ESCAPES */
2005 } /* switch on escaped char */
2010 } /* switch on char */
2012 } /* next_char_of_string() */
2015 get_segmented_expression (expP)
2016 register expressionS * expP;
2018 register segT retval;
2020 if ((retval = expression(expP)) == SEG_PASS1 || retval == SEG_ABSENT || retval == SEG_BIG)
2022 as_bad("Expected address expression: absolute 0 assumed");
2023 retval = expP->X_seg = SEG_ABSOLUTE;
2024 expP->X_add_number = 0;
2025 expP->X_add_symbol = expP->X_subtract_symbol = 0;
2027 return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
2030 static segT get_known_segmented_expression(expP)
2031 register expressionS *expP;
2033 register segT retval;
2034 register char * name1;
2035 register char * name2;
2037 if ((retval = get_segmented_expression (expP)) == SEG_UNKNOWN)
2039 name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : "";
2040 name2 = expP->X_subtract_symbol ?
2041 S_GET_NAME(expP->X_subtract_symbol) :
2045 as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2050 as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
2051 name1 ? name1 : name2);
2053 retval = expP->X_seg = SEG_ABSOLUTE;
2054 expP->X_add_number = 0;
2055 expP->X_add_symbol = expP->X_subtract_symbol = NULL;
2057 know(retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE);
2059 } /* get_known_segmented_expression() */
2063 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
2064 get_absolute_expression ()
2069 if ((s = expression(& exp)) != SEG_ABSOLUTE)
2071 if (s != SEG_ABSENT)
2073 as_bad("Bad Absolute Expression, absolute 0 assumed.");
2075 exp . X_add_number = 0;
2077 return (exp . X_add_number);
2080 char /* return terminator */
2081 get_absolute_expression_and_terminator(val_pointer)
2082 long * val_pointer; /* return value of expression */
2084 * val_pointer = get_absolute_expression ();
2085 return (* input_line_pointer ++);
2089 * demand_copy_C_string()
2091 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2092 * Give a warning if that happens.
2095 demand_copy_C_string (len_pointer)
2100 if ((s = demand_copy_string(len_pointer)) != 0)
2104 for (len = * len_pointer;
2113 as_bad("This string may not contain \'\\0\'");
2121 * demand_copy_string()
2123 * Demand string, but return a safe (=private) copy of the string.
2124 * Return NULL if we can't read a string here.
2126 static char *demand_copy_string(lenP)
2129 register unsigned int c;
2135 if (*input_line_pointer == '\"') {
2136 input_line_pointer++; /* Skip opening quote. */
2138 while (is_a_char(c = next_char_of_string())) {
2139 obstack_1grow(¬es, c);
2142 /* JF this next line is so demand_copy_C_string will return a null
2143 termanated string. */
2144 obstack_1grow(¬es,'\0');
2145 retval=obstack_finish(¬es);
2147 as_warn("Missing string");
2149 ignore_rest_of_line();
2153 } /* demand_copy_string() */
2156 * is_it_end_of_statement()
2158 * In: Input_line_pointer->next character.
2160 * Do: Skip input_line_pointer over all whitespace.
2162 * Out: 1 if input_line_pointer->end-of-line.
2164 static int is_it_end_of_statement() {
2166 return (is_end_of_line [* input_line_pointer]);
2167 } /* is_it_end_of_statement() */
2169 void equals(sym_name)
2172 register symbolS *symbolP; /* symbol we are working with */
2174 input_line_pointer++;
2175 if (*input_line_pointer=='=')
2176 input_line_pointer++;
2178 while(*input_line_pointer==' ' || *input_line_pointer=='\t')
2179 input_line_pointer++;
2181 if (sym_name[0]=='.' && sym_name[1]=='\0') {
2182 /* Turn '. = mumble' into a .org mumble */
2183 register segT segment;
2187 segment = get_known_segmented_expression(& exp);
2188 if (! need_pass_2) {
2189 if (segment != now_seg && segment != SEG_ABSOLUTE)
2190 as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
2191 segment_name(segment),
2192 segment_name(now_seg));
2193 p = frag_var(rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
2194 exp.X_add_number, (char *)0);
2196 } /* if (ok to make frag) */
2198 symbolP=symbol_find_or_make(sym_name);
2199 pseudo_set(symbolP);
2203 /* .include -- include a file at this point. */
2215 filename = demand_copy_string(&i);
2216 demand_empty_rest_of_line();
2217 path = malloc(i + include_dir_maxlen + 5 /* slop */);
2218 for (i = 0; i < include_dir_count; i++) {
2219 strcpy(path, include_dirs[i]);
2221 strcat(path, filename);
2222 if (0 != (try = fopen(path, "r")))
2231 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2232 newbuf = input_scrub_include_file (path, input_line_pointer);
2233 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
2236 void add_include_dir(path)
2241 if (include_dir_count == 0)
2243 include_dirs = (char **)malloc (2 * sizeof (*include_dirs));
2244 include_dirs[0] = "."; /* Current dir */
2245 include_dir_count = 2;
2249 include_dir_count++;
2250 include_dirs = (char **) realloc(include_dirs,
2251 include_dir_count*sizeof (*include_dirs));
2254 include_dirs[include_dir_count-1] = path; /* New one */
2257 if (i > include_dir_maxlen)
2258 include_dir_maxlen = i;
2259 } /* add_include_dir() */
2264 extern char is_end_of_line[];
2266 while (!is_end_of_line[*input_line_pointer]) {
2267 ++input_line_pointer;
2269 ++input_line_pointer;