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 2, 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. */
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 MASK_CHAR ((int)(unsigned char)-1)
30 /* This is the largest known floating point format (for now). It will
31 grow when we do 4361 style flonums. */
33 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
35 /* Routines that read assembler source text to build spagetti in memory.
36 Another group of these functions is in the expr.c module. */
48 /* The NOP_OPCODE is for the alignment fill value.
49 * fill it a nop instruction so that the disassembler does not choke
53 #define NOP_OPCODE 0x00
56 char *input_line_pointer; /*->next char of source file to parse. */
58 #if BITS_PER_CHAR != 8
59 /* The following table is indexed by[(char)] and will break if
60 a char does not have exactly 256 states (hopefully 0:255!)! */
64 /* used by is_... macros. our ctype[] */
65 const char lex_type[256] =
67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
69 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
70 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
71 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
72 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
73 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
74 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 * Out: 1 if this character ends a line.
90 char is_end_of_line[256] =
93 _, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _, /* @abcdefghijklmno */
95 _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _, /* @abcdefghijklmno */
97 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
98 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
99 _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, /* 0123456789:;<=>? */
100 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
101 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
102 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
103 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
104 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
105 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
106 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
107 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
108 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
112 /* Functions private to this file. */
114 static char *buffer; /* 1st char of each buffer of lines is here. */
115 static char *buffer_limit; /*->1 + last char in buffer. */
117 static char *bignum_low; /* Lowest char of bignum. */
118 static char *bignum_limit; /* 1st illegal address of bignum. */
119 static char *bignum_high; /* Highest char of bignum. */
120 /* May point to (bignum_start-1). */
121 /* Never >= bignum_limit. */
123 static char *old_buffer; /* JF a hack */
124 static char *old_input;
125 static char *old_limit;
127 /* Variables for handling include file directory list. */
129 char **include_dirs; /* List of pointers to directories to
130 search for .include's */
131 int include_dir_count; /* How many are in the list */
132 int include_dir_maxlen = 1;/* Length of longest in list */
134 #ifndef WORKING_DOT_WORD
135 struct broken_word *broken_words;
136 int new_broken_words;
139 static char *demand_copy_string PARAMS ((int *lenP));
140 int is_it_end_of_statement PARAMS ((void));
141 unsigned int next_char_of_string PARAMS ((void));
142 static segT get_known_segmented_expression PARAMS ((expressionS * expP));
143 static void grow_bignum PARAMS ((void));
144 static void pobegin PARAMS ((void));
145 void stringer PARAMS ((int append_zero));
156 obj_read_begin_hook ();
158 obstack_begin (¬es, 5000);
159 obstack_begin (&cond_obstack, 960);
161 #define BIGNUM_BEGIN_SIZE (16)
162 bignum_low = xmalloc ((long) BIGNUM_BEGIN_SIZE);
163 bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
165 /* Use machine dependent syntax */
166 for (p = line_separator_chars; *p; p++)
167 is_end_of_line[*p] = 1;
168 /* Use more. FIXME-SOMEDAY. */
171 /* set up pseudo-op tables */
173 struct hash_control *po_hash;
175 static const pseudo_typeS potable[] =
177 {"abort", s_abort, 0},
178 {"align", s_align_ptwo, 0},
179 {"ascii", stringer, 0},
180 {"asciz", stringer, 1},
186 {"double", float_cons, 'd'},
188 {"eject", listing_eject, 0}, /* Formfeed listing */
191 {"endif", s_endif, 0},
196 {"extern", s_ignore, 0}, /* We treat all undef as ext */
197 {"app-file", s_app_file, 0},
198 {"file", s_app_file, 0},
200 {"float", float_cons, 'f'},
201 {"global", s_globl, 0},
202 {"globl", s_globl, 0},
205 {"ifdef", s_ifdef, 0},
206 {"ifeqs", s_ifeqs, 0},
207 {"ifndef", s_ifdef, 1},
208 {"ifnes", s_ifeqs, 1},
209 {"ifnotdef", s_ifdef, 1},
210 {"include", s_include, 0},
212 {"lcomm", s_lcomm, 0},
213 {"lflags", listing_flags, 0}, /* Listing flags */
214 {"list", listing_list, 1}, /* Turn listing on */
217 {"nolist", listing_list, 0}, /* Turn listing off */
218 {"octa", big_cons, 16},
220 {"psize", listing_psize, 0}, /* set paper size */
222 {"quad", big_cons, 8},
223 {"sbttl", listing_title, 1}, /* Subtitle of listing */
228 {"single", float_cons, 'f'},
230 {"space", s_space, 0},
233 {"title", listing_title, 0}, /* Listing title */
238 {NULL} /* end sentinel */
244 char *errtxt; /* error text */
245 const pseudo_typeS *pop;
247 po_hash = hash_new ();
249 /* Do the target-specific pseudo ops. */
250 for (pop = md_pseudo_table; pop->poc_name; pop++)
252 errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
253 if (errtxt && *errtxt)
255 as_fatal ("error constructing md pseudo-op table");
259 /* Now object specific. Skip any that were in the target table. */
260 for (pop = obj_pseudo_table; pop->poc_name; pop++)
262 errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
263 if (errtxt && *errtxt)
265 if (!strcmp (errtxt, "exists"))
267 #ifdef DIE_ON_OVERRIDES
268 as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
269 #endif /* DIE_ON_OVERRIDES */
270 continue; /* OK if target table overrides. */
274 as_fatal ("error constructing obj pseudo-op table");
275 } /* if overridden */
279 /* Now portable ones. Skip any that we've seen already. */
280 for (pop = potable; pop->poc_name; pop++)
282 errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
283 if (errtxt && *errtxt)
285 if (!strcmp (errtxt, "exists"))
287 #ifdef DIE_ON_OVERRIDES
288 as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
289 #endif /* DIE_ON_OVERRIDES */
290 continue; /* OK if target table overrides. */
294 as_fatal ("error constructing obj pseudo-op table");
295 } /* if overridden */
302 #define HANDLE_CONDITIONAL_ASSEMBLY() \
303 if (ignore_input ()) \
305 while (! is_end_of_line[*input_line_pointer++]) \
306 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.
318 read_a_source_file (name)
322 register char *s; /* string of symbol, '\0' appended */
324 /* register struct frag * fragP; JF unused *//* a frag we just made */
327 buffer = input_scrub_new_file (name);
330 listing_newline ("");
332 while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
333 { /* We have another line to parse. */
334 know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
335 contin: /* JF this goto is my fault I admit it.
336 Someone brave please re-write the whole
337 input section here? Pleeze??? */
338 while (input_line_pointer < buffer_limit)
340 /* 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')
349 bump_line_counters ();
352 /* Text at the start of a line must be a label, we run down and stick a colon in */
353 if (is_name_beginner (*input_line_pointer))
355 char *line_start = input_line_pointer;
356 char c = get_symbol_end ();
358 *input_line_pointer = c;
360 input_line_pointer++;
368 * We are at the begining of a line, or similar place.
369 * We expect a well-formed assembler statement.
370 * A "symbol-name:" is a statement.
372 * Depending on what compiler is used, the order of these tests
373 * may vary to catch most common case 1st.
374 * Each test is independent of all other tests at the (top) level.
375 * PLEASE make a compiler that doesn't use this assembler.
376 * It is crufty to waste a compiler's time encoding things for this
377 * assembler, which then wastes more time decoding it.
378 * (And communicating via (linear) files is silly!
379 * If you must pass stuff, please pass a tree!)
381 if ((c = *input_line_pointer++) == '\t'
386 c = *input_line_pointer++;
388 know (c != ' '); /* No further leading whitespace. */
391 * C is the 1st significant character.
392 * Input_line_pointer points after that character.
394 if (is_name_beginner (c))
395 { /* want user-defined label or pseudo/opcode */
396 HANDLE_CONDITIONAL_ASSEMBLY ();
398 s = --input_line_pointer;
399 c = get_symbol_end (); /* name's delimiter */
401 * C is character after symbol.
402 * That character's place in the input line is now '\0'.
403 * S points to the beginning of the symbol.
404 * [In case of pseudo-op, s->'.'.]
405 * Input_line_pointer->'\0' where c was.
409 colon (s); /* user-defined label */
410 *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
411 /* Input_line_pointer->after ':'. */
416 else if (c == '=' || input_line_pointer[1] == '=')
417 { /* JF deal with FOO=BAR */
419 demand_empty_rest_of_line ();
422 { /* expect pseudo-op or machine instruction */
424 if (!done_pseudo (s))
432 * WARNING: c has next char, which may be end-of-line.
433 * We lookup the pseudo-op table with s+1 because we
434 * already know that the pseudo-op begins with a '.'.
437 pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
439 /* Print the error msg now, while we still can */
442 as_bad ("Unknown pseudo-op: `%s'", s);
443 *input_line_pointer = c;
448 /* Put it back for error messages etc. */
449 *input_line_pointer = c;
450 /* The following skip of whitespace is compulsory. */
451 /* A well shaped space is sometimes all that separates keyword from operands. */
452 if (c == ' ' || c == '\t')
454 input_line_pointer++;
455 } /* Skip seperator after keyword. */
457 * Input_line is restored.
458 * Input_line_pointer->1st non-blank char
459 * after pseudo-operation.
463 ignore_rest_of_line ();
468 (*pop->poc_handler) (pop->poc_val);
469 } /* if we have one */
473 { /* machine instruction */
474 /* WARNING: c has char, which may be end-of-line. */
475 /* Also: input_line_pointer->`\0` where c was. */
476 *input_line_pointer = c;
477 while (!is_end_of_line[*input_line_pointer])
479 input_line_pointer++;
482 c = *input_line_pointer;
483 *input_line_pointer = '\0';
485 md_assemble (s); /* Assemble 1 instruction. */
487 *input_line_pointer++ = c;
489 /* We resume loop AFTER the end-of-line from this instruction */
494 } /* if (is_name_beginner(c) */
497 if (is_end_of_line[c])
500 } /* empty statement */
503 #if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
505 { /* local label ("4:") */
506 char *backup = input_line_pointer;
508 HANDLE_CONDITIONAL_ASSEMBLY ();
512 while (isdigit (*input_line_pointer))
514 temp = (temp * 10) + *input_line_pointer - '0';
515 ++input_line_pointer;
516 } /* read the whole number */
518 #ifdef LOCAL_LABELS_DOLLAR
519 if (*input_line_pointer == '$'
520 && *(input_line_pointer + 1) == ':')
522 input_line_pointer += 2;
524 if (dollar_label_defined (temp))
526 as_fatal ("label \"%d$\" redefined", temp);
529 define_dollar_label (temp);
530 colon (dollar_label_name (temp, 0));
533 #endif /* LOCAL_LABELS_DOLLAR */
535 #ifdef LOCAL_LABELS_FB
536 if (*input_line_pointer++ == ':')
538 fb_label_instance_inc (temp);
539 colon (fb_label_name (temp, 0));
542 #endif /* LOCAL_LABELS_FB */
544 input_line_pointer = backup;
545 } /* local label ("4:") */
546 #endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
548 if (c && strchr (line_comment_chars, c))
549 { /* Its a comment. Better say APP or NO_APP */
555 extern char *scrub_string, *scrub_last_string;
557 bump_line_counters ();
558 s = input_line_pointer;
559 if (strncmp (s, "APP\n", 4))
560 continue; /* We ignore it */
563 ends = strstr (s, "#NO_APP\n");
570 /* The end of the #APP wasn't in this buffer. We
571 keep reading in buffers until we find the #NO_APP
572 that goes with this #APP There is one. The specs
574 tmp_len = buffer_limit - s;
575 tmp_buf = xmalloc (tmp_len + 1);
576 bcopy (s, tmp_buf, tmp_len);
579 new_tmp = input_scrub_next_buffer (&buffer);
583 buffer_limit = new_tmp;
584 input_line_pointer = buffer;
585 ends = strstr (buffer, "#NO_APP\n");
589 num = buffer_limit - buffer;
591 tmp_buf = xrealloc (tmp_buf, tmp_len + num);
592 bcopy (buffer, tmp_buf + tmp_len, num);
597 input_line_pointer = ends ? ends + 8 : NULL;
605 input_line_pointer = ends + 8;
607 new_buf = xmalloc (100);
612 scrub_last_string = ends;
617 ch = do_scrub_next_char (scrub_from_string, scrub_to_string);
621 if (new_tmp == new_buf + new_length)
623 new_buf = xrealloc (new_buf, new_length + 100);
624 new_tmp = new_buf + new_length;
632 old_input = input_line_pointer;
633 old_limit = buffer_limit;
635 input_line_pointer = new_buf;
636 buffer_limit = new_tmp;
640 HANDLE_CONDITIONAL_ASSEMBLY ();
642 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
643 input_line_pointer--; /* Report unknown char as ignored. */
644 ignore_rest_of_line ();
645 } /* while (input_line_pointer<buffer_limit) */
648 bump_line_counters ();
652 input_line_pointer = old_input;
653 buffer_limit = old_limit;
658 } /* while (more buffers to scan) */
659 input_scrub_close (); /* Close the input file */
661 } /* read_a_source_file() */
666 as_fatal (".abort detected. Abandoning ship.");
669 /* For machines where ".align 4" means align to a 4 byte boundary. */
674 register unsigned int temp;
675 register long temp_fill;
677 unsigned long max_alignment = 1 << 15;
679 if (is_end_of_line[*input_line_pointer])
680 temp = arg; /* Default value from pseudo-op table */
682 temp = get_absolute_expression ();
684 if (temp > max_alignment)
686 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
690 * For the sparc, `.align (1<<n)' actually means `.align n'
691 * so we have to convert it.
695 for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
699 as_bad ("Alignment not a power of 2");
702 if (*input_line_pointer == ',')
704 input_line_pointer++;
705 temp_fill = get_absolute_expression ();
707 else if (now_seg != data_section && now_seg != bss_section)
708 temp_fill = NOP_OPCODE;
711 /* Only make a frag if we HAVE to. . . */
712 if (temp && !need_pass_2)
713 frag_align (temp, (int) temp_fill);
715 demand_empty_rest_of_line ();
716 } /* s_align_bytes() */
718 /* For machines where ".align 4" means align to 2**4 boundary. */
723 register long temp_fill;
724 long max_alignment = 15;
726 temp = get_absolute_expression ();
727 if (temp > max_alignment)
728 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
731 as_bad ("Alignment negative. 0 assumed.");
734 if (*input_line_pointer == ',')
736 input_line_pointer++;
737 temp_fill = get_absolute_expression ();
739 /* @@ Fix this right for BFD! */
740 else if (now_seg != data_section && now_seg != bss_section)
741 temp_fill = NOP_OPCODE;
744 /* Only make a frag if we HAVE to. . . */
745 if (temp && !need_pass_2)
746 frag_align (temp, (int) temp_fill);
748 record_alignment (now_seg, temp);
750 demand_empty_rest_of_line ();
751 } /* s_align_ptwo() */
760 register symbolS *symbolP;
762 name = input_line_pointer;
763 c = get_symbol_end ();
764 /* just after name is now '\0' */
765 p = input_line_pointer;
768 if (*input_line_pointer != ',')
770 as_bad ("Expected comma after symbol-name: rest of line ignored.");
771 ignore_rest_of_line ();
774 input_line_pointer++; /* skip ',' */
775 if ((temp = get_absolute_expression ()) < 0)
777 as_warn (".COMMon length (%d.) <0! Ignored.", temp);
778 ignore_rest_of_line ();
782 symbolP = symbol_find_or_make (name);
784 if (S_IS_DEFINED (symbolP))
786 as_bad ("Ignoring attempt to re-define symbol");
787 ignore_rest_of_line ();
790 if (S_GET_VALUE (symbolP))
792 if (S_GET_VALUE (symbolP) != temp)
793 as_bad ("Length of .comm \"%s\" is already %d. Not changed to %d.",
794 S_GET_NAME (symbolP),
795 S_GET_VALUE (symbolP),
800 S_SET_VALUE (symbolP, temp);
801 S_SET_EXTERNAL (symbolP);
804 if ( (!temp) || !flagseen['1'])
805 S_GET_OTHER(symbolP) = const_flag;
806 #endif /* not OBJ_VMS */
807 know (symbolP->sy_frag == &zero_address_frag);
808 demand_empty_rest_of_line ();
816 temp = get_absolute_expression ();
818 subseg_set (data_section, (subsegT) temp);
820 subseg_new (data_section, (subsegT) temp);
826 demand_empty_rest_of_line ();
835 /* Some assemblers tolerate immediately following '"' */
836 if ((s = demand_copy_string (&length)) != 0)
838 new_logical_line (s, -1);
839 demand_empty_rest_of_line ();
842 c_dot_file_symbol (s);
843 #endif /* OBJ_COFF */
849 long temp_repeat = 0;
851 register long temp_fill = 0;
855 temp_repeat = get_absolute_expression ();
856 if (*input_line_pointer == ',')
858 input_line_pointer++;
859 temp_size = get_absolute_expression ();
860 if (*input_line_pointer == ',')
862 input_line_pointer++;
863 temp_fill = get_absolute_expression ();
866 /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */
867 #define BSD_FILL_SIZE_CROCK_8 (8)
868 if (temp_size > BSD_FILL_SIZE_CROCK_8)
870 as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
871 temp_size = BSD_FILL_SIZE_CROCK_8;
875 as_warn ("Size negative: .fill ignored.");
878 else if (temp_repeat <= 0)
880 as_warn ("Repeat < 0, .fill ignored");
884 if (temp_size && !need_pass_2)
886 p = frag_var (rs_fill, (int) temp_size, (int) temp_size, (relax_substateT) 0, (symbolS *) 0, temp_repeat, (char *) 0);
887 memset (p, 0, (int) temp_size);
888 /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
889 * flavoured AS. The following bizzare behaviour is to be
890 * compatible with above. I guess they tried to take up to 8
891 * bytes from a 4-byte expression and they forgot to sign
892 * extend. Un*x Sux. */
893 #define BSD_FILL_SIZE_CROCK_4 (4)
894 md_number_to_chars (p, temp_fill,
895 (temp_size > BSD_FILL_SIZE_CROCK_4
896 ? BSD_FILL_SIZE_CROCK_4
898 /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
899 * but emits no error message because it seems a legal thing to do.
900 * It is a degenerate case of .fill but could be emitted by a compiler.
903 demand_empty_rest_of_line ();
911 register symbolS *symbolP;
915 name = input_line_pointer;
916 c = get_symbol_end ();
917 symbolP = symbol_find_or_make (name);
918 *input_line_pointer = c;
920 S_SET_EXTERNAL (symbolP);
923 input_line_pointer++;
925 if (*input_line_pointer == '\n')
930 demand_empty_rest_of_line ();
934 s_lcomm (needs_align)
935 /* 1 if this was a ".bss" directive, which may require a 3rd argument
936 (alignment); 0 if it was an ".lcomm" (2 args only) */
943 register symbolS *symbolP;
944 const int max_alignment = 15;
947 name = input_line_pointer;
948 c = get_symbol_end ();
949 p = input_line_pointer;
952 if (*input_line_pointer != ',')
954 as_bad ("Expected comma after name");
955 ignore_rest_of_line ();
959 ++input_line_pointer;
961 if (*input_line_pointer == '\n')
963 as_bad ("Missing size expression");
967 if ((temp = get_absolute_expression ()) < 0)
969 as_warn ("BSS length (%d.) <0! Ignored.", temp);
970 ignore_rest_of_line ();
978 if (*input_line_pointer != ',')
980 as_bad ("Expected comma after size");
981 ignore_rest_of_line ();
984 input_line_pointer++;
986 if (*input_line_pointer == '\n')
988 as_bad ("Missing alignment");
991 align = get_absolute_expression ();
992 if (align > max_alignment)
994 align = max_alignment;
995 as_warn ("Alignment too large: %d. assumed.", align);
1000 as_warn ("Alignment negative. 0 assumed.");
1002 record_alignment (bss_section, align);
1003 } /* if needs align */
1006 symbolP = symbol_find_or_make (name);
1010 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1011 S_GET_OTHER (symbolP) == 0 &&
1012 S_GET_DESC (symbolP) == 0 &&
1013 #endif /* OBJ_AOUT or OBJ_BOUT */
1014 (S_GET_SEGMENT (symbolP) == bss_section
1015 || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
1018 segT current_seg = now_seg;
1019 subsegT current_subseg = now_subseg;
1021 #ifdef BFD_ASSEMBLER
1022 subseg_set (bss_section, 1);
1024 subseg_new (bss_section, 1);
1028 frag_align (align, 0);
1029 /* detach from old frag */
1030 if (S_GET_SEGMENT (symbolP) == bss_section)
1031 symbolP->sy_frag->fr_symbol = NULL;
1033 symbolP->sy_frag = frag_now;
1034 p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
1038 S_SET_SEGMENT (symbolP, bss_section);
1041 /* The symbol may already have been created with a preceding
1042 ".globl" directive -- be careful not to step on storage class
1043 in that case. Otherwise, set it to static. */
1044 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
1046 S_SET_STORAGE_CLASS (symbolP, C_STAT);
1048 #endif /* OBJ_COFF */
1049 #ifdef BFD_ASSEMBLER
1050 subseg_set (current_seg, current_subseg);
1052 subseg_new (current_seg, current_subseg);
1057 as_bad ("Ignoring attempt to re-define symbol %s.", name);
1059 demand_empty_rest_of_line ();
1079 register char *name;
1082 register segT segment;
1084 register symbolS *symbolP;
1086 /* we permit ANY defined expression: BSD4.2 demands constants */
1087 name = input_line_pointer;
1088 c = get_symbol_end ();
1089 p = input_line_pointer;
1092 if (*input_line_pointer != ',')
1095 as_bad ("Expected comma after name \"%s\"", name);
1097 ignore_rest_of_line ();
1100 input_line_pointer++;
1101 segment = expression (&exp);
1102 if (segment != absolute_section
1103 && segment != reg_section
1104 && ! SEG_NORMAL (segment))
1106 as_bad ("Bad expression: %s", segment_name (segment));
1107 ignore_rest_of_line ();
1111 symbolP = symbol_find_or_make (name);
1113 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 &&
1114 symbolP->sy_desc == 0) out of this test because coff doesn't have
1115 those fields, and I can't see when they'd ever be tripped. I
1116 don't think I understand why they were here so I may have
1117 introduced a bug. As recently as 1.37 didn't have this test
1118 anyway. xoxorich. */
1120 if (S_GET_SEGMENT (symbolP) == undefined_section
1121 && S_GET_VALUE (symbolP) == 0)
1123 /* The name might be an undefined .global symbol; be sure to
1124 keep the "external" bit. */
1125 S_SET_SEGMENT (symbolP, segment);
1126 S_SET_VALUE (symbolP, (valueT) (exp.X_add_number));
1130 as_bad ("Symbol %s already defined", name);
1133 demand_empty_rest_of_line ();
1139 register segT segment;
1141 register long temp_fill;
1143 /* Don't believe the documentation of BSD 4.2 AS. There is no such
1144 thing as a sub-segment-relative origin. Any absolute origin is
1145 given a warning, then assumed to be segment-relative. Any
1146 segmented origin expression ("foo+42") had better be in the right
1147 segment or the .org is ignored.
1149 BSD 4.2 AS warns if you try to .org backwards. We cannot because
1150 we never know sub-segment sizes when we are reading code. BSD
1151 will crash trying to emit negative numbers of filler bytes in
1152 certain .orgs. We don't crash, but see as-write for that code.
1154 Don't make frag if need_pass_2==1. */
1155 segment = get_known_segmented_expression (&exp);
1156 if (*input_line_pointer == ',')
1158 input_line_pointer++;
1159 temp_fill = get_absolute_expression ();
1165 if (segment != now_seg && segment != absolute_section)
1166 as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1167 segment_name (segment), segment_name (now_seg));
1168 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1169 exp.X_add_number, (char *) 0);
1171 } /* if (ok to make frag) */
1172 demand_empty_rest_of_line ();
1178 register char *name;
1179 register char delim;
1180 register char *end_name;
1181 register symbolS *symbolP;
1184 * Especial apologies for the random logic:
1185 * this just grew, and could be parsed much more simply!
1188 name = input_line_pointer;
1189 delim = get_symbol_end ();
1190 end_name = input_line_pointer;
1194 if (*input_line_pointer != ',')
1197 as_bad ("Expected comma after name \"%s\"", name);
1199 ignore_rest_of_line ();
1203 input_line_pointer++;
1206 if (name[0] == '.' && name[1] == '\0')
1208 /* Turn '. = mumble' into a .org mumble */
1209 register segT segment;
1213 segment = get_known_segmented_expression (&exp);
1217 if (segment != now_seg && segment != absolute_section)
1218 as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1219 segment_name (segment),
1220 segment_name (now_seg));
1221 ptr = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1222 exp.X_add_number, (char *) 0);
1224 } /* if (ok to make frag) */
1230 if ((symbolP = symbol_find (name)) == NULL
1231 && (symbolP = md_undefined_symbol (name)) == NULL)
1233 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1235 /* "set" symbols are local unless otherwise specified. */
1236 SF_SET_LOCAL (symbolP);
1237 #endif /* OBJ_COFF */
1239 } /* make a new symbol */
1241 symbol_table_insert (symbolP);
1244 pseudo_set (symbolP);
1245 demand_empty_rest_of_line ();
1253 register long temp_fill;
1256 /* Just like .fill, but temp_size = 1 */
1257 if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
1259 temp_fill = get_absolute_expression ();
1263 input_line_pointer--; /* Backup over what was not a ','. */
1268 temp_repeat *= mult;
1270 if (temp_repeat <= 0)
1272 as_warn ("Repeat < 0, .space ignored");
1273 ignore_rest_of_line ();
1278 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
1279 temp_repeat, (char *) 0);
1282 demand_empty_rest_of_line ();
1290 temp = get_absolute_expression ();
1291 #ifdef BFD_ASSEMBLER
1292 subseg_set (text_section, (subsegT) temp);
1294 subseg_new (text_section, (subsegT) temp);
1296 demand_empty_rest_of_line ();
1301 demand_empty_rest_of_line ()
1304 if (is_end_of_line[*input_line_pointer])
1306 input_line_pointer++;
1310 ignore_rest_of_line ();
1312 /* Return having already swallowed end-of-line. */
1313 } /* Return pointing just after end-of-line. */
1316 ignore_rest_of_line () /* For suspect lines: gives warning. */
1318 if (!is_end_of_line[*input_line_pointer])
1320 if (isprint (*input_line_pointer))
1321 as_bad ("Rest of line ignored. First ignored character is `%c'.",
1322 *input_line_pointer);
1324 as_bad ("Rest of line ignored. First ignored character valued 0x%x.",
1325 *input_line_pointer);
1326 while (input_line_pointer < buffer_limit
1327 && !is_end_of_line[*input_line_pointer])
1329 input_line_pointer++;
1332 input_line_pointer++; /* Return pointing just after end-of-line. */
1333 know (is_end_of_line[input_line_pointer[-1]]);
1339 * In: Pointer to a symbol.
1340 * Input_line_pointer->expression.
1342 * Out: Input_line_pointer->just after any whitespace after expression.
1343 * Tried to set symbol to value of expression.
1344 * Will change symbols type, value, and frag;
1345 * May set need_pass_2 == 1.
1348 pseudo_set (symbolP)
1352 register segT segment;
1353 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1355 #endif /* OBJ_AOUT or OBJ_BOUT */
1357 know (symbolP); /* NULL pointer is logic error. */
1358 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1359 /* @@ Fix this right for BFD. */
1360 ext = S_IS_EXTERNAL (symbolP);
1361 #endif /* OBJ_AOUT or OBJ_BOUT */
1363 if ((segment = expression (&exp)) == absent_section)
1365 as_bad ("Missing expression: absolute 0 assumed");
1366 exp.X_seg = absolute_section;
1367 exp.X_add_number = 0;
1370 if (segment == reg_section)
1372 S_SET_SEGMENT (symbolP, reg_section);
1373 S_SET_VALUE (symbolP, exp.X_add_number);
1374 symbolP->sy_frag = &zero_address_frag;
1376 else if (segment == big_section)
1378 as_bad ("%s number invalid. Absolute 0 assumed.",
1379 exp.X_add_number > 0 ? "Bignum" : "Floating-Point");
1380 S_SET_SEGMENT (symbolP, absolute_section);
1381 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1382 /* @@ Fix this right for BFD. */
1383 ext ? S_SET_EXTERNAL (symbolP) :
1384 S_CLEAR_EXTERNAL (symbolP);
1385 #endif /* OBJ_AOUT or OBJ_BOUT */
1386 S_SET_VALUE (symbolP, 0);
1387 symbolP->sy_frag = &zero_address_frag;
1389 else if (segment == absent_section)
1391 as_warn ("No expression: Using absolute 0");
1392 S_SET_SEGMENT (symbolP, absolute_section);
1393 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1394 /* @@ Fix this right for BFD. */
1395 ext ? S_SET_EXTERNAL (symbolP) :
1396 S_CLEAR_EXTERNAL (symbolP);
1397 #endif /* OBJ_AOUT or OBJ_BOUT */
1398 S_SET_VALUE (symbolP, 0);
1399 symbolP->sy_frag = &zero_address_frag;
1401 else if (segment == diff_section)
1403 if (exp.X_add_symbol && exp.X_subtract_symbol
1404 && (S_GET_SEGMENT (exp.X_add_symbol) ==
1405 S_GET_SEGMENT (exp.X_subtract_symbol)))
1407 if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag)
1409 as_bad ("Unknown expression: symbols %s and %s are in different frags.",
1410 S_GET_NAME (exp.X_add_symbol), S_GET_NAME (exp.X_subtract_symbol));
1413 exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) -
1414 S_GET_VALUE (exp.X_subtract_symbol);
1417 as_bad ("Complex expression. Absolute segment assumed.");
1420 else if (segment == absolute_section)
1423 S_SET_SEGMENT (symbolP, absolute_section);
1424 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1425 /* @@ Fix this right for BFD. */
1426 ext ? S_SET_EXTERNAL (symbolP) :
1427 S_CLEAR_EXTERNAL (symbolP);
1428 #endif /* OBJ_AOUT or OBJ_BOUT */
1429 S_SET_VALUE (symbolP, exp.X_add_number);
1430 symbolP->sy_frag = &zero_address_frag;
1432 else if (segment == pass1_section)
1434 symbolP->sy_forward = exp.X_add_symbol;
1435 as_bad ("Unknown expression");
1436 know (need_pass_2 == 1);
1438 else if (segment == undefined_section)
1440 symbolP->sy_forward = exp.X_add_symbol;
1444 #ifndef BFD_ASSEMBLER
1445 #ifndef MANY_SEGMENTS
1454 as_fatal ("failed sanity check.");
1455 } /* switch on segment */
1458 S_SET_SEGMENT (symbolP, segment);
1459 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1460 /* @@ Fix this right for BFD! */
1463 S_SET_EXTERNAL (symbolP);
1467 S_CLEAR_EXTERNAL (symbolP);
1469 #endif /* OBJ_AOUT or OBJ_BOUT */
1471 S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (exp.X_add_symbol));
1472 symbolP->sy_frag = exp.X_add_symbol->sy_frag;
1479 * CONStruct more frag of .bytes, or .words etc.
1480 * Should need_pass_2 be 1 then emit no frag(s).
1481 * This understands EXPRESSIONS, as opposed to big_cons().
1485 * This has a split personality. We use expression() to read the
1486 * value. We can detect if the value won't fit in a byte or word.
1487 * But we can't detect if expression() discarded significant digits
1488 * in the case of a long. Not worth the crocks required to fix it.
1491 /* worker to do .byte etc statements */
1492 /* clobbers input_line_pointer, checks */
1496 register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
1499 register long mask; /* High-order bits we will left-truncate, */
1500 /* but includes sign bit also. */
1501 register long get; /* what we get */
1502 register long use; /* get after truncation. */
1503 register long unmask; /* what bits we will store */
1505 register segT segment;
1509 * Input_line_pointer->1st char after pseudo-op-code and could legally
1510 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1512 /* JF << of >= number of bits in the object is undefined. In particular
1513 SPARC (Sun 4) has problems */
1515 if (nbytes >= sizeof (long))
1521 mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
1522 } /* bigger than a long */
1524 unmask = ~mask; /* Do store these bits. */
1527 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1528 mask = ~(unmask >> 1); /* Includes sign bit now. */
1532 * The following awkward logic is to parse ZERO or more expressions,
1533 * comma seperated. Recall an expression includes its leading &
1534 * trailing blanks. We fake a leading ',' if there is (supposed to
1535 * be) a 1st expression, and keep demanding 1 expression for each ','.
1537 if (is_it_end_of_statement ())
1539 c = 0; /* Skip loop. */
1540 input_line_pointer++; /* Matches end-of-loop 'correction'. */
1545 } /* if the end else fake it */
1550 #ifdef WANT_BITFIELDS
1551 unsigned int bits_available = BITS_PER_CHAR * nbytes;
1552 /* used for error messages and rescanning */
1553 char *hold = input_line_pointer;
1554 #endif /* WANT_BITFIELDS */
1556 if (*input_line_pointer == '\'')
1558 /* An MRI style string, cut into as many bytes as will fit
1559 into a nbyte chunk, left justify if necessary, and sepatate
1560 with commas so we can try again later */
1562 unsigned int result = 0;
1563 input_line_pointer++;
1564 for (scan = 0; scan < nbytes; scan++)
1566 if (*input_line_pointer == '\'')
1568 if (input_line_pointer[1] == '\'')
1570 input_line_pointer++;
1575 result = (result << 8) | (*input_line_pointer++);
1579 while (scan < nbytes)
1584 /* Create correct expression */
1585 exp.X_add_symbol = 0;
1586 exp.X_add_number = result;
1587 exp.X_seg = segment = absolute_section;
1588 /* Fake it so that we can read the next char too */
1589 if (input_line_pointer[0] != '\'' ||
1590 (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
1592 input_line_pointer -= 2;
1593 input_line_pointer[0] = ',';
1594 input_line_pointer[1] = '\'';
1597 input_line_pointer++;
1602 /* At least scan over the expression. */
1603 segment = expression (&exp);
1605 #ifdef WANT_BITFIELDS
1606 /* Some other assemblers, (eg, asm960), allow
1607 bitfields after ".byte" as w:x,y:z, where w and
1608 y are bitwidths and x and y are values. They
1609 then pack them all together. We do a little
1610 better in that we allow them in words, longs,
1611 etc. and we'll pack them in target byte order
1614 The rules are: pack least significat bit first,
1615 if a field doesn't entirely fit, put it in the
1616 next unit. Overflowing the bitfield is
1617 explicitly *not* even a warning. The bitwidth
1618 should be considered a "mask".
1620 FIXME-SOMEDAY: If this is considered generally
1621 useful, this logic should probably be reworked.
1624 if (*input_line_pointer == ':')
1630 unsigned long width;
1632 if (*input_line_pointer != ':')
1634 input_line_pointer = hold;
1636 } /* next piece is not a bitfield */
1638 /* In the general case, we can't allow
1639 full expressions with symbol
1640 differences and such. The relocation
1641 entries for symbols not defined in this
1642 assembly would require arbitrary field
1643 widths, positions, and masks which most
1644 of our current object formats don't
1647 In the specific case where a symbol
1648 *is* defined in this assembly, we
1649 *could* build fixups and track it, but
1650 this could lead to confusion for the
1651 backends. I'm lazy. I'll take any
1652 SEG_ABSOLUTE. I think that means that
1653 you can use a previous .set or
1654 .equ type symbol. xoxorich. */
1656 if (segment == absent_section)
1658 as_warn ("Using a bit field width of zero.");
1659 exp.X_add_number = 0;
1660 segment = absolute_section;
1661 } /* implied zero width bitfield */
1663 if (segment != absolute_section)
1665 *input_line_pointer = '\0';
1666 as_bad ("Field width \"%s\" too complex for a bitfield.\n", hold);
1667 *input_line_pointer = ':';
1668 demand_empty_rest_of_line ();
1672 if ((width = exp.X_add_number) > (BITS_PER_CHAR * nbytes))
1674 as_warn ("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1675 width, nbytes, (BITS_PER_CHAR * nbytes));
1676 width = BITS_PER_CHAR * nbytes;
1679 if (width > bits_available)
1681 /* FIXME-SOMEDAY: backing up and
1682 reparsing is wasteful */
1683 input_line_pointer = hold;
1684 exp.X_add_number = value;
1688 hold = ++input_line_pointer; /* skip ':' */
1690 if ((segment = expression (&exp)) != absolute_section)
1692 char cache = *input_line_pointer;
1694 *input_line_pointer = '\0';
1695 as_bad ("Field value \"%s\" too complex for a bitfield.\n", hold);
1696 *input_line_pointer = cache;
1697 demand_empty_rest_of_line ();
1701 value |= (~(-1 << width) & exp.X_add_number)
1702 << ((BITS_PER_CHAR * nbytes) - bits_available);
1704 if ((bits_available -= width) == 0
1705 || is_it_end_of_statement ()
1706 || *input_line_pointer != ',')
1709 } /* all the bitfields we're gonna get */
1711 hold = ++input_line_pointer;
1712 segment = expression (&exp);
1713 } /* forever loop */
1715 exp.X_add_number = value;
1716 segment = absolute_section;
1717 } /* if looks like a bitfield */
1718 #endif /* WANT_BITFIELDS */
1721 { /* Still worthwhile making frags. */
1723 /* Don't call this if we are going to junk this pass anyway! */
1724 know (segment != pass1_section);
1726 if (segment == diff_section && exp.X_add_symbol == NULL)
1728 as_bad ("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1729 S_GET_NAME (exp.X_subtract_symbol),
1730 segment_name (S_GET_SEGMENT (exp.X_subtract_symbol)));
1731 segment = absolute_section;
1732 /* Leave exp . X_add_number alone. */
1734 p = frag_more (nbytes);
1735 if (segment == big_section)
1737 as_bad ("%s number invalid. Absolute 0 assumed.",
1738 exp.X_add_number > 0 ? "Bignum" : "Floating-Point");
1739 md_number_to_chars (p, (long) 0, nbytes);
1741 else if (segment == absent_section)
1743 as_warn ("0 assumed for missing expression");
1744 exp.X_add_number = 0;
1745 know (exp.X_add_symbol == NULL);
1748 else if (segment == absolute_section)
1751 get = exp.X_add_number;
1753 if ((get & mask) && (get & mask) != mask)
1754 { /* Leading bits contain both 0s & 1s. */
1755 as_warn ("Value 0x%x truncated to 0x%x.", get, use);
1757 md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
1759 else if (segment == diff_section)
1761 #ifndef WORKING_DOT_WORD
1764 struct broken_word *x;
1766 x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
1767 x->next_broken_word = broken_words;
1770 x->word_goes_here = p;
1772 x->add = exp.X_add_symbol;
1773 x->sub = exp.X_subtract_symbol;
1774 x->addnum = exp.X_add_number;
1783 /* undefined_section, others */
1786 #ifdef BFD_ASSEMBLER
1787 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1788 exp.X_add_symbol, exp.X_subtract_symbol,
1789 exp.X_add_number, 0,
1790 /* @@ Should look at CPU word size. */
1794 fix_new_ns32k (frag_now, p - frag_now->fr_literal, nbytes,
1795 exp.X_add_symbol, exp.X_subtract_symbol,
1796 exp.X_add_number, 0, 0, 2, 0, 0);
1798 #if defined(TC_SPARC) || defined(TC_A29K)
1799 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1800 exp.X_add_symbol, exp.X_subtract_symbol,
1801 exp.X_add_number, 0, RELOC_32);
1803 #if defined(TC_H8300)
1804 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1805 exp.X_add_symbol, exp.X_subtract_symbol,
1806 exp.X_add_number, 0, R_RELWORD);
1810 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1811 exp.X_add_symbol, exp.X_subtract_symbol,
1812 exp.X_add_number, 0, NO_RELOC);
1814 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1815 exp.X_add_symbol, exp.X_subtract_symbol,
1816 exp.X_add_number, 0, 0);
1817 #endif /* NO_RELOC */
1818 #endif /* tc_h8300 */
1819 #endif /* tc_sparc|tc_a29k */
1820 #endif /* TC_NS32K */
1821 #endif /* BFD_ASSEMBLER */
1822 } /* switch(segment) */
1825 } /* if (!need_pass_2) */
1826 c = *input_line_pointer++;
1827 } /* while(c==',') */
1828 input_line_pointer--; /* Put terminator back into stream. */
1829 demand_empty_rest_of_line ();
1835 * CONStruct more frag(s) of .quads, or .octa etc.
1836 * Makes 0 or more new frags.
1837 * If need_pass_2 == 1, generate no frag.
1838 * This understands only bignums, not expressions. Cons() understands
1841 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1843 * This creates objects with struct obstack_control objs, destroying
1844 * any context objs held about a partially completed object. Beware!
1847 * I think it sucks to have 2 different types of integers, with 2
1848 * routines to read them, store them etc.
1849 * It would be nicer to permit bignums in expressions and only
1850 * complain if the result overflowed. However, due to "efficiency"...
1852 /* worker to do .quad etc statements */
1853 /* clobbers input_line_pointer, checks */
1855 /* 8=.quad 16=.octa ... */
1859 register int nbytes;
1861 register char c; /* input_line_pointer->c. */
1863 register long length; /* Number of chars in an object. */
1864 register int digit; /* Value of 1 digit. */
1865 register int carry; /* For multi-precision arithmetic. */
1866 register int work; /* For multi-precision arithmetic. */
1867 register char *p; /* For multi-precision arithmetic. */
1869 extern const char hex_value[]; /* In hex_value.c. */
1872 * The following awkward logic is to parse ZERO or more strings,
1873 * comma seperated. Recall an expression includes its leading &
1874 * trailing blanks. We fake a leading ',' if there is (supposed to
1875 * be) a 1st expression, and keep demanding 1 expression for each ','.
1877 if (is_it_end_of_statement ())
1879 c = 0; /* Skip loop. */
1883 c = ','; /* Do loop. */
1884 --input_line_pointer;
1888 ++input_line_pointer;
1890 c = *input_line_pointer;
1891 /* C contains 1st non-blank character of what we hope is a number. */
1894 c = *++input_line_pointer;
1895 if (c == 'x' || c == 'X')
1897 c = *++input_line_pointer;
1910 * This feature (?) is here to stop people worrying about
1911 * mysterious zero constants: which is what they get when
1912 * they completely omit digits.
1914 if (hex_value[c] >= radix)
1916 as_bad ("Missing digits. 0 assumed.");
1918 bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
1919 for (; (digit = hex_value[c]) < radix; c = *++input_line_pointer)
1921 /* Multiply existing number by radix, then add digit. */
1923 for (p = bignum_low; p <= bignum_high; p++)
1925 work = (*p & MASK_CHAR) * radix + carry;
1926 *p = work & MASK_CHAR;
1927 carry = work >> BITS_PER_CHAR;
1932 *bignum_high = carry & MASK_CHAR;
1933 know ((carry & ~MASK_CHAR) == 0);
1936 length = bignum_high - bignum_low + 1;
1937 if (length > nbytes)
1939 as_warn ("Most significant bits truncated in integer constant.");
1943 register long leading_zeroes;
1945 for (leading_zeroes = nbytes - length;
1955 p = frag_more (nbytes);
1956 bcopy (bignum_low, p, (int) nbytes);
1958 /* C contains character after number. */
1960 c = *input_line_pointer;
1961 /* C contains 1st non-blank character after number. */
1963 demand_empty_rest_of_line ();
1966 /* Extend bignum by 1 char. */
1970 register long length;
1973 if (bignum_high >= bignum_limit)
1975 length = bignum_limit - bignum_low;
1976 bignum_low = xrealloc (bignum_low, length + length);
1977 bignum_high = bignum_low + length;
1978 bignum_limit = bignum_low + length + length;
1980 } /* grow_bignum(); */
1985 * CONStruct some more frag chars of .floats .ffloats etc.
1986 * Makes 0 or more new frags.
1987 * If need_pass_2 == 1, no frags are emitted.
1988 * This understands only floating literals, not expressions. Sorry.
1990 * A floating constant is defined by atof_generic(), except it is preceded
1991 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1992 * reading, I decided to be incompatible. This always tries to give you
1993 * rounded bits to the precision of the pseudo-op. Former AS did premature
1994 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1995 * a choice of 2 flavours of noise according to which of 2 floating-point
1996 * scanners you directed AS to use.
1998 * In: input_line_pointer->whitespace before, or '0' of flonum.
2002 void /* JF was static, but can't be if VAX.C is goning to use it */
2003 float_cons (float_type) /* Worker to do .float etc statements. */
2004 /* Clobbers input_line-pointer, checks end-of-line. */
2005 register int float_type; /* 'f':.ffloat ... 'F':.float ... */
2009 int length; /* Number of chars in an object. */
2010 register char *err; /* Error from scanning floating literal. */
2011 char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
2014 * The following awkward logic is to parse ZERO or more strings,
2015 * comma seperated. Recall an expression includes its leading &
2016 * trailing blanks. We fake a leading ',' if there is (supposed to
2017 * be) a 1st expression, and keep demanding 1 expression for each ','.
2019 if (is_it_end_of_statement ())
2021 c = 0; /* Skip loop. */
2022 ++input_line_pointer; /*->past termintor. */
2026 c = ','; /* Do loop. */
2030 /* input_line_pointer->1st char of a flonum (we hope!). */
2032 /* Skip any 0{letter} that may be present. Don't even check if the
2033 * letter is legal. Someone may invent a "z" format and this routine
2034 * has no use for such information. Lusers beware: you get
2035 * diagnostics if your input is ill-conditioned.
2038 if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
2039 input_line_pointer += 2;
2041 err = md_atof (float_type, temp, &length);
2042 know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
2046 as_bad ("Bad floating literal: %s", err);
2047 ignore_rest_of_line ();
2048 /* Input_line_pointer->just after end-of-line. */
2049 c = 0; /* Break out of loop. */
2055 p = frag_more (length);
2056 bcopy (temp, p, length);
2059 c = *input_line_pointer++;
2060 /* C contains 1st non-white character after number. */
2061 /* input_line_pointer->just after terminator (c). */
2064 --input_line_pointer; /*->terminator (is not ','). */
2065 demand_empty_rest_of_line ();
2066 } /* float_cons() */
2071 * We read 0 or more ',' seperated, double-quoted strings.
2073 * Caller should have checked need_pass_2 is FALSE because we don't check it.
2078 stringer (append_zero) /* Worker to do .ascii etc statements. */
2079 /* Checks end-of-line. */
2080 register int append_zero; /* 0: don't append '\0', else 1 */
2082 register unsigned int c;
2085 * The following awkward logic is to parse ZERO or more strings,
2086 * comma seperated. Recall a string expression includes spaces
2087 * before the opening '\"' and spaces after the closing '\"'.
2088 * We fake a leading ',' if there is (supposed to be)
2089 * a 1st, expression. We keep demanding expressions for each
2092 if (is_it_end_of_statement ())
2094 c = 0; /* Skip loop. */
2095 ++input_line_pointer; /* Compensate for end of loop. */
2099 c = ','; /* Do loop. */
2101 while (c == ',' || c == '<' || c == '"')
2104 switch (*input_line_pointer)
2107 ++input_line_pointer; /*->1st char of string. */
2108 while (is_a_char (c = next_char_of_string ()))
2110 FRAG_APPEND_1_CHAR (c);
2114 FRAG_APPEND_1_CHAR (0);
2116 know (input_line_pointer[-1] == '\"');
2119 input_line_pointer++;
2120 c = get_single_number ();
2121 FRAG_APPEND_1_CHAR (c);
2122 if (*input_line_pointer != '>')
2124 as_bad ("Expected <nn>");
2126 input_line_pointer++;
2129 input_line_pointer++;
2133 c = *input_line_pointer;
2136 demand_empty_rest_of_line ();
2139 /* FIXME-SOMEDAY: I had trouble here on characters with the
2140 high bits set. We'll probably also have trouble with
2141 multibyte chars, wide chars, etc. Also be careful about
2142 returning values bigger than 1 byte. xoxorich. */
2145 next_char_of_string ()
2147 register unsigned int c;
2149 c = *input_line_pointer++ & CHAR_MASK;
2157 switch (c = *input_line_pointer++)
2187 break; /* As itself. */
2202 for (number = 0; isdigit (c); c = *input_line_pointer++)
2204 number = number * 8 + c - '0';
2208 --input_line_pointer;
2212 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2213 as_warn ("Unterminated string: Newline inserted.");
2219 #ifdef ONLY_STANDARD_ESCAPES
2220 as_bad ("Bad escaped character in string, '?' assumed");
2222 #endif /* ONLY_STANDARD_ESCAPES */
2225 } /* switch on escaped char */
2230 } /* switch on char */
2232 } /* next_char_of_string() */
2235 get_segmented_expression (expP)
2236 register expressionS *expP;
2238 register segT retval;
2240 retval = expression (expP);
2241 if (retval == pass1_section
2242 || retval == absent_section
2243 || retval == big_section)
2245 as_bad ("Expected address expression: absolute 0 assumed");
2246 retval = expP->X_seg = absolute_section;
2247 expP->X_add_number = 0;
2248 expP->X_add_symbol = expP->X_subtract_symbol = 0;
2250 return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
2254 get_known_segmented_expression (expP)
2255 register expressionS *expP;
2257 register segT retval;
2258 register CONST char *name1;
2259 register CONST char *name2;
2261 if ((retval = get_segmented_expression (expP)) == undefined_section)
2263 name1 = expP->X_add_symbol ? S_GET_NAME (expP->X_add_symbol) : "";
2264 name2 = expP->X_subtract_symbol ?
2265 S_GET_NAME (expP->X_subtract_symbol) :
2269 as_warn ("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2274 as_warn ("Symbol \"%s\" undefined: absolute 0 assumed.",
2275 name1 ? name1 : name2);
2277 retval = expP->X_seg = absolute_section;
2278 expP->X_add_number = 0;
2279 expP->X_add_symbol = expP->X_subtract_symbol = NULL;
2281 know (retval == absolute_section
2282 || retval == diff_section
2283 || SEG_NORMAL (retval));
2286 } /* get_known_segmented_expression() */
2290 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
2291 get_absolute_expression ()
2296 if ((s = expression (&exp)) != absolute_section)
2298 if (s != absent_section)
2300 as_bad ("Bad Absolute Expression, absolute 0 assumed.");
2302 exp.X_add_number = 0;
2304 return (exp.X_add_number);
2307 char /* return terminator */
2308 get_absolute_expression_and_terminator (val_pointer)
2309 long *val_pointer; /* return value of expression */
2311 *val_pointer = get_absolute_expression ();
2312 return (*input_line_pointer++);
2316 * demand_copy_C_string()
2318 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2319 * Give a warning if that happens.
2322 demand_copy_C_string (len_pointer)
2327 if ((s = demand_copy_string (len_pointer)) != 0)
2331 for (len = *len_pointer;
2340 as_bad ("This string may not contain \'\\0\'");
2348 * demand_copy_string()
2350 * Demand string, but return a safe (=private) copy of the string.
2351 * Return NULL if we can't read a string here.
2354 demand_copy_string (lenP)
2357 register unsigned int c;
2363 if (*input_line_pointer == '\"')
2365 input_line_pointer++; /* Skip opening quote. */
2367 while (is_a_char (c = next_char_of_string ()))
2369 obstack_1grow (¬es, c);
2372 /* JF this next line is so demand_copy_C_string will return a null
2373 termanated string. */
2374 obstack_1grow (¬es, '\0');
2375 retval = obstack_finish (¬es);
2379 as_warn ("Missing string");
2381 ignore_rest_of_line ();
2385 } /* demand_copy_string() */
2388 * is_it_end_of_statement()
2390 * In: Input_line_pointer->next character.
2392 * Do: Skip input_line_pointer over all whitespace.
2394 * Out: 1 if input_line_pointer->end-of-line.
2397 is_it_end_of_statement ()
2400 return (is_end_of_line[*input_line_pointer]);
2401 } /* is_it_end_of_statement() */
2407 register symbolS *symbolP; /* symbol we are working with */
2409 input_line_pointer++;
2410 if (*input_line_pointer == '=')
2411 input_line_pointer++;
2413 while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
2414 input_line_pointer++;
2416 if (sym_name[0] == '.' && sym_name[1] == '\0')
2418 /* Turn '. = mumble' into a .org mumble */
2419 register segT segment;
2423 segment = get_known_segmented_expression (&exp);
2426 if (segment != now_seg && segment != absolute_section)
2427 as_warn ("Illegal segment \"%s\". Segment \"%s\" assumed.",
2428 segment_name (segment),
2429 segment_name (now_seg));
2430 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
2431 exp.X_add_number, (char *) 0);
2433 } /* if (ok to make frag) */
2437 symbolP = symbol_find_or_make (sym_name);
2438 pseudo_set (symbolP);
2442 /* .include -- include a file at this point. */
2455 filename = demand_copy_string (&i);
2456 demand_empty_rest_of_line ();
2457 path = xmalloc (i + include_dir_maxlen + 5 /* slop */ );
2458 for (i = 0; i < include_dir_count; i++)
2460 strcpy (path, include_dirs[i]);
2462 strcat (path, filename);
2463 if (0 != (try = fopen (path, "r")))
2472 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2473 newbuf = input_scrub_include_file (path, input_line_pointer);
2474 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
2478 add_include_dir (path)
2483 if (include_dir_count == 0)
2485 include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
2486 include_dirs[0] = "."; /* Current dir */
2487 include_dir_count = 2;
2491 include_dir_count++;
2492 include_dirs = (char **) realloc (include_dirs,
2493 include_dir_count * sizeof (*include_dirs));
2496 include_dirs[include_dir_count - 1] = path; /* New one */
2499 if (i > include_dir_maxlen)
2500 include_dir_maxlen = i;
2501 } /* add_include_dir() */
2507 extern char is_end_of_line[];
2509 while (!is_end_of_line[*input_line_pointer])
2511 ++input_line_pointer;
2513 ++input_line_pointer;