Changes to support stabs-in-coff
[deliverable/binutils-gdb.git] / gas / read.c
1 /* read.c - read a source file -
2 Copyright (C) 1986, 1987, 1990, 1991, 1993 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
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)
9 any later version.
10
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.
15
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. */
19
20 #if 0
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.)
25 */
26 #else
27 #define MASK_CHAR ((int)(unsigned char)-1)
28 #endif
29
30
31 /* This is the largest known floating point format (for now). It will
32 grow when we do 4361 style flonums. */
33
34 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
35
36 /* Routines that read assembler source text to build spagetti in memory.
37 Another group of these functions is in the expr.c module. */
38
39 /* for isdigit() */
40 #include <ctype.h>
41
42 #include "as.h"
43 #include "subsegs.h"
44
45 #include "obstack.h"
46 #include "listing.h"
47
48 /* We need this, despite the apparent object format dependency, since
49 it defines stab types, which all object formats can use now. */
50
51 #include "aout/stab_gnu.h"
52
53 #ifndef TC_START_LABEL
54 #define TC_START_LABEL(x,y) (x==':')
55 #endif
56
57 /* The NOP_OPCODE is for the alignment fill value.
58 * fill it a nop instruction so that the disassembler does not choke
59 * on it
60 */
61 #ifndef NOP_OPCODE
62 #define NOP_OPCODE 0x00
63 #endif
64
65 char *input_line_pointer; /*->next char of source file to parse. */
66
67 #if BITS_PER_CHAR != 8
68 /* The following table is indexed by[(char)] and will break if
69 a char does not have exactly 256 states (hopefully 0:255!)! */
70 die horribly;
71 #endif
72
73 #ifndef LEX_AT
74 /* The m88k unfortunately uses @ as a label beginner. */
75 #define LEX_AT 0
76 #endif
77
78 /* used by is_... macros. our ctype[] */
79 const char lex_type[256] =
80 {
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
82 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
83 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
84 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
85 LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
86 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
87 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
88 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96 };
97
98
99 /*
100 * In: a character.
101 * Out: 1 if this character ends a line.
102 */
103 #define _ (0)
104 char is_end_of_line[256] =
105 {
106 #ifdef CR_EOL
107 _, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _, /* @abcdefghijklmno */
108 #else
109 _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _, /* @abcdefghijklmno */
110 #endif
111 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
112 #ifdef TC_HPPA
113 _,99, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* _!"#$%&'()*+,-./ */
114 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0123456789:;<=>? */
115 #else
116 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
117 _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, /* 0123456789:;<=>? */
118 #endif
119 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
120 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
121 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
122 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
123 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
124 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
125 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
126 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
127 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
128 };
129 #undef _
130
131 /* Functions private to this file. */
132
133 static char *buffer; /* 1st char of each buffer of lines is here. */
134 static char *buffer_limit; /*->1 + last char in buffer. */
135
136 static char *bignum_low; /* Lowest char of bignum. */
137 static char *bignum_limit; /* 1st illegal address of bignum. */
138 static char *bignum_high; /* Highest char of bignum. */
139 /* May point to (bignum_start-1). */
140 /* Never >= bignum_limit. */
141
142 int target_big_endian;
143
144 static char *old_buffer; /* JF a hack */
145 static char *old_input;
146 static char *old_limit;
147
148 /* Variables for handling include file directory list. */
149
150 char **include_dirs; /* List of pointers to directories to
151 search for .include's */
152 int include_dir_count; /* How many are in the list */
153 int include_dir_maxlen = 1;/* Length of longest in list */
154
155 #ifndef WORKING_DOT_WORD
156 struct broken_word *broken_words;
157 int new_broken_words;
158 #endif
159
160 static char *demand_copy_string PARAMS ((int *lenP));
161 int is_it_end_of_statement PARAMS ((void));
162 unsigned int next_char_of_string PARAMS ((void));
163 static segT get_segmented_expression PARAMS ((expressionS *expP));
164 static segT get_known_segmented_expression PARAMS ((expressionS * expP));
165 static void grow_bignum PARAMS ((void));
166 static void pobegin PARAMS ((void));
167
168 extern int listing;
169 \f
170
171 void
172 read_begin ()
173 {
174 const char *p;
175
176 pobegin ();
177 obj_read_begin_hook ();
178
179 /* Something close -- but not too close -- to a multiple of 1024.
180 The debugging malloc I'm using has 24 bytes of overhead. */
181 obstack_begin (&notes, 5090);
182 obstack_begin (&cond_obstack, 990);
183
184 #define BIGNUM_BEGIN_SIZE (16)
185 bignum_low = xmalloc ((long) BIGNUM_BEGIN_SIZE);
186 bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
187
188 /* Use machine dependent syntax */
189 for (p = line_separator_chars; *p; p++)
190 is_end_of_line[*p] = 1;
191 /* Use more. FIXME-SOMEDAY. */
192 }
193 \f
194 /* set up pseudo-op tables */
195
196 struct hash_control *po_hash;
197
198 static const pseudo_typeS potable[] =
199 {
200 {"abort", s_abort, 0},
201 {"align", s_align_ptwo, 0},
202 {"ascii", stringer, 0},
203 {"asciz", stringer, 1},
204 /* block */
205 {"byte", cons, 1},
206 {"comm", s_comm, 0},
207 {"data", s_data, 0},
208 {"desc", s_desc, 0},
209 /* dim */
210 {"double", float_cons, 'd'},
211 /* dsect */
212 {"eject", listing_eject, 0}, /* Formfeed listing */
213 {"else", s_else, 0},
214 {"end", s_end, 0},
215 {"endif", s_endif, 0},
216 /* endef */
217 {"equ", s_set, 0},
218 /* err */
219 /* extend */
220 {"extern", s_ignore, 0}, /* We treat all undef as ext */
221 {"appfile", s_app_file, 1},
222 {"appline", s_app_line, 0},
223 {"file", s_app_file, 0},
224 {"fill", s_fill, 0},
225 {"float", float_cons, 'f'},
226 {"global", s_globl, 0},
227 {"globl", s_globl, 0},
228 {"hword", cons, 2},
229 {"if", s_if, 0},
230 {"ifdef", s_ifdef, 0},
231 {"ifeqs", s_ifeqs, 0},
232 {"ifndef", s_ifdef, 1},
233 {"ifnes", s_ifeqs, 1},
234 {"ifnotdef", s_ifdef, 1},
235 {"include", s_include, 0},
236 {"int", cons, 4},
237 {"lcomm", s_lcomm, 0},
238 {"lflags", listing_flags, 0}, /* Listing flags */
239 {"list", listing_list, 1}, /* Turn listing on */
240 {"long", cons, 4},
241 {"lsym", s_lsym, 0},
242 {"nolist", listing_list, 0}, /* Turn listing off */
243 {"octa", big_cons, 16},
244 {"org", s_org, 0},
245 {"psize", listing_psize, 0}, /* set paper size */
246 /* print */
247 {"quad", big_cons, 8},
248 {"sbttl", listing_title, 1}, /* Subtitle of listing */
249 /* scl */
250 /* sect */
251 {"set", s_set, 0},
252 {"short", cons, 2},
253 {"single", float_cons, 'f'},
254 /* size */
255 {"space", s_space, 0},
256 {"stabd", s_stab, 'd'},
257 {"stabn", s_stab, 'n'},
258 {"stabs", s_stab, 's'},
259 {"string", stringer, 1},
260 /* tag */
261 {"text", s_text, 0},
262 {"title", listing_title, 0}, /* Listing title */
263 /* type */
264 /* use */
265 /* val */
266 {"xstabs", s_xstab, 's'},
267 {"word", cons, 2},
268 {NULL} /* end sentinel */
269 };
270
271 static void
272 pobegin ()
273 {
274 char *errtxt; /* error text */
275 const pseudo_typeS *pop;
276
277 po_hash = hash_new ();
278
279 /* Do the target-specific pseudo ops. */
280 for (pop = md_pseudo_table; pop->poc_name; pop++)
281 {
282 errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
283 if (errtxt && *errtxt)
284 {
285 as_fatal ("error constructing md pseudo-op table");
286 } /* on error */
287 } /* for each op */
288
289 /* Now object specific. Skip any that were in the target table. */
290 for (pop = obj_pseudo_table; pop->poc_name; pop++)
291 {
292 errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
293 if (errtxt && *errtxt)
294 {
295 if (!strcmp (errtxt, "exists"))
296 {
297 #ifdef DIE_ON_OVERRIDES
298 as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
299 #endif /* DIE_ON_OVERRIDES */
300 continue; /* OK if target table overrides. */
301 }
302 else
303 {
304 as_fatal ("error constructing obj pseudo-op table");
305 } /* if overridden */
306 } /* on error */
307 } /* for each op */
308
309 /* Now portable ones. Skip any that we've seen already. */
310 for (pop = potable; pop->poc_name; pop++)
311 {
312 errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
313 if (errtxt && *errtxt)
314 {
315 if (!strcmp (errtxt, "exists"))
316 {
317 #ifdef DIE_ON_OVERRIDES
318 as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
319 #endif /* DIE_ON_OVERRIDES */
320 continue; /* OK if target table overrides. */
321 }
322 else
323 {
324 as_fatal ("error constructing obj pseudo-op table");
325 } /* if overridden */
326 } /* on error */
327 } /* for each op */
328
329 return;
330 } /* pobegin() */
331 \f
332 #define HANDLE_CONDITIONAL_ASSEMBLY() \
333 if (ignore_input ()) \
334 { \
335 while (! is_end_of_line[*input_line_pointer++]) \
336 if (input_line_pointer == buffer_limit) \
337 break; \
338 continue; \
339 }
340
341
342 /* read_a_source_file()
343 *
344 * We read the file, putting things into a web that
345 * represents what we have been reading.
346 */
347 void
348 read_a_source_file (name)
349 char *name;
350 {
351 register char c;
352 register char *s; /* string of symbol, '\0' appended */
353 register int temp;
354 pseudo_typeS *pop;
355
356 buffer = input_scrub_new_file (name);
357
358 listing_file (name);
359 listing_newline ("");
360
361 while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
362 { /* We have another line to parse. */
363 know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
364 contin: /* JF this goto is my fault I admit it.
365 Someone brave please re-write the whole
366 input section here? Pleeze??? */
367 while (input_line_pointer < buffer_limit)
368 {
369 /* We have more of this buffer to parse. */
370
371 /*
372 * We now have input_line_pointer->1st char of next line.
373 * If input_line_pointer [-1] == '\n' then we just
374 * scanned another line: so bump line counters.
375 */
376 if (input_line_pointer[-1] == '\n')
377 {
378 bump_line_counters ();
379
380 #ifdef MRI
381 /* Text at the start of a line must be a label, we run down and stick a colon in */
382 if (is_name_beginner (*input_line_pointer))
383 {
384 char *line_start = input_line_pointer;
385 char c = get_symbol_end ();
386 colon (line_start);
387 *input_line_pointer = c;
388 if (c == ':')
389 input_line_pointer++;
390
391 }
392 #endif
393 }
394
395
396 /*
397 * We are at the begining of a line, or similar place.
398 * We expect a well-formed assembler statement.
399 * A "symbol-name:" is a statement.
400 *
401 * Depending on what compiler is used, the order of these tests
402 * may vary to catch most common case 1st.
403 * Each test is independent of all other tests at the (top) level.
404 * PLEASE make a compiler that doesn't use this assembler.
405 * It is crufty to waste a compiler's time encoding things for this
406 * assembler, which then wastes more time decoding it.
407 * (And communicating via (linear) files is silly!
408 * If you must pass stuff, please pass a tree!)
409 */
410 if ((c = *input_line_pointer++) == '\t'
411 || c == ' '
412 || c == '\f'
413 || c == 0)
414 {
415 c = *input_line_pointer++;
416 }
417 know (c != ' '); /* No further leading whitespace. */
418 LISTING_NEWLINE ();
419 /*
420 * C is the 1st significant character.
421 * Input_line_pointer points after that character.
422 */
423 if (is_name_beginner (c))
424 { /* want user-defined label or pseudo/opcode */
425 HANDLE_CONDITIONAL_ASSEMBLY ();
426
427 s = --input_line_pointer;
428 c = get_symbol_end (); /* name's delimiter */
429 /*
430 * C is character after symbol.
431 * That character's place in the input line is now '\0'.
432 * S points to the beginning of the symbol.
433 * [In case of pseudo-op, s->'.'.]
434 * Input_line_pointer->'\0' where c was.
435 */
436 if (TC_START_LABEL(c, input_line_pointer))
437 {
438 colon (s); /* user-defined label */
439 *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
440 /* Input_line_pointer->after ':'. */
441 SKIP_WHITESPACE ();
442
443
444 }
445 else if (c == '='
446 || (input_line_pointer[1] == '='
447 #ifdef TC_EQUAL_IN_INSN
448 && ! TC_EQUAL_IN_INSN (c, input_line_pointer)
449 #endif
450 ))
451 {
452 equals (s);
453 demand_empty_rest_of_line ();
454 }
455 else
456 { /* expect pseudo-op or machine instruction */
457 #ifdef MRI
458 if (!done_pseudo (s))
459
460 #else
461
462 pop = NULL;
463
464 #ifdef NO_PSEUDO_DOT
465 /* The m88k uses pseudo-ops without a period. */
466 pop = (pseudo_typeS *) hash_find (po_hash, s);
467 if (pop != NULL && pop->poc_handler == NULL)
468 pop = NULL;
469 #endif
470
471 if (pop != NULL || *s == '.')
472 {
473 /*
474 * PSEUDO - OP.
475 *
476 * WARNING: c has next char, which may be end-of-line.
477 * We lookup the pseudo-op table with s+1 because we
478 * already know that the pseudo-op begins with a '.'.
479 */
480
481 if (pop == NULL)
482 pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
483
484 /* Print the error msg now, while we still can */
485 if (pop == NULL)
486 {
487 as_bad ("Unknown pseudo-op: `%s'", s);
488 *input_line_pointer = c;
489 s_ignore (0);
490 break;
491 }
492
493 /* Put it back for error messages etc. */
494 *input_line_pointer = c;
495 /* The following skip of whitespace is compulsory.
496 A well shaped space is sometimes all that separates
497 keyword from operands. */
498 if (c == ' ' || c == '\t')
499 {
500 input_line_pointer++;
501 } /* Skip seperator after keyword. */
502 /*
503 * Input_line is restored.
504 * Input_line_pointer->1st non-blank char
505 * after pseudo-operation.
506 */
507 if (!pop)
508 {
509 ignore_rest_of_line ();
510 break;
511 }
512 else
513 {
514 (*pop->poc_handler) (pop->poc_val);
515 } /* if we have one */
516 }
517 else
518 #endif
519 { /* machine instruction */
520 /* WARNING: c has char, which may be end-of-line. */
521 /* Also: input_line_pointer->`\0` where c was. */
522 *input_line_pointer = c;
523 while (!is_end_of_line[*input_line_pointer]
524 #ifdef TC_EOL_IN_INSN
525 || TC_EOL_IN_INSN (input_line_pointer)
526 #endif
527 )
528 {
529 input_line_pointer++;
530 }
531
532 c = *input_line_pointer;
533 *input_line_pointer = '\0';
534
535 md_assemble (s); /* Assemble 1 instruction. */
536
537 *input_line_pointer++ = c;
538
539 /* We resume loop AFTER the end-of-line from this instruction */
540 } /* if (*s=='.') */
541
542 } /* if c==':' */
543 continue;
544 } /* if (is_name_beginner(c) */
545
546
547 if (is_end_of_line[c])
548 {
549 continue;
550 } /* empty statement */
551
552
553 #if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
554 if (isdigit (c))
555 { /* local label ("4:") */
556 char *backup = input_line_pointer;
557
558 HANDLE_CONDITIONAL_ASSEMBLY ();
559
560 temp = c - '0';
561
562 while (isdigit (*input_line_pointer))
563 {
564 temp = (temp * 10) + *input_line_pointer - '0';
565 ++input_line_pointer;
566 } /* read the whole number */
567
568 #ifdef LOCAL_LABELS_DOLLAR
569 if (*input_line_pointer == '$'
570 && *(input_line_pointer + 1) == ':')
571 {
572 input_line_pointer += 2;
573
574 if (dollar_label_defined (temp))
575 {
576 as_fatal ("label \"%d$\" redefined", temp);
577 }
578
579 define_dollar_label (temp);
580 colon (dollar_label_name (temp, 0));
581 continue;
582 }
583 #endif /* LOCAL_LABELS_DOLLAR */
584
585 #ifdef LOCAL_LABELS_FB
586 if (*input_line_pointer++ == ':')
587 {
588 fb_label_instance_inc (temp);
589 colon (fb_label_name (temp, 0));
590 continue;
591 }
592 #endif /* LOCAL_LABELS_FB */
593
594 input_line_pointer = backup;
595 } /* local label ("4:") */
596 #endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
597
598 if (c && strchr (line_comment_chars, c))
599 { /* Its a comment. Better say APP or NO_APP */
600 char *ends;
601 char *new_buf;
602 char *new_tmp;
603 int new_length;
604 char *tmp_buf = 0;
605 extern char *scrub_string, *scrub_last_string;
606
607 bump_line_counters ();
608 s = input_line_pointer;
609 if (strncmp (s, "APP\n", 4))
610 continue; /* We ignore it */
611 s += 4;
612
613 ends = strstr (s, "#NO_APP\n");
614
615 if (!ends)
616 {
617 int tmp_len;
618 int num;
619
620 /* The end of the #APP wasn't in this buffer. We
621 keep reading in buffers until we find the #NO_APP
622 that goes with this #APP There is one. The specs
623 guarentee it. . . */
624 tmp_len = buffer_limit - s;
625 tmp_buf = xmalloc (tmp_len + 1);
626 memcpy (tmp_buf, s, tmp_len);
627 do
628 {
629 new_tmp = input_scrub_next_buffer (&buffer);
630 if (!new_tmp)
631 break;
632 else
633 buffer_limit = new_tmp;
634 input_line_pointer = buffer;
635 ends = strstr (buffer, "#NO_APP\n");
636 if (ends)
637 num = ends - buffer;
638 else
639 num = buffer_limit - buffer;
640
641 tmp_buf = xrealloc (tmp_buf, tmp_len + num);
642 memcpy (tmp_buf, buffer + tmp_len, num);
643 tmp_len += num;
644 }
645 while (!ends);
646
647 input_line_pointer = ends ? ends + 8 : NULL;
648
649 s = tmp_buf;
650 ends = s + tmp_len;
651
652 }
653 else
654 {
655 input_line_pointer = ends + 8;
656 }
657 new_buf = xmalloc (100);
658 new_length = 100;
659 new_tmp = new_buf;
660
661 scrub_string = s;
662 scrub_last_string = ends;
663 for (;;)
664 {
665 int ch;
666
667 ch = do_scrub_next_char (scrub_from_string, scrub_to_string);
668 if (ch == EOF)
669 break;
670 *new_tmp++ = ch;
671 if (new_tmp == new_buf + new_length)
672 {
673 new_buf = xrealloc (new_buf, new_length + 100);
674 new_tmp = new_buf + new_length;
675 new_length += 100;
676 }
677 }
678
679 if (tmp_buf)
680 free (tmp_buf);
681 old_buffer = buffer;
682 old_input = input_line_pointer;
683 old_limit = buffer_limit;
684 buffer = new_buf;
685 input_line_pointer = new_buf;
686 buffer_limit = new_tmp;
687 continue;
688 }
689
690 HANDLE_CONDITIONAL_ASSEMBLY ();
691
692 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
693 input_line_pointer--; /* Report unknown char as ignored. */
694 ignore_rest_of_line ();
695 } /* while (input_line_pointer<buffer_limit) */
696 if (old_buffer)
697 {
698 bump_line_counters ();
699 if (old_input != 0)
700 {
701 buffer = old_buffer;
702 input_line_pointer = old_input;
703 buffer_limit = old_limit;
704 old_buffer = 0;
705 goto contin;
706 }
707 }
708 } /* while (more buffers to scan) */
709 input_scrub_close (); /* Close the input file */
710
711 } /* read_a_source_file() */
712
713 void
714 s_abort ()
715 {
716 as_fatal (".abort detected. Abandoning ship.");
717 } /* s_abort() */
718
719 /* For machines where ".align 4" means align to a 4 byte boundary. */
720 void
721 s_align_bytes (arg)
722 int arg;
723 {
724 register unsigned int temp;
725 register long temp_fill;
726 unsigned int i = 0;
727 unsigned long max_alignment = 1 << 15;
728
729 if (is_end_of_line[*input_line_pointer])
730 temp = arg; /* Default value from pseudo-op table */
731 else
732 temp = get_absolute_expression ();
733
734 if (temp > max_alignment)
735 {
736 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
737 }
738
739 /*
740 * For the sparc, `.align (1<<n)' actually means `.align n'
741 * so we have to convert it.
742 */
743 if (temp != 0)
744 {
745 for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
746 ;
747 }
748 if (temp != 1)
749 as_bad ("Alignment not a power of 2");
750
751 temp = i;
752 if (*input_line_pointer == ',')
753 {
754 input_line_pointer++;
755 temp_fill = get_absolute_expression ();
756 }
757 else if (now_seg != data_section && now_seg != bss_section)
758 temp_fill = NOP_OPCODE;
759 else
760 temp_fill = 0;
761 /* Only make a frag if we HAVE to. . . */
762 if (temp && !need_pass_2)
763 frag_align (temp, (int) temp_fill);
764
765 record_alignment (now_seg, temp);
766
767 demand_empty_rest_of_line ();
768 } /* s_align_bytes() */
769
770 /* For machines where ".align 4" means align to 2**4 boundary. */
771 void
772 s_align_ptwo ()
773 {
774 register int temp;
775 register long temp_fill;
776 long max_alignment = 15;
777
778 temp = get_absolute_expression ();
779 if (temp > max_alignment)
780 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
781 else if (temp < 0)
782 {
783 as_bad ("Alignment negative. 0 assumed.");
784 temp = 0;
785 }
786 if (*input_line_pointer == ',')
787 {
788 input_line_pointer++;
789 temp_fill = get_absolute_expression ();
790 }
791 /* @@ Fix this right for BFD! */
792 else if (now_seg != data_section && now_seg != bss_section)
793 temp_fill = NOP_OPCODE;
794 else
795 temp_fill = 0;
796 /* Only make a frag if we HAVE to. . . */
797 if (temp && !need_pass_2)
798 frag_align (temp, (int) temp_fill);
799
800 record_alignment (now_seg, temp);
801
802 demand_empty_rest_of_line ();
803 } /* s_align_ptwo() */
804
805 void
806 s_comm ()
807 {
808 register char *name;
809 register char c;
810 register char *p;
811 valueT temp;
812 register symbolS *symbolP;
813
814 name = input_line_pointer;
815 c = get_symbol_end ();
816 /* just after name is now '\0' */
817 p = input_line_pointer;
818 *p = c;
819 SKIP_WHITESPACE ();
820 if (*input_line_pointer != ',')
821 {
822 as_bad ("Expected comma after symbol-name: rest of line ignored.");
823 ignore_rest_of_line ();
824 return;
825 }
826 input_line_pointer++; /* skip ',' */
827 if ((temp = get_absolute_expression ()) < 0)
828 {
829 as_warn (".COMMon length (%d.) <0! Ignored.", temp);
830 ignore_rest_of_line ();
831 return;
832 }
833 *p = 0;
834 symbolP = symbol_find_or_make (name);
835 *p = c;
836 if (S_IS_DEFINED (symbolP))
837 {
838 as_bad ("Ignoring attempt to re-define symbol");
839 ignore_rest_of_line ();
840 return;
841 }
842 if (S_GET_VALUE (symbolP))
843 {
844 if (S_GET_VALUE (symbolP) != temp)
845 as_bad ("Length of .comm \"%s\" is already %d. Not changed to %d.",
846 S_GET_NAME (symbolP),
847 S_GET_VALUE (symbolP),
848 temp);
849 }
850 else
851 {
852 S_SET_VALUE (symbolP, temp);
853 S_SET_EXTERNAL (symbolP);
854 }
855 #ifdef OBJ_VMS
856 if ( (!temp) || !flagseen['1'])
857 S_GET_OTHER(symbolP) = const_flag;
858 #endif /* not OBJ_VMS */
859 know (symbolP->sy_frag == &zero_address_frag);
860 demand_empty_rest_of_line ();
861 } /* s_comm() */
862
863 void
864 s_data ()
865 {
866 segT section;
867 register int temp;
868
869 temp = get_absolute_expression ();
870 if (flagseen['R'])
871 {
872 section = text_section;
873 temp += 1000;
874 }
875 else
876 section = data_section;
877
878 #ifdef BFD_ASSEMBLER
879 subseg_set (section, (subsegT) temp);
880 #else
881 subseg_new (section, (subsegT) temp);
882 #endif
883
884 #ifdef OBJ_VMS
885 const_flag = 0;
886 #endif
887 demand_empty_rest_of_line ();
888 }
889
890 /* Handle the .appfile pseudo-op. This is automatically generated by
891 do_scrub_next_char when a preprocessor # line comment is seen with
892 a file name. This default definition may be overridden by the
893 object or CPU specific pseudo-ops. This function is also the
894 default definition for .file; the APPFILE argument is 1 for
895 .appfile, 0 for .file. */
896
897 void
898 s_app_file (appfile)
899 int appfile;
900 {
901 register char *s;
902 int length;
903
904 /* Some assemblers tolerate immediately following '"' */
905 if ((s = demand_copy_string (&length)) != 0)
906 {
907 /* If this is a fake .appfile, a fake newline was inserted into
908 the buffer. Passing -2 to new_logical_line tells it to
909 account for it. */
910 new_logical_line (s, appfile ? -2 : -1);
911 demand_empty_rest_of_line ();
912 #ifdef LISTING
913 if (listing)
914 listing_source_file (s);
915 #endif
916 }
917 #ifdef OBJ_COFF
918 c_dot_file_symbol (s);
919 #endif /* OBJ_COFF */
920 #ifdef OBJ_ELF
921 elf_file_symbol (s);
922 #endif
923 }
924
925 /* Handle the .appline pseudo-op. This is automatically generated by
926 do_scrub_next_char when a preprocessor # line comment is seen.
927 This default definition may be overridden by the object or CPU
928 specific pseudo-ops. */
929
930 void
931 s_app_line ()
932 {
933 int l;
934
935 /* The given number is that of the next line. */
936 l = get_absolute_expression () - 1;
937 new_logical_line ((char *) NULL, l);
938 #ifdef LISTING
939 if (listing)
940 listing_source_line (l);
941 #endif
942 demand_empty_rest_of_line ();
943 }
944
945 void
946 s_fill ()
947 {
948 long temp_repeat = 0;
949 long temp_size = 1;
950 register long temp_fill = 0;
951 char *p;
952
953
954 temp_repeat = get_absolute_expression ();
955 if (*input_line_pointer == ',')
956 {
957 input_line_pointer++;
958 temp_size = get_absolute_expression ();
959 if (*input_line_pointer == ',')
960 {
961 input_line_pointer++;
962 temp_fill = get_absolute_expression ();
963 }
964 }
965 /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */
966 #define BSD_FILL_SIZE_CROCK_8 (8)
967 if (temp_size > BSD_FILL_SIZE_CROCK_8)
968 {
969 as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
970 temp_size = BSD_FILL_SIZE_CROCK_8;
971 }
972 if (temp_size < 0)
973 {
974 as_warn ("Size negative: .fill ignored.");
975 temp_size = 0;
976 }
977 else if (temp_repeat <= 0)
978 {
979 as_warn ("Repeat < 0, .fill ignored");
980 temp_size = 0;
981 }
982
983 if (temp_size && !need_pass_2)
984 {
985 p = frag_var (rs_fill, (int) temp_size, (int) temp_size, (relax_substateT) 0, (symbolS *) 0, temp_repeat, (char *) 0);
986 memset (p, 0, (int) temp_size);
987 /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
988 * flavoured AS. The following bizzare behaviour is to be
989 * compatible with above. I guess they tried to take up to 8
990 * bytes from a 4-byte expression and they forgot to sign
991 * extend. Un*x Sux. */
992 #define BSD_FILL_SIZE_CROCK_4 (4)
993 md_number_to_chars (p, temp_fill,
994 (temp_size > BSD_FILL_SIZE_CROCK_4
995 ? BSD_FILL_SIZE_CROCK_4
996 : (int) temp_size));
997 /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
998 * but emits no error message because it seems a legal thing to do.
999 * It is a degenerate case of .fill but could be emitted by a compiler.
1000 */
1001 }
1002 demand_empty_rest_of_line ();
1003 }
1004
1005 void
1006 s_globl ()
1007 {
1008 char *name;
1009 int c;
1010 symbolS *symbolP;
1011
1012 do
1013 {
1014 name = input_line_pointer;
1015 c = get_symbol_end ();
1016 symbolP = symbol_find_or_make (name);
1017 *input_line_pointer = c;
1018 SKIP_WHITESPACE ();
1019 S_SET_EXTERNAL (symbolP);
1020 if (c == ',')
1021 {
1022 input_line_pointer++;
1023 SKIP_WHITESPACE ();
1024 if (*input_line_pointer == '\n')
1025 c = '\n';
1026 }
1027 }
1028 while (c == ',');
1029 demand_empty_rest_of_line ();
1030 }
1031
1032 void
1033 s_lcomm (needs_align)
1034 /* 1 if this was a ".bss" directive, which may require a 3rd argument
1035 (alignment); 0 if it was an ".lcomm" (2 args only) */
1036 int needs_align;
1037 {
1038 register char *name;
1039 register char c;
1040 register char *p;
1041 register int temp;
1042 register symbolS *symbolP;
1043 segT current_seg = now_seg;
1044 subsegT current_subseg = now_subseg;
1045 const int max_alignment = 15;
1046 int align = 0;
1047 segT bss_seg = bss_section;
1048
1049 name = input_line_pointer;
1050 c = get_symbol_end ();
1051 p = input_line_pointer;
1052 *p = c;
1053 SKIP_WHITESPACE ();
1054 if (*input_line_pointer != ',')
1055 {
1056 as_bad ("Expected comma after name");
1057 ignore_rest_of_line ();
1058 return;
1059 }
1060
1061 ++input_line_pointer;
1062
1063 if (*input_line_pointer == '\n')
1064 {
1065 as_bad ("Missing size expression");
1066 return;
1067 }
1068
1069 if ((temp = get_absolute_expression ()) < 0)
1070 {
1071 as_warn ("BSS length (%d.) <0! Ignored.", temp);
1072 ignore_rest_of_line ();
1073 return;
1074 }
1075
1076 #ifdef TC_MIPS
1077 #ifdef OBJ_ECOFF
1078 /* For MIPS ECOFF, small objects are put in .sbss. */
1079 if (temp <= bfd_get_gp_size (stdoutput))
1080 bss_seg = subseg_new (".sbss", 1);
1081 #endif
1082 #endif
1083
1084 if (needs_align)
1085 {
1086 align = 0;
1087 SKIP_WHITESPACE ();
1088 if (*input_line_pointer != ',')
1089 {
1090 as_bad ("Expected comma after size");
1091 ignore_rest_of_line ();
1092 return;
1093 }
1094 input_line_pointer++;
1095 SKIP_WHITESPACE ();
1096 if (*input_line_pointer == '\n')
1097 {
1098 as_bad ("Missing alignment");
1099 return;
1100 }
1101 align = get_absolute_expression ();
1102 if (align > max_alignment)
1103 {
1104 align = max_alignment;
1105 as_warn ("Alignment too large: %d. assumed.", align);
1106 }
1107 else if (align < 0)
1108 {
1109 align = 0;
1110 as_warn ("Alignment negative. 0 assumed.");
1111 }
1112 record_alignment (bss_seg, align);
1113 } /* if needs align */
1114
1115 *p = 0;
1116 symbolP = symbol_find_or_make (name);
1117 *p = c;
1118
1119 if (
1120 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1121 S_GET_OTHER (symbolP) == 0 &&
1122 S_GET_DESC (symbolP) == 0 &&
1123 #endif /* OBJ_AOUT or OBJ_BOUT */
1124 (S_GET_SEGMENT (symbolP) == bss_seg
1125 || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
1126 {
1127 char *p;
1128
1129 #ifdef BFD_ASSEMBLER
1130 subseg_set (bss_seg, 1);
1131 #else
1132 subseg_new (bss_seg, 1);
1133 #endif
1134
1135 if (align)
1136 frag_align (align, 0);
1137 /* detach from old frag */
1138 if (S_GET_SEGMENT (symbolP) == bss_seg)
1139 symbolP->sy_frag->fr_symbol = NULL;
1140
1141 symbolP->sy_frag = frag_now;
1142 p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
1143 temp, (char *)0);
1144 *p = 0;
1145
1146 S_SET_SEGMENT (symbolP, bss_seg);
1147
1148 #ifdef OBJ_COFF
1149 /* The symbol may already have been created with a preceding
1150 ".globl" directive -- be careful not to step on storage class
1151 in that case. Otherwise, set it to static. */
1152 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
1153 {
1154 S_SET_STORAGE_CLASS (symbolP, C_STAT);
1155 }
1156 #endif /* OBJ_COFF */
1157 }
1158 else
1159 {
1160 as_bad ("Ignoring attempt to re-define symbol %s.", name);
1161 }
1162
1163 #ifdef BFD_ASSEMBLER
1164 subseg_set (current_seg, current_subseg);
1165 #else
1166 subseg_new (current_seg, current_subseg);
1167 #endif
1168
1169 demand_empty_rest_of_line ();
1170 } /* s_lcomm() */
1171
1172 void
1173 s_long ()
1174 {
1175 cons (4);
1176 }
1177
1178 void
1179 s_int ()
1180 {
1181 cons (4);
1182 }
1183
1184 void
1185 s_lsym ()
1186 {
1187 register char *name;
1188 register char c;
1189 register char *p;
1190 expressionS exp;
1191 register symbolS *symbolP;
1192
1193 /* we permit ANY defined expression: BSD4.2 demands constants */
1194 name = input_line_pointer;
1195 c = get_symbol_end ();
1196 p = input_line_pointer;
1197 *p = c;
1198 SKIP_WHITESPACE ();
1199 if (*input_line_pointer != ',')
1200 {
1201 *p = 0;
1202 as_bad ("Expected comma after name \"%s\"", name);
1203 *p = c;
1204 ignore_rest_of_line ();
1205 return;
1206 }
1207 input_line_pointer++;
1208 expression (&exp);
1209 if (exp.X_op != O_constant
1210 && exp.X_op != O_register)
1211 {
1212 as_bad ("bad expression");
1213 ignore_rest_of_line ();
1214 return;
1215 }
1216 *p = 0;
1217 symbolP = symbol_find_or_make (name);
1218
1219 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 &&
1220 symbolP->sy_desc == 0) out of this test because coff doesn't have
1221 those fields, and I can't see when they'd ever be tripped. I
1222 don't think I understand why they were here so I may have
1223 introduced a bug. As recently as 1.37 didn't have this test
1224 anyway. xoxorich. */
1225
1226 if (S_GET_SEGMENT (symbolP) == undefined_section
1227 && S_GET_VALUE (symbolP) == 0)
1228 {
1229 /* The name might be an undefined .global symbol; be sure to
1230 keep the "external" bit. */
1231 S_SET_SEGMENT (symbolP,
1232 (exp.X_op == O_constant
1233 ? absolute_section
1234 : reg_section));
1235 S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
1236 }
1237 else
1238 {
1239 as_bad ("Symbol %s already defined", name);
1240 }
1241 *p = c;
1242 demand_empty_rest_of_line ();
1243 } /* s_lsym() */
1244
1245 void
1246 s_org ()
1247 {
1248 register segT segment;
1249 expressionS exp;
1250 register long temp_fill;
1251 register char *p;
1252 /* Don't believe the documentation of BSD 4.2 AS. There is no such
1253 thing as a sub-segment-relative origin. Any absolute origin is
1254 given a warning, then assumed to be segment-relative. Any
1255 segmented origin expression ("foo+42") had better be in the right
1256 segment or the .org is ignored.
1257
1258 BSD 4.2 AS warns if you try to .org backwards. We cannot because
1259 we never know sub-segment sizes when we are reading code. BSD
1260 will crash trying to emit negative numbers of filler bytes in
1261 certain .orgs. We don't crash, but see as-write for that code.
1262
1263 Don't make frag if need_pass_2==1. */
1264 segment = get_known_segmented_expression (&exp);
1265 if (*input_line_pointer == ',')
1266 {
1267 input_line_pointer++;
1268 temp_fill = get_absolute_expression ();
1269 }
1270 else
1271 temp_fill = 0;
1272 if (!need_pass_2)
1273 {
1274 if (segment != now_seg && segment != absolute_section)
1275 as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1276 segment_name (segment), segment_name (now_seg));
1277 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1278 exp.X_add_number, (char *) 0);
1279 *p = temp_fill;
1280 } /* if (ok to make frag) */
1281 demand_empty_rest_of_line ();
1282 } /* s_org() */
1283
1284 void
1285 s_set ()
1286 {
1287 register char *name;
1288 register char delim;
1289 register char *end_name;
1290 register symbolS *symbolP;
1291
1292 /*
1293 * Especial apologies for the random logic:
1294 * this just grew, and could be parsed much more simply!
1295 * Dean in haste.
1296 */
1297 name = input_line_pointer;
1298 delim = get_symbol_end ();
1299 end_name = input_line_pointer;
1300 *end_name = delim;
1301 SKIP_WHITESPACE ();
1302
1303 if (*input_line_pointer != ',')
1304 {
1305 *end_name = 0;
1306 as_bad ("Expected comma after name \"%s\"", name);
1307 *end_name = delim;
1308 ignore_rest_of_line ();
1309 return;
1310 }
1311
1312 input_line_pointer++;
1313 *end_name = 0;
1314
1315 if (name[0] == '.' && name[1] == '\0')
1316 {
1317 /* Turn '. = mumble' into a .org mumble */
1318 register segT segment;
1319 expressionS exp;
1320 register char *ptr;
1321
1322 segment = get_known_segmented_expression (&exp);
1323
1324 if (!need_pass_2)
1325 {
1326 if (segment != now_seg && segment != absolute_section)
1327 as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1328 segment_name (segment),
1329 segment_name (now_seg));
1330 ptr = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1331 exp.X_add_number, (char *) 0);
1332 *ptr = 0;
1333 } /* if (ok to make frag) */
1334
1335 *end_name = delim;
1336 return;
1337 }
1338
1339 if ((symbolP = symbol_find (name)) == NULL
1340 && (symbolP = md_undefined_symbol (name)) == NULL)
1341 {
1342 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1343 #ifdef OBJ_COFF
1344 /* "set" symbols are local unless otherwise specified. */
1345 SF_SET_LOCAL (symbolP);
1346 #endif /* OBJ_COFF */
1347
1348 } /* make a new symbol */
1349
1350 symbol_table_insert (symbolP);
1351
1352 *end_name = delim;
1353 pseudo_set (symbolP);
1354 demand_empty_rest_of_line ();
1355 } /* s_set() */
1356
1357 void
1358 s_space (mult)
1359 int mult;
1360 {
1361 long temp_repeat;
1362 register long temp_fill;
1363 register char *p;
1364
1365 /* Just like .fill, but temp_size = 1 */
1366 if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
1367 {
1368 temp_fill = get_absolute_expression ();
1369 }
1370 else
1371 {
1372 input_line_pointer--; /* Backup over what was not a ','. */
1373 temp_fill = 0;
1374 }
1375 if (mult)
1376 {
1377 temp_repeat *= mult;
1378 }
1379 if (temp_repeat <= 0)
1380 {
1381 as_warn ("Repeat < 0, .space ignored");
1382 ignore_rest_of_line ();
1383 return;
1384 }
1385 if (!need_pass_2)
1386 {
1387 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
1388 temp_repeat, (char *) 0);
1389 *p = temp_fill;
1390 }
1391 demand_empty_rest_of_line ();
1392 } /* s_space() */
1393
1394 void
1395 s_text ()
1396 {
1397 register int temp;
1398
1399 temp = get_absolute_expression ();
1400 #ifdef BFD_ASSEMBLER
1401 subseg_set (text_section, (subsegT) temp);
1402 #else
1403 subseg_new (text_section, (subsegT) temp);
1404 #endif
1405 demand_empty_rest_of_line ();
1406 } /* s_text() */
1407 \f
1408
1409 void
1410 demand_empty_rest_of_line ()
1411 {
1412 SKIP_WHITESPACE ();
1413 if (is_end_of_line[*input_line_pointer])
1414 {
1415 input_line_pointer++;
1416 }
1417 else
1418 {
1419 ignore_rest_of_line ();
1420 }
1421 /* Return having already swallowed end-of-line. */
1422 } /* Return pointing just after end-of-line. */
1423
1424 void
1425 ignore_rest_of_line () /* For suspect lines: gives warning. */
1426 {
1427 if (!is_end_of_line[*input_line_pointer])
1428 {
1429 if (isprint (*input_line_pointer))
1430 as_bad ("Rest of line ignored. First ignored character is `%c'.",
1431 *input_line_pointer);
1432 else
1433 as_bad ("Rest of line ignored. First ignored character valued 0x%x.",
1434 *input_line_pointer);
1435 while (input_line_pointer < buffer_limit
1436 && !is_end_of_line[*input_line_pointer])
1437 {
1438 input_line_pointer++;
1439 }
1440 }
1441 input_line_pointer++; /* Return pointing just after end-of-line. */
1442 know (is_end_of_line[input_line_pointer[-1]]);
1443 }
1444
1445 /*
1446 * pseudo_set()
1447 *
1448 * In: Pointer to a symbol.
1449 * Input_line_pointer->expression.
1450 *
1451 * Out: Input_line_pointer->just after any whitespace after expression.
1452 * Tried to set symbol to value of expression.
1453 * Will change symbols type, value, and frag;
1454 */
1455 void
1456 pseudo_set (symbolP)
1457 symbolS *symbolP;
1458 {
1459 expressionS exp;
1460 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1461 int ext;
1462 #endif /* OBJ_AOUT or OBJ_BOUT */
1463
1464 know (symbolP); /* NULL pointer is logic error. */
1465 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1466 /* @@ Fix this right for BFD. */
1467 ext = S_IS_EXTERNAL (symbolP);
1468 #endif /* OBJ_AOUT or OBJ_BOUT */
1469
1470 (void) expression (&exp);
1471
1472 if (exp.X_op == O_illegal)
1473 as_bad ("illegal expression; zero assumed");
1474 else if (exp.X_op == O_absent)
1475 as_bad ("missing expression; zero assumed");
1476 else if (exp.X_op == O_big)
1477 as_bad ("%s number invalid; zero assumed",
1478 exp.X_add_number > 0 ? "bignum" : "floating point");
1479 else if (exp.X_op == O_subtract
1480 && (S_GET_SEGMENT (exp.X_add_symbol)
1481 == S_GET_SEGMENT (exp.X_op_symbol))
1482 && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol))
1483 && exp.X_add_symbol->sy_frag == exp.X_op_symbol->sy_frag)
1484 {
1485 exp.X_op = O_constant;
1486 exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol)
1487 - S_GET_VALUE (exp.X_op_symbol));
1488 }
1489
1490 switch (exp.X_op)
1491 {
1492 case O_illegal:
1493 case O_absent:
1494 case O_big:
1495 exp.X_add_number = 0;
1496 /* Fall through. */
1497 case O_constant:
1498 S_SET_SEGMENT (symbolP, absolute_section);
1499 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1500 /* @@ Fix this right for BFD. */
1501 if (ext)
1502 S_SET_EXTERNAL (symbolP);
1503 else
1504 S_CLEAR_EXTERNAL (symbolP);
1505 #endif /* OBJ_AOUT or OBJ_BOUT */
1506 S_SET_VALUE (symbolP, exp.X_add_number);
1507 symbolP->sy_frag = &zero_address_frag;
1508 break;
1509
1510 case O_register:
1511 S_SET_SEGMENT (symbolP, reg_section);
1512 S_SET_VALUE (symbolP, exp.X_add_number);
1513 symbolP->sy_frag = &zero_address_frag;
1514 break;
1515
1516 case O_symbol:
1517 if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section)
1518 symbolP->sy_value = exp;
1519 else
1520 {
1521 S_SET_SEGMENT (symbolP, S_GET_SEGMENT (exp.X_add_symbol));
1522 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1523 /* @@ Fix this right for BFD! */
1524 if (ext)
1525 S_SET_EXTERNAL (symbolP);
1526 else
1527 S_CLEAR_EXTERNAL (symbolP);
1528 #endif /* OBJ_AOUT or OBJ_BOUT */
1529 S_SET_VALUE (symbolP,
1530 exp.X_add_number + S_GET_VALUE (exp.X_add_symbol));
1531 symbolP->sy_frag = exp.X_add_symbol->sy_frag;
1532 }
1533 break;
1534
1535 default:
1536 /* The value is some complex expression.
1537 FIXME: Should we set the segment to anything? */
1538 symbolP->sy_value = exp;
1539 break;
1540 }
1541 }
1542 \f
1543 /*
1544 * cons()
1545 *
1546 * CONStruct more frag of .bytes, or .words etc.
1547 * Should need_pass_2 be 1 then emit no frag(s).
1548 * This understands EXPRESSIONS, as opposed to big_cons().
1549 *
1550 * Bug (?)
1551 *
1552 * This has a split personality. We use expression() to read the
1553 * value. We can detect if the value won't fit in a byte or word.
1554 * But we can't detect if expression() discarded significant digits
1555 * in the case of a long. Not worth the crocks required to fix it.
1556 */
1557
1558 /* Select a parser for cons expressions. */
1559
1560 /* Some targets need to parse the expression in various fancy ways.
1561 You can define TC_PARSE_CONS_EXPRESSION to do whatever you like
1562 (for example, the HPPA does this). Otherwise, you can define
1563 BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or
1564 REPEAT_CONS_EXPRESSIONS to permit repeat counts. If none of these
1565 are defined, which is the normal case, then only simple expressions
1566 are permitted. */
1567
1568 #ifndef TC_PARSE_CONS_EXPRESSION
1569 #ifdef BITFIELD_CONS_EXPRESSIONS
1570 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
1571 static void
1572 parse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes));
1573 #endif
1574 #ifdef MRI
1575 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_mri_cons (EXP)
1576 static void
1577 parse_mri_cons PARAMS ((expressionS *exp));
1578 #endif
1579 #ifdef REPEAT_CONS_EXPRESSIONS
1580 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
1581 static void
1582 parse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes));
1583 #endif
1584
1585 /* If we haven't gotten one yet, just call expression. */
1586 #ifndef TC_PARSE_CONS_EXPRESSION
1587 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
1588 #endif
1589 #endif
1590
1591 /* worker to do .byte etc statements */
1592 /* clobbers input_line_pointer, checks */
1593 /* end-of-line. */
1594 void
1595 cons (nbytes)
1596 register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
1597 {
1598 expressionS exp;
1599
1600 if (is_it_end_of_statement ())
1601 {
1602 demand_empty_rest_of_line ();
1603 return;
1604 }
1605
1606 do
1607 {
1608 TC_PARSE_CONS_EXPRESSION (&exp, nbytes);
1609 emit_expr (&exp, nbytes);
1610 }
1611 while (*input_line_pointer++ == ',');
1612
1613 input_line_pointer--; /* Put terminator back into stream. */
1614 demand_empty_rest_of_line ();
1615 } /* cons() */
1616
1617 /* Put the contents of expression EXP into the object file using
1618 NBYTES bytes. If need_pass_2 is 1, this does nothing. */
1619
1620 void
1621 emit_expr (exp, nbytes)
1622 expressionS *exp;
1623 unsigned int nbytes;
1624 {
1625 operatorT op;
1626 register char *p;
1627
1628 /* Don't do anything if we are going to make another pass. */
1629 if (need_pass_2)
1630 return;
1631
1632 op = exp->X_op;
1633
1634 if (op == O_absent || op == O_illegal)
1635 {
1636 as_warn ("zero assumed for missing expression");
1637 exp->X_add_number = 0;
1638 op = O_constant;
1639 }
1640 else if (op == O_big)
1641 {
1642 as_bad ("%s number invalid; zero assumed",
1643 exp->X_add_number > 0 ? "bignum" : "floating point");
1644 exp->X_add_number = 0;
1645 op = O_constant;
1646 }
1647 else if (op == O_register)
1648 {
1649 as_warn ("register value used as expression");
1650 op = O_constant;
1651 }
1652
1653 p = frag_more (nbytes);
1654
1655 #ifndef WORKING_DOT_WORD
1656 /* If we have the difference of two symbols in a word, save it on
1657 the broken_words list. See the code in write.c. */
1658 if (op == O_subtract && nbytes == 2)
1659 {
1660 struct broken_word *x;
1661
1662 x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
1663 x->next_broken_word = broken_words;
1664 broken_words = x;
1665 x->frag = frag_now;
1666 x->word_goes_here = p;
1667 x->dispfrag = 0;
1668 x->add = exp->X_add_symbol;
1669 x->sub = exp->X_op_symbol;
1670 x->addnum = exp->X_add_number;
1671 x->added = 0;
1672 new_broken_words++;
1673 return;
1674 }
1675 #endif
1676
1677 if (op == O_constant)
1678 {
1679 register long get;
1680 register long use;
1681 register long mask;
1682 register long unmask;
1683
1684 /* JF << of >= number of bits in the object is undefined. In
1685 particular SPARC (Sun 4) has problems */
1686 if (nbytes >= sizeof (long))
1687 mask = 0;
1688 else
1689 mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
1690
1691 unmask = ~mask; /* Do store these bits. */
1692
1693 #ifdef NEVER
1694 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1695 mask = ~(unmask >> 1); /* Includes sign bit now. */
1696 #endif
1697
1698 get = exp->X_add_number;
1699 use = get & unmask;
1700 if ((get & mask) != 0 && (get & mask) != mask)
1701 { /* Leading bits contain both 0s & 1s. */
1702 as_warn ("Value 0x%x truncated to 0x%x.", get, use);
1703 }
1704 md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
1705 }
1706 else
1707 {
1708 md_number_to_chars (p, (long) 0, nbytes);
1709
1710 /* Now we need to generate a fixS to record the symbol value.
1711 This is easy for BFD. For other targets it can be more
1712 complex. For very complex cases (currently, the HPPA and
1713 NS32K), you can define TC_CONS_FIX_NEW to do whatever you
1714 want. For simpler cases, you can define TC_CONS_RELOC to be
1715 the name of the reloc code that should be stored in the fixS.
1716 If neither is defined, the code uses NO_RELOC if it is
1717 defined, and otherwise uses 0. */
1718
1719 #ifdef BFD_ASSEMBLER
1720 #ifdef TC_CONS_FIX_NEW
1721 TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
1722 #else
1723 fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes, exp, 0,
1724 /* @@ Should look at CPU word size. */
1725 nbytes == 2 ? BFD_RELOC_16
1726 : nbytes == 8 ? BFD_RELOC_64
1727 : BFD_RELOC_32);
1728 #endif
1729 #else
1730 #ifdef TC_CONS_FIX_NEW
1731 TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
1732 #else
1733 /* Figure out which reloc number to use. Use TC_CONS_RELOC if
1734 it is defined, otherwise use NO_RELOC if it is defined,
1735 otherwise use 0. */
1736 #ifndef TC_CONS_RELOC
1737 #ifdef NO_RELOC
1738 #define TC_CONS_RELOC NO_RELOC
1739 #else
1740 #define TC_CONS_RELOC 0
1741 #endif
1742 #endif
1743 fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes, exp, 0,
1744 TC_CONS_RELOC);
1745 #endif /* TC_CONS_FIX_NEW */
1746 #endif /* BFD_ASSEMBLER */
1747 }
1748 }
1749 \f
1750 #ifdef BITFIELD_CONS_EXPRESSIONS
1751
1752 /* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as
1753 w:x,y:z, where w and y are bitwidths and x and y are values. They
1754 then pack them all together. We do a little better in that we allow
1755 them in words, longs, etc. and we'll pack them in target byte order
1756 for you.
1757
1758 The rules are: pack least significat bit first, if a field doesn't
1759 entirely fit, put it in the next unit. Overflowing the bitfield is
1760 explicitly *not* even a warning. The bitwidth should be considered
1761 a "mask".
1762
1763 To use this function the tc-XXX.h file should define
1764 BITFIELD_CONS_EXPRESSIONS. */
1765
1766 static void
1767 parse_bitfield_cons (exp, nbytes)
1768 expressionS *exp;
1769 unsigned int nbytes;
1770 {
1771 unsigned int bits_available = BITS_PER_CHAR * nbytes;
1772 char *hold = input_line_pointer;
1773
1774 (void) expression (exp);
1775
1776 if (*input_line_pointer == ':')
1777 { /* bitfields */
1778 long value = 0;
1779
1780 for (;;)
1781 {
1782 unsigned long width;
1783
1784 if (*input_line_pointer != ':')
1785 {
1786 input_line_pointer = hold;
1787 break;
1788 } /* next piece is not a bitfield */
1789
1790 /* In the general case, we can't allow
1791 full expressions with symbol
1792 differences and such. The relocation
1793 entries for symbols not defined in this
1794 assembly would require arbitrary field
1795 widths, positions, and masks which most
1796 of our current object formats don't
1797 support.
1798
1799 In the specific case where a symbol
1800 *is* defined in this assembly, we
1801 *could* build fixups and track it, but
1802 this could lead to confusion for the
1803 backends. I'm lazy. I'll take any
1804 SEG_ABSOLUTE. I think that means that
1805 you can use a previous .set or
1806 .equ type symbol. xoxorich. */
1807
1808 if (exp->X_op == O_absent)
1809 {
1810 as_warn ("using a bit field width of zero");
1811 exp->X_add_number = 0;
1812 exp->X_op = O_constant;
1813 } /* implied zero width bitfield */
1814
1815 if (exp->X_op != O_constant)
1816 {
1817 *input_line_pointer = '\0';
1818 as_bad ("field width \"%s\" too complex for a bitfield", hold);
1819 *input_line_pointer = ':';
1820 demand_empty_rest_of_line ();
1821 return;
1822 } /* too complex */
1823
1824 if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
1825 {
1826 as_warn ("field width %d too big to fit in %d bytes: truncated to %d bits",
1827 width, nbytes, (BITS_PER_CHAR * nbytes));
1828 width = BITS_PER_CHAR * nbytes;
1829 } /* too big */
1830
1831 if (width > bits_available)
1832 {
1833 /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
1834 input_line_pointer = hold;
1835 exp->X_add_number = value;
1836 break;
1837 } /* won't fit */
1838
1839 hold = ++input_line_pointer; /* skip ':' */
1840
1841 (void) expression (exp);
1842 if (exp->X_op != O_constant)
1843 {
1844 char cache = *input_line_pointer;
1845
1846 *input_line_pointer = '\0';
1847 as_bad ("field value \"%s\" too complex for a bitfield", hold);
1848 *input_line_pointer = cache;
1849 demand_empty_rest_of_line ();
1850 return;
1851 } /* too complex */
1852
1853 value |= ((~(-1 << width) & exp->X_add_number)
1854 << ((BITS_PER_CHAR * nbytes) - bits_available));
1855
1856 if ((bits_available -= width) == 0
1857 || is_it_end_of_statement ()
1858 || *input_line_pointer != ',')
1859 {
1860 break;
1861 } /* all the bitfields we're gonna get */
1862
1863 hold = ++input_line_pointer;
1864 (void) expression (exp);
1865 } /* forever loop */
1866
1867 exp->X_add_number = value;
1868 exp->X_op = O_constant;
1869 } /* if looks like a bitfield */
1870 } /* parse_bitfield_cons() */
1871
1872 #endif /* BITFIELD_CONS_EXPRESSIONS */
1873 \f
1874 #ifdef MRI
1875
1876 static void
1877 parse_mri_cons (exp, nbytes)
1878 expressionS *exp;
1879 unsigned int nbytes;
1880 {
1881 if (*input_line_pointer == '\'')
1882 {
1883 /* An MRI style string, cut into as many bytes as will fit into
1884 a nbyte chunk, left justify if necessary, and separate with
1885 commas so we can try again later */
1886 int scan = 0;
1887 unsigned int result = 0;
1888 input_line_pointer++;
1889 for (scan = 0; scan < nbytes; scan++)
1890 {
1891 if (*input_line_pointer == '\'')
1892 {
1893 if (input_line_pointer[1] == '\'')
1894 {
1895 input_line_pointer++;
1896 }
1897 else
1898 break;
1899 }
1900 result = (result << 8) | (*input_line_pointer++);
1901 }
1902
1903 /* Left justify */
1904 while (scan < nbytes)
1905 {
1906 result <<= 8;
1907 scan++;
1908 }
1909 /* Create correct expression */
1910 exp->X_op = O_constant;
1911 exp->X_add_number = result;
1912 /* Fake it so that we can read the next char too */
1913 if (input_line_pointer[0] != '\'' ||
1914 (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
1915 {
1916 input_line_pointer -= 2;
1917 input_line_pointer[0] = ',';
1918 input_line_pointer[1] = '\'';
1919 }
1920 else
1921 input_line_pointer++;
1922 }
1923 else
1924 expression (&exp);
1925 }
1926
1927 #endif /* MRI */
1928 \f
1929 #ifdef REPEAT_CONS_EXPRESSIONS
1930
1931 /* Parse a repeat expression for cons. This is used by the MIPS
1932 assembler. The format is NUMBER:COUNT; NUMBER appears in the
1933 object file COUNT times.
1934
1935 To use this for a target, define REPEAT_CONS_EXPRESSIONS. */
1936
1937 static void
1938 parse_repeat_cons (exp, nbytes)
1939 expressionS *exp;
1940 unsigned int nbytes;
1941 {
1942 expressionS count;
1943 register int i;
1944
1945 expression (exp);
1946
1947 if (*input_line_pointer != ':')
1948 {
1949 /* No repeat count. */
1950 return;
1951 }
1952
1953 ++input_line_pointer;
1954 expression (&count);
1955 if (count.X_op != O_constant
1956 || count.X_add_number <= 0)
1957 {
1958 as_warn ("Unresolvable or nonpositive repeat count; using 1");
1959 return;
1960 }
1961
1962 /* The cons function is going to output this expression once. So we
1963 output it count - 1 times. */
1964 for (i = count.X_add_number - 1; i > 0; i--)
1965 emit_expr (exp, nbytes);
1966 }
1967
1968 #endif /* REPEAT_CONS_EXPRESSIONS */
1969 \f
1970 /*
1971 * big_cons()
1972 *
1973 * CONStruct more frag(s) of .quads, or .octa etc.
1974 * Makes 0 or more new frags.
1975 * If need_pass_2 == 1, generate no frag.
1976 * This understands only bignums, not expressions. Cons() understands
1977 * expressions.
1978 *
1979 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1980 *
1981 * This creates objects with struct obstack_control objs, destroying
1982 * any context objs held about a partially completed object. Beware!
1983 *
1984 *
1985 * I think it sucks to have 2 different types of integers, with 2
1986 * routines to read them, store them etc.
1987 * It would be nicer to permit bignums in expressions and only
1988 * complain if the result overflowed. However, due to "efficiency"...
1989 */
1990 /* Worker to do .quad etc statements. Clobbers input_line_pointer, checks
1991 end-of-line. 8=.quad 16=.octa ... */
1992
1993 void
1994 big_cons (nbytes)
1995 register int nbytes;
1996 {
1997 register char c; /* input_line_pointer->c. */
1998 register int radix;
1999 register long length; /* Number of chars in an object. */
2000 register int digit; /* Value of 1 digit. */
2001 register int carry; /* For multi-precision arithmetic. */
2002 register int work; /* For multi-precision arithmetic. */
2003 register char *p; /* For multi-precision arithmetic. */
2004
2005 extern const char hex_value[]; /* In hex_value.c. */
2006
2007 /*
2008 * The following awkward logic is to parse ZERO or more strings,
2009 * comma seperated. Recall an expression includes its leading &
2010 * trailing blanks. We fake a leading ',' if there is (supposed to
2011 * be) a 1st expression, and keep demanding 1 expression for each ','.
2012 */
2013 if (is_it_end_of_statement ())
2014 {
2015 c = 0; /* Skip loop. */
2016 }
2017 else
2018 {
2019 c = ','; /* Do loop. */
2020 --input_line_pointer;
2021 }
2022 while (c == ',')
2023 {
2024 ++input_line_pointer;
2025 SKIP_WHITESPACE ();
2026 c = *input_line_pointer;
2027 /* C contains 1st non-blank character of what we hope is a number. */
2028 if (c == '0')
2029 {
2030 c = *++input_line_pointer;
2031 if (c == 'x' || c == 'X')
2032 {
2033 c = *++input_line_pointer;
2034 radix = 16;
2035 }
2036 else
2037 {
2038 radix = 8;
2039 }
2040 }
2041 else
2042 {
2043 radix = 10;
2044 }
2045 /*
2046 * This feature (?) is here to stop people worrying about
2047 * mysterious zero constants: which is what they get when
2048 * they completely omit digits.
2049 */
2050 if (hex_value[c] >= radix)
2051 {
2052 as_bad ("Missing digits. 0 assumed.");
2053 }
2054 bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
2055 for (; (digit = hex_value[c]) < radix; c = *++input_line_pointer)
2056 {
2057 /* Multiply existing number by radix, then add digit. */
2058 carry = digit;
2059 for (p = bignum_low; p <= bignum_high; p++)
2060 {
2061 work = (*p & MASK_CHAR) * radix + carry;
2062 *p = work & MASK_CHAR;
2063 carry = work >> BITS_PER_CHAR;
2064 }
2065 if (carry)
2066 {
2067 grow_bignum ();
2068 *bignum_high = carry & MASK_CHAR;
2069 know ((carry & ~MASK_CHAR) == 0);
2070 }
2071 }
2072 length = bignum_high - bignum_low + 1;
2073 if (length > nbytes)
2074 {
2075 as_warn ("Most significant bits truncated in integer constant.");
2076 }
2077 else
2078 {
2079 register long leading_zeroes;
2080
2081 for (leading_zeroes = nbytes - length;
2082 leading_zeroes;
2083 leading_zeroes--)
2084 {
2085 grow_bignum ();
2086 *bignum_high = 0;
2087 }
2088 }
2089 if (!need_pass_2)
2090 {
2091 char *src = bignum_low;
2092 p = frag_more (nbytes);
2093 if (target_big_endian)
2094 {
2095 int i;
2096 for (i = nbytes - 1; i >= 0; i--)
2097 p[i] = *src++;
2098 }
2099 else
2100 memcpy (p, bignum_low, (int) nbytes);
2101 }
2102 /* C contains character after number. */
2103 SKIP_WHITESPACE ();
2104 c = *input_line_pointer;
2105 /* C contains 1st non-blank character after number. */
2106 }
2107 demand_empty_rest_of_line ();
2108 } /* big_cons() */
2109
2110 /* Extend bignum by 1 char. */
2111 static void
2112 grow_bignum ()
2113 {
2114 register long length;
2115
2116 bignum_high++;
2117 if (bignum_high >= bignum_limit)
2118 {
2119 length = bignum_limit - bignum_low;
2120 bignum_low = xrealloc (bignum_low, length + length);
2121 bignum_high = bignum_low + length;
2122 bignum_limit = bignum_low + length + length;
2123 }
2124 } /* grow_bignum(); */
2125 \f
2126 /*
2127 * float_cons()
2128 *
2129 * CONStruct some more frag chars of .floats .ffloats etc.
2130 * Makes 0 or more new frags.
2131 * If need_pass_2 == 1, no frags are emitted.
2132 * This understands only floating literals, not expressions. Sorry.
2133 *
2134 * A floating constant is defined by atof_generic(), except it is preceded
2135 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
2136 * reading, I decided to be incompatible. This always tries to give you
2137 * rounded bits to the precision of the pseudo-op. Former AS did premature
2138 * truncatation, restored noisy bits instead of trailing 0s AND gave you
2139 * a choice of 2 flavours of noise according to which of 2 floating-point
2140 * scanners you directed AS to use.
2141 *
2142 * In: input_line_pointer->whitespace before, or '0' of flonum.
2143 *
2144 */
2145
2146 void
2147 float_cons (float_type)
2148 /* Clobbers input_line-pointer, checks end-of-line. */
2149 register int float_type; /* 'f':.ffloat ... 'F':.float ... */
2150 {
2151 register char *p;
2152 int length; /* Number of chars in an object. */
2153 register char *err; /* Error from scanning floating literal. */
2154 char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
2155
2156 if (is_it_end_of_statement ())
2157 {
2158 demand_empty_rest_of_line ();
2159 return;
2160 }
2161
2162 do
2163 {
2164 /* input_line_pointer->1st char of a flonum (we hope!). */
2165 SKIP_WHITESPACE ();
2166
2167 /* Skip any 0{letter} that may be present. Don't even check if the
2168 * letter is legal. Someone may invent a "z" format and this routine
2169 * has no use for such information. Lusers beware: you get
2170 * diagnostics if your input is ill-conditioned.
2171 */
2172 if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
2173 input_line_pointer += 2;
2174
2175 err = md_atof (float_type, temp, &length);
2176 know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
2177 know (length > 0);
2178 if (err && *err)
2179 {
2180 as_bad ("Bad floating literal: %s", err);
2181 ignore_rest_of_line ();
2182 return;
2183 }
2184
2185 if (!need_pass_2)
2186 {
2187 int count;
2188
2189 count = 1;
2190
2191 #ifdef REPEAT_CONS_EXPRESSIONS
2192 if (*input_line_pointer == ':')
2193 {
2194 expressionS count_exp;
2195
2196 ++input_line_pointer;
2197 expression (&count_exp);
2198 if (count_exp.X_op != O_constant
2199 || count_exp.X_add_number <= 0)
2200 {
2201 as_warn ("unresolvable or nonpositive repeat count; using 1");
2202 }
2203 else
2204 count = count_exp.X_add_number;
2205 }
2206 #endif
2207
2208 while (--count >= 0)
2209 {
2210 p = frag_more (length);
2211 memcpy (p, temp, length);
2212 }
2213 }
2214 SKIP_WHITESPACE ();
2215 }
2216 while (*input_line_pointer++ == ',');
2217
2218 --input_line_pointer; /* Put terminator back into stream. */
2219 demand_empty_rest_of_line ();
2220 } /* float_cons() */
2221 \f
2222 /*
2223 * stringer()
2224 *
2225 * We read 0 or more ',' seperated, double-quoted strings.
2226 *
2227 * Caller should have checked need_pass_2 is FALSE because we don't check it.
2228 */
2229
2230
2231 void
2232 stringer (append_zero) /* Worker to do .ascii etc statements. */
2233 /* Checks end-of-line. */
2234 register int append_zero; /* 0: don't append '\0', else 1 */
2235 {
2236 register unsigned int c;
2237
2238 /*
2239 * The following awkward logic is to parse ZERO or more strings,
2240 * comma seperated. Recall a string expression includes spaces
2241 * before the opening '\"' and spaces after the closing '\"'.
2242 * We fake a leading ',' if there is (supposed to be)
2243 * a 1st, expression. We keep demanding expressions for each
2244 * ','.
2245 */
2246 if (is_it_end_of_statement ())
2247 {
2248 c = 0; /* Skip loop. */
2249 ++input_line_pointer; /* Compensate for end of loop. */
2250 }
2251 else
2252 {
2253 c = ','; /* Do loop. */
2254 }
2255 while (c == ',' || c == '<' || c == '"')
2256 {
2257 SKIP_WHITESPACE ();
2258 switch (*input_line_pointer)
2259 {
2260 case '\"':
2261 ++input_line_pointer; /*->1st char of string. */
2262 while (is_a_char (c = next_char_of_string ()))
2263 {
2264 FRAG_APPEND_1_CHAR (c);
2265 }
2266 if (append_zero)
2267 {
2268 FRAG_APPEND_1_CHAR (0);
2269 }
2270 know (input_line_pointer[-1] == '\"');
2271 break;
2272 case '<':
2273 input_line_pointer++;
2274 c = get_single_number ();
2275 FRAG_APPEND_1_CHAR (c);
2276 if (*input_line_pointer != '>')
2277 {
2278 as_bad ("Expected <nn>");
2279 }
2280 input_line_pointer++;
2281 break;
2282 case ',':
2283 input_line_pointer++;
2284 break;
2285 }
2286 SKIP_WHITESPACE ();
2287 c = *input_line_pointer;
2288 }
2289
2290 demand_empty_rest_of_line ();
2291 } /* stringer() */
2292 \f
2293 /* FIXME-SOMEDAY: I had trouble here on characters with the
2294 high bits set. We'll probably also have trouble with
2295 multibyte chars, wide chars, etc. Also be careful about
2296 returning values bigger than 1 byte. xoxorich. */
2297
2298 unsigned int
2299 next_char_of_string ()
2300 {
2301 register unsigned int c;
2302
2303 c = *input_line_pointer++ & CHAR_MASK;
2304 switch (c)
2305 {
2306 case '\"':
2307 c = NOT_A_CHAR;
2308 break;
2309
2310 case '\\':
2311 switch (c = *input_line_pointer++)
2312 {
2313 case 'b':
2314 c = '\b';
2315 break;
2316
2317 case 'f':
2318 c = '\f';
2319 break;
2320
2321 case 'n':
2322 c = '\n';
2323 break;
2324
2325 case 'r':
2326 c = '\r';
2327 break;
2328
2329 case 't':
2330 c = '\t';
2331 break;
2332
2333 #ifdef BACKSLASH_V
2334 case 'v':
2335 c = '\013';
2336 break;
2337 #endif
2338
2339 case '\\':
2340 case '"':
2341 break; /* As itself. */
2342
2343 case '0':
2344 case '1':
2345 case '2':
2346 case '3':
2347 case '4':
2348 case '5':
2349 case '6':
2350 case '7':
2351 case '8':
2352 case '9':
2353 {
2354 long number;
2355
2356 for (number = 0; isdigit (c); c = *input_line_pointer++)
2357 {
2358 number = number * 8 + c - '0';
2359 }
2360 c = number & 0xff;
2361 }
2362 --input_line_pointer;
2363 break;
2364
2365 case '\n':
2366 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2367 as_warn ("Unterminated string: Newline inserted.");
2368 c = '\n';
2369 break;
2370
2371 default:
2372
2373 #ifdef ONLY_STANDARD_ESCAPES
2374 as_bad ("Bad escaped character in string, '?' assumed");
2375 c = '?';
2376 #endif /* ONLY_STANDARD_ESCAPES */
2377
2378 break;
2379 } /* switch on escaped char */
2380 break;
2381
2382 default:
2383 break;
2384 } /* switch on char */
2385 return (c);
2386 } /* next_char_of_string() */
2387 \f
2388 static segT
2389 get_segmented_expression (expP)
2390 register expressionS *expP;
2391 {
2392 register segT retval;
2393
2394 retval = expression (expP);
2395 if (expP->X_op == O_illegal
2396 || expP->X_op == O_absent
2397 || expP->X_op == O_big)
2398 {
2399 as_bad ("expected address expression; zero assumed");
2400 expP->X_op = O_constant;
2401 expP->X_add_number = 0;
2402 retval = absolute_section;
2403 }
2404 return retval;
2405 }
2406
2407 static segT
2408 get_known_segmented_expression (expP)
2409 register expressionS *expP;
2410 {
2411 register segT retval;
2412
2413 if ((retval = get_segmented_expression (expP)) == undefined_section)
2414 {
2415 /* There is no easy way to extract the undefined symbol from the
2416 expression. */
2417 if (expP->X_add_symbol != NULL
2418 && S_GET_SEGMENT (expP->X_add_symbol) != expr_section)
2419 as_warn ("symbol \"%s\" undefined; zero assumed",
2420 S_GET_NAME (expP->X_add_symbol));
2421 else
2422 as_warn ("some symbol undefined; zero assumed");
2423 retval = absolute_section;
2424 expP->X_op = O_constant;
2425 expP->X_add_number = 0;
2426 }
2427 know (retval == absolute_section || SEG_NORMAL (retval));
2428 return (retval);
2429 } /* get_known_segmented_expression() */
2430
2431 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
2432 get_absolute_expression ()
2433 {
2434 expressionS exp;
2435
2436 expression (&exp);
2437 if (exp.X_op != O_constant)
2438 {
2439 if (exp.X_op != O_absent)
2440 as_bad ("bad absolute expression; zero assumed");
2441 exp.X_add_number = 0;
2442 }
2443 return exp.X_add_number;
2444 }
2445
2446 char /* return terminator */
2447 get_absolute_expression_and_terminator (val_pointer)
2448 long *val_pointer; /* return value of expression */
2449 {
2450 *val_pointer = get_absolute_expression ();
2451 return (*input_line_pointer++);
2452 }
2453 \f
2454 /*
2455 * demand_copy_C_string()
2456 *
2457 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2458 * Give a warning if that happens.
2459 */
2460 char *
2461 demand_copy_C_string (len_pointer)
2462 int *len_pointer;
2463 {
2464 register char *s;
2465
2466 if ((s = demand_copy_string (len_pointer)) != 0)
2467 {
2468 register int len;
2469
2470 for (len = *len_pointer;
2471 len > 0;
2472 len--)
2473 {
2474 if (*s == 0)
2475 {
2476 s = 0;
2477 len = 1;
2478 *len_pointer = 0;
2479 as_bad ("This string may not contain \'\\0\'");
2480 }
2481 }
2482 }
2483 return (s);
2484 }
2485 \f
2486 /*
2487 * demand_copy_string()
2488 *
2489 * Demand string, but return a safe (=private) copy of the string.
2490 * Return NULL if we can't read a string here.
2491 */
2492 static char *
2493 demand_copy_string (lenP)
2494 int *lenP;
2495 {
2496 register unsigned int c;
2497 register int len;
2498 char *retval;
2499
2500 len = 0;
2501 SKIP_WHITESPACE ();
2502 if (*input_line_pointer == '\"')
2503 {
2504 input_line_pointer++; /* Skip opening quote. */
2505
2506 while (is_a_char (c = next_char_of_string ()))
2507 {
2508 obstack_1grow (&notes, c);
2509 len++;
2510 }
2511 /* JF this next line is so demand_copy_C_string will return a null
2512 termanated string. */
2513 obstack_1grow (&notes, '\0');
2514 retval = obstack_finish (&notes);
2515 }
2516 else
2517 {
2518 as_warn ("Missing string");
2519 retval = NULL;
2520 ignore_rest_of_line ();
2521 }
2522 *lenP = len;
2523 return (retval);
2524 } /* demand_copy_string() */
2525 \f
2526 /*
2527 * is_it_end_of_statement()
2528 *
2529 * In: Input_line_pointer->next character.
2530 *
2531 * Do: Skip input_line_pointer over all whitespace.
2532 *
2533 * Out: 1 if input_line_pointer->end-of-line.
2534 */
2535 int
2536 is_it_end_of_statement ()
2537 {
2538 SKIP_WHITESPACE ();
2539 return (is_end_of_line[*input_line_pointer]);
2540 } /* is_it_end_of_statement() */
2541
2542 void
2543 equals (sym_name)
2544 char *sym_name;
2545 {
2546 register symbolS *symbolP; /* symbol we are working with */
2547
2548 input_line_pointer++;
2549 if (*input_line_pointer == '=')
2550 input_line_pointer++;
2551
2552 while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
2553 input_line_pointer++;
2554
2555 if (sym_name[0] == '.' && sym_name[1] == '\0')
2556 {
2557 /* Turn '. = mumble' into a .org mumble */
2558 register segT segment;
2559 expressionS exp;
2560 register char *p;
2561
2562 segment = get_known_segmented_expression (&exp);
2563 if (!need_pass_2)
2564 {
2565 if (segment != now_seg && segment != absolute_section)
2566 as_warn ("Illegal segment \"%s\". Segment \"%s\" assumed.",
2567 segment_name (segment),
2568 segment_name (now_seg));
2569 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
2570 exp.X_add_number, (char *) 0);
2571 *p = 0;
2572 } /* if (ok to make frag) */
2573 }
2574 else
2575 {
2576 symbolP = symbol_find_or_make (sym_name);
2577 pseudo_set (symbolP);
2578 }
2579 } /* equals() */
2580
2581 /* .include -- include a file at this point. */
2582
2583 /* ARGSUSED */
2584 void
2585 s_include (arg)
2586 int arg;
2587 {
2588 char *newbuf;
2589 char *filename;
2590 int i;
2591 FILE *try;
2592 char *path;
2593
2594 filename = demand_copy_string (&i);
2595 demand_empty_rest_of_line ();
2596 path = xmalloc (i + include_dir_maxlen + 5 /* slop */ );
2597 for (i = 0; i < include_dir_count; i++)
2598 {
2599 strcpy (path, include_dirs[i]);
2600 strcat (path, "/");
2601 strcat (path, filename);
2602 if (0 != (try = fopen (path, "r")))
2603 {
2604 fclose (try);
2605 goto gotit;
2606 }
2607 }
2608 free (path);
2609 path = filename;
2610 gotit:
2611 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2612 newbuf = input_scrub_include_file (path, input_line_pointer);
2613 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
2614 } /* s_include() */
2615
2616 void
2617 add_include_dir (path)
2618 char *path;
2619 {
2620 int i;
2621
2622 if (include_dir_count == 0)
2623 {
2624 include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
2625 include_dirs[0] = "."; /* Current dir */
2626 include_dir_count = 2;
2627 }
2628 else
2629 {
2630 include_dir_count++;
2631 include_dirs = (char **) realloc (include_dirs,
2632 include_dir_count * sizeof (*include_dirs));
2633 }
2634
2635 include_dirs[include_dir_count - 1] = path; /* New one */
2636
2637 i = strlen (path);
2638 if (i > include_dir_maxlen)
2639 include_dir_maxlen = i;
2640 } /* add_include_dir() */
2641
2642 void
2643 s_ignore (arg)
2644 int arg;
2645 {
2646 while (!is_end_of_line[*input_line_pointer])
2647 {
2648 ++input_line_pointer;
2649 }
2650 ++input_line_pointer;
2651
2652 return;
2653 } /* s_ignore() */
2654
2655 /*
2656 * Handle .stabX directives, which used to be open-coded.
2657 * So much creeping featurism overloaded the semantics that we decided
2658 * to put all .stabX thinking in one place. Here.
2659 *
2660 * We try to make any .stabX directive legal. Other people's AS will often
2661 * do assembly-time consistency checks: eg assigning meaning to n_type bits
2662 * and "protecting" you from setting them to certain values. (They also zero
2663 * certain bits before emitting symbols. Tut tut.)
2664 *
2665 * If an expression is not absolute we either gripe or use the relocation
2666 * information. Other people's assemblers silently forget information they
2667 * don't need and invent information they need that you didn't supply.
2668 */
2669
2670 void
2671 change_to_section (name, len, exp)
2672 char *name;
2673 unsigned int len;
2674 unsigned int exp;
2675 {
2676 #ifndef BFD_ASSEMBLER
2677 unsigned int i;
2678 extern segment_info_type segment_info[];
2679
2680 /* Find out if we've already got a section of this name etc */
2681 for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++)
2682 {
2683 if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0)
2684 {
2685 subseg_new (i, exp);
2686 return;
2687 }
2688 }
2689 /* No section, add one */
2690 strncpy (segment_info[i].scnhdr.s_name, name, 8);
2691 segment_info[i].scnhdr.s_flags = 0 /* STYP_NOLOAD */;
2692 subseg_new (i, exp);
2693 #endif
2694 }
2695
2696 /*
2697 * Build a string dictionary entry for a .stabX symbol.
2698 * The symbol is added to the .<secname>str section.
2699 */
2700
2701 static unsigned int
2702 get_stab_string_offset (string, secname)
2703 char *string, *secname;
2704 {
2705 segT save_seg;
2706 segT seg;
2707 subsegT save_subseg;
2708 unsigned int length;
2709 unsigned int old_gdb_string_index;
2710 char *clengthP;
2711 int i;
2712 char c;
2713 /* @@FIXME -- there should be no static data here!
2714 This also has the effect of making all stab string tables large enough
2715 to contain all the contents written to any of them. This only matters
2716 with the Solaris native compiler for the moment, but it should be fixed
2717 anyways. */
2718 static unsigned int gdb_string_index = 0;
2719
2720 old_gdb_string_index = 0;
2721 length = strlen (string);
2722 clengthP = (char *) &length;
2723 if (length > 0)
2724 { /* Ordinary case. */
2725 save_seg = now_seg;
2726 save_subseg = now_subseg;
2727
2728 /* Create the stabstr sections, if they are not already created. */
2729 {
2730 char *newsecname = xmalloc (strlen (secname) + 4);
2731 strcpy (newsecname, secname);
2732 strcat (newsecname, "str");
2733 #ifdef BFD_ASSEMBLER
2734 seg = bfd_get_section_by_name (stdoutput, newsecname);
2735 if (seg == 0)
2736 {
2737 seg = bfd_make_section_old_way (stdoutput, newsecname);
2738 bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_ALLOC);
2739 }
2740 #else
2741 change_to_section(newsecname, strlen(newsecname), 0);
2742 #endif
2743 /* free (newsecname);*/
2744 }
2745 #ifdef BFD_ASSEMBLER
2746 subseg_new ((char *) seg->name, save_subseg);
2747 #else
2748 /* subseg_new (seg, save_subseg); */
2749 #endif
2750 old_gdb_string_index = gdb_string_index;
2751 i = 0;
2752 while ((c = *string++))
2753 {
2754 i++;
2755 gdb_string_index++;
2756 FRAG_APPEND_1_CHAR (c);
2757 }
2758 {
2759 FRAG_APPEND_1_CHAR ((char) 0);
2760 i++;
2761 gdb_string_index++;
2762 }
2763 while (i % 4 != 0)
2764 {
2765 FRAG_APPEND_1_CHAR ((char) 0);
2766 i++;
2767 gdb_string_index++;
2768 }
2769 #ifdef BFD_ASSEMBLER
2770 subseg_new ((char *) save_seg->name, save_subseg);
2771 #else
2772 /* subseg_new (save_seg, save_subseg); */
2773 #endif
2774 }
2775 return old_gdb_string_index;
2776 }
2777
2778 /* This can handle different kinds of stabs (s,n,d) and different
2779 kinds of stab sections. */
2780
2781 static void
2782 s_stab_generic (what, secname)
2783 int what;
2784 char *secname;
2785 {
2786 extern int listing;
2787
2788 symbolS *symbol;
2789 char *string;
2790 int saved_type = 0;
2791 int length;
2792 int goof = 0;
2793 int seg_is_new = 0;
2794 long longint;
2795 segT saved_seg = now_seg;
2796 segT seg;
2797 subsegT saved_subseg = now_subseg;
2798 subsegT subseg;
2799 int offset;
2800 int valu;
2801 char *toP;
2802
2803 valu = ((char *) obstack_next_free (&frags)) - frag_now->fr_literal;
2804
2805 #ifdef SEPARATE_STAB_SECTIONS
2806 #ifdef BFD_ASSEMBLER
2807 seg = bfd_get_section_by_name (stdoutput, secname);
2808 if (seg == 0)
2809 {
2810 seg = subseg_new (secname, 0);
2811 bfd_set_section_flags (stdoutput, seg,
2812 SEC_READONLY | SEC_ALLOC | SEC_RELOC);
2813 subseg_set (saved_seg, subseg);
2814 seg_is_new = 1;
2815 }
2816 #else
2817 change_to_section (secname, strlen(secname), 0);
2818 #endif
2819 #endif /* SEPARATE_STAB_SECTIONS */
2820
2821 /*
2822 * Enter with input_line_pointer pointing past .stabX and any following
2823 * whitespace.
2824 */
2825 if (what == 's')
2826 {
2827 string = demand_copy_C_string (&length);
2828 SKIP_WHITESPACE ();
2829 if (*input_line_pointer == ',')
2830 input_line_pointer++;
2831 else
2832 {
2833 as_bad ("I need a comma after symbol's name");
2834 goof = 1;
2835 }
2836 }
2837 else
2838 string = "";
2839
2840 /*
2841 * Input_line_pointer->after ','. String->symbol name.
2842 */
2843 if (!goof)
2844 {
2845 #ifdef MAKE_STAB_SYMBOL
2846 MAKE_STAB_SYMBOL(symbol, string, secname);
2847 #else
2848 symbol = symbol_new (string, undefined_section, 0, (struct frag *) 0);
2849 #endif
2850 /* Make sure that the rest of this is going to work. */
2851 if (symbol == NULL)
2852 as_fatal ("no stab symbol created");
2853
2854 switch (what)
2855 {
2856 case 'd':
2857 S_SET_NAME (symbol, NULL); /* .stabd feature. */
2858 #ifdef STAB_SYMBOL_SET_VALUE
2859 STAB_SYMBOL_SET_VALUE (symbol, valu);
2860 #else
2861 S_SET_VALUE (symbol, valu);
2862 #endif
2863 #if STAB_SYMBOL_SET_SEGMENT
2864 #else
2865 S_SET_SEGMENT (symbol, now_seg);
2866 #endif
2867 symbol->sy_frag = frag_now;
2868 break;
2869
2870 case 'n':
2871 symbol->sy_frag = &zero_address_frag;
2872 break;
2873
2874 case 's':
2875 symbol->sy_frag = &zero_address_frag;
2876 break;
2877
2878 default:
2879 BAD_CASE (what);
2880 break;
2881 }
2882
2883 if (get_absolute_expression_and_terminator (&longint) == ',')
2884 {
2885 saved_type = longint;
2886 S_SET_TYPE (symbol, saved_type);
2887 }
2888 else
2889 {
2890 as_bad ("I want a comma after the n_type expression");
2891 goof = 1;
2892 input_line_pointer--; /* Backup over a non-',' char. */
2893 }
2894 }
2895
2896 if (!goof)
2897 {
2898 if (get_absolute_expression_and_terminator (&longint) == ',')
2899 S_SET_OTHER (symbol, longint);
2900 else
2901 {
2902 as_bad ("I want a comma after the n_other expression");
2903 goof = 1;
2904 input_line_pointer--; /* Backup over a non-',' char. */
2905 }
2906 }
2907
2908 if (!goof)
2909 {
2910 S_SET_DESC (symbol, get_absolute_expression ());
2911 if (what == 's' || what == 'n')
2912 {
2913 if (*input_line_pointer != ',')
2914 {
2915 as_bad ("I want a comma after the n_desc expression");
2916 goof = 1;
2917 }
2918 else
2919 {
2920 input_line_pointer++;
2921 }
2922 }
2923 }
2924
2925 /* Line is messed up - ignore it and get out of here. */
2926 if (goof)
2927 {
2928 ignore_rest_of_line ();
2929 subseg_new (saved_seg, saved_subseg);
2930 return;
2931 }
2932
2933 #ifdef BFD_ASSEMBLER
2934 subseg_new ((char *) seg->name, subseg);
2935 #endif
2936
2937 #if 0 /* needed for elf only? */
2938 if (seg_is_new)
2939 /* allocate and discard -- filled in later */
2940 (void) frag_more (12);
2941 #endif
2942
2943 #ifdef SEPARATE_STAB_SECTIONS
2944 change_to_section(secname, strlen(secname), 0);
2945 toP = frag_more (8);
2946 /* the string index portion of the stab */
2947 md_number_to_chars (toP, (valueT) S_GET_OFFSET_2(symbol), 4);
2948 md_number_to_chars (toP + 4, (valueT) S_GET_TYPE(symbol), 1);
2949 md_number_to_chars (toP + 5, (valueT) S_GET_OTHER(symbol), 1);
2950 md_number_to_chars (toP + 6, (valueT) S_GET_DESC(symbol), 2);
2951 #endif
2952
2953 #ifdef SEPARATE_STAB_SECTIONS
2954 if (what == 's' || what == 'n')
2955 {
2956 cons (4);
2957 input_line_pointer--;
2958 }
2959 else
2960 {
2961 char *p = frag_more (4);
2962 md_number_to_chars (p, 0, 4);
2963 }
2964 #ifdef BFD_ASSEMBLER
2965 subseg_new ((char *) saved_seg->name, subseg);
2966 #else
2967 /* subseg_new (saved_seg, subseg); */
2968 #endif
2969 #else
2970 if (what == 's' || what == 'n')
2971 {
2972 pseudo_set (symbol);
2973 S_SET_TYPE (symbol, saved_type);
2974 }
2975 #endif
2976
2977 #if 0 /* for elf only? */
2978 if (what == 's' && S_GET_TYPE (symbol) == N_SO)
2979 {
2980 fragS *fragp = seg_info (seg)->frchainP->frch_root;
2981 while (fragp
2982 && fragp->fr_address + fragp->fr_fix < 12)
2983 fragp = fragp->fr_next;
2984 assert (fragp != 0);
2985 assert (fragp->fr_type == rs_fill);
2986 assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
2987 md_number_to_chars (fragp->fr_literal, (valueT) symbol->sy_name_offset,
2988 4);
2989 }
2990 #endif
2991
2992 #ifndef NO_LISTING
2993 if (listing)
2994 switch (S_GET_TYPE (symbol))
2995 {
2996 case N_SLINE:
2997 listing_source_line (S_GET_DESC (symbol));
2998 break;
2999 case N_SO:
3000 case N_SOL:
3001 listing_source_file (string);
3002 break;
3003 }
3004 #endif /* !NO_LISTING */
3005
3006 #ifdef SEPARATE_STAB_SECTIONS
3007 subseg_new (saved_seg, saved_subseg);
3008 #endif
3009
3010 demand_empty_rest_of_line ();
3011 }
3012
3013 /* Regular stab directive. */
3014
3015 void
3016 s_stab (what)
3017 int what;
3018 {
3019 s_stab_generic (what, ".stab");
3020 }
3021
3022 /* "Extended stabs", used in Solaris only now. */
3023
3024 void
3025 s_xstab (what)
3026 int what;
3027 {
3028 int length;
3029 char *secname;
3030
3031 secname = demand_copy_C_string (&length);
3032 SKIP_WHITESPACE ();
3033 if (*input_line_pointer == ',')
3034 input_line_pointer++;
3035 else
3036 {
3037 as_bad ("comma missing in .xstabs");
3038 ignore_rest_of_line ();
3039 return;
3040 }
3041 s_stab_generic (what, secname);
3042 }
3043
3044 /* Frob invented at RMS' request. Set the n_desc of a symbol. */
3045
3046 void
3047 s_desc ()
3048 {
3049 char *name;
3050 char c;
3051 char *p;
3052 symbolS *symbolP;
3053 int temp;
3054
3055 name = input_line_pointer;
3056 c = get_symbol_end ();
3057 p = input_line_pointer;
3058 *p = c;
3059 SKIP_WHITESPACE ();
3060 if (*input_line_pointer != ',')
3061 {
3062 *p = 0;
3063 as_bad ("Expected comma after name \"%s\"", name);
3064 *p = c;
3065 ignore_rest_of_line ();
3066 }
3067 else
3068 {
3069 input_line_pointer++;
3070 temp = get_absolute_expression ();
3071 *p = 0;
3072 symbolP = symbol_find_or_make (name);
3073 *p = c;
3074 S_SET_DESC (symbolP, temp);
3075 }
3076 demand_empty_rest_of_line ();
3077 } /* s_desc() */
3078
3079 /* end of read.c */
This page took 0.090595 seconds and 5 git commands to generate.