ld64 with ppc
[darwin-xtools.git] / cctools / as / read.c
blob1e4222ef3878de8ad881c4f9adc20eddbdb87ab7
1 /* read.c - read a source file -
2 Copyright (C) 1986,1987 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 #define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
21 change this a bit. But then, GNU isnt
22 spozed to run on your machine anyway.
23 (RMS is so shortsighted sometimes.)
26 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
27 /* This is the largest known floating point */
28 /* format (for now). It will grow when we */
29 /* do 4361 style flonums. */
32 /* Routines that read assembler source text to build spagetti in memory. */
33 /* Another group of these functions is in the expr.c module */
35 #include <ctype.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include "stuff/rnd.h"
41 #include "stuff/arch.h"
42 #include "stuff/best_arch.h"
43 #include "as.h"
44 #include "flonum.h"
45 #include "struc-symbol.h"
46 #include "expr.h"
47 #include "read.h"
48 #include "hash.h"
49 #include "obstack.h"
50 #include "md.h"
51 #include "symbols.h"
52 #include "sections.h"
53 #include "input-scrub.h"
54 #include "input-file.h"
55 #include "hex_value.h"
56 #include "messages.h"
57 #include "xmalloc.h"
58 #include "app.h"
59 #if defined(I386) && defined(ARCH64)
60 #include "i386.h"
61 #endif
62 #include "dwarf2dbg.h"
64 #ifndef ALLOW_64BIT_LEB_ON_32B_TARGET
65 #define ALLOW_64BIT_LEB_ON_32B_TARGET 0
66 #endif
69 * Parsing of input is done off of this pointer which points to the next char
70 * of source file to parse.
72 char *input_line_pointer = NULL;
75 * buffer_limit is the value returned by the input_scrub_next_buffer() in
76 * read_a_source_file() and is not static only so read_an_include_file can save
77 * and restore it.
79 char *buffer_limit = NULL; /* -> 1 + last char in buffer. */
81 /* FROM line 164 */
82 #define TARGET_BYTES_BIG_ENDIAN 0 /* HACK */
83 /* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1
84 in the tc-<CPU>.h file. See the "Porting GAS" section of the
85 internals manual. */
86 int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
89 * This table is used by the macros is_name_beginner() and is_part_of_name()
90 * defined in read.h .
92 #ifndef PPC
93 const
94 #endif /* PPC */
95 char lex_type[256] = {
96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
98 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
99 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
100 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
101 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
102 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
103 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
104 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* Allow all chars */
105 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* with the high bit */
106 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* set in names */
107 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
108 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
109 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
110 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
114 * In: a character.
115 * Out: TRUE if this character ends a line.
117 static
118 #ifndef PPC
119 const
120 #endif /* PPC */
121 char is_end_of_line_tab[256] = {
122 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* @abcdefghijklmno */
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* 0123456789:;<=>? */
126 #if defined(M88K) || defined(PPC) || defined(HPPA)
127 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
128 #else
129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
130 #endif
131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */
138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* */
140 // binutils references the table directly, but that requires a cast
141 // whenever you try to index into the array with a char and that's
142 // annoying. The function avoids this. We'd make this a macro,
143 // but it needs to be referenced externally and we don't need to
144 // export the table.
145 char is_end_of_line(int c) { return is_end_of_line_tab[c & 0xFF]; }
148 * The conditional assembly feature (.if, .else, .elseif and .endif) is
149 * implemented with cond_state that tells us what we are in the middle of
150 * processing. ignore can be either TRUE or FALSE. When TRUE we are ignoring
151 * the block of code in the middle of a conditional. MAX_IF_DEPTH is the
152 * maximum depth that if's can be nested.
154 #define MAX_IF_DEPTH 20
155 typedef enum {
156 no_cond, /* no conditional is being processed */
157 if_cond, /* inside if conditional */
158 elseif_cond,/* inside elseif conditional */
159 else_cond /* inside else conditional */
160 }cond_type;
162 struct cond_state {
163 cond_type the_cond;
164 int cond_met;
165 int ignore;
167 typedef struct cond_state cond_stateS;
168 static cond_stateS the_cond_state = {no_cond, FALSE, FALSE};
169 static cond_stateS last_states[MAX_IF_DEPTH];
170 static int if_depth = 0;
173 * Assembler macros are implemented with these variables and functions.
175 #define MAX_MACRO_DEPTH 20
176 static int macro_depth = 0;
177 static struct hash_control
178 *ma_hash = NULL; /* use before set up: NULL-> address error */
179 static struct obstack macros; /* obstack for macro text */
180 static char *macro_name = NULL; /* name of macro we are defining */
181 static int count_lines = TRUE; /* turns line number counting on and off */
182 static int macros_on = TRUE; /* .macros_on and .macros_off toggles this to
183 allow macros to be turned off, which allows
184 macros to override a machine instruction and
185 still use it. */
186 static void expand_macro(char *macro_contents);
187 static void macro_begin(void);
191 * The .dump and .load feature is implemented with these variables and
192 * functions.
194 static FILE *dump_fp = NULL;
195 static void write_macro(const char *string, PTR value);
196 static void write_symbol(const char *string, PTR value);
199 /* Functions private to this file */
200 static void parse_a_buffer(char *buffer);
201 #ifdef PPC
202 static void ppcasm_parse_a_buffer(char *buffer);
203 #endif
204 static void parse_line_comment(char **buffer);
205 static segT get_segmented_expression(expressionS *expP);
206 static void pseudo_op_begin(void);
207 #ifdef PPC
208 static void ppcasm_pseudo_op_begin(void);
209 #endif
210 static void stab(uintptr_t what);
211 static char get_absolute_expression_and_terminator(int32_t *val_pointer);
212 static char *demand_copy_string(int *lenP);
213 static int is_it_end_of_statement(void);
214 static void equals(char *sym_name);
215 static int next_char_of_string(void);
217 #ifdef M68K /* we allow big cons only on the 68k machines */
219 * This is setup by read_begin() and used by big_cons() with using grow_bignum()
220 * to make it bigger if needed.
222 #define BIGNUM_BEGIN_SIZE (16)
223 static char *bignum_low; /* Lowest char of bignum. */
224 static char *bignum_limit;/* 1st illegal address of bignum. */
225 static char *bignum_high; /* Highest char of bignum, may point to
226 (bignum_start-1), never >= bignum_limit. */
227 static void grow_bignum(void);
228 #endif /* M68K */
230 * This is set in read_a_source_file() to the section number of the text section
231 * for used by the machine dependent md_assemble() to create line number stabs
232 * for assembly instructions in the text section when -g is seen.
234 uint32_t text_nsect = 0;
237 * These are the names of the section types used by the .section directive.
239 struct type_name {
240 char *name;
241 unsigned type;
243 static struct type_name type_names[] = {
244 { "regular", S_REGULAR },
245 { "cstring_literals", S_CSTRING_LITERALS },
246 { "4byte_literals", S_4BYTE_LITERALS },
247 { "8byte_literals", S_8BYTE_LITERALS },
248 { "16byte_literals", S_16BYTE_LITERALS },
249 { "literal_pointers", S_LITERAL_POINTERS },
250 #if !(defined(I386) && defined(ARCH64))
251 { "non_lazy_symbol_pointers", S_NON_LAZY_SYMBOL_POINTERS },
252 { "lazy_symbol_pointers", S_LAZY_SYMBOL_POINTERS },
253 { "symbol_stubs", S_SYMBOL_STUBS },
254 #endif
255 { "mod_init_funcs", S_MOD_INIT_FUNC_POINTERS },
256 { "mod_term_funcs", S_MOD_TERM_FUNC_POINTERS },
257 { "coalesced", S_COALESCED },
258 { "interposing", S_INTERPOSING },
259 { "thread_local_regular", S_THREAD_LOCAL_REGULAR },
260 { "thread_local_variables", S_THREAD_LOCAL_VARIABLES },
261 { "thread_local_init_function_pointers",
262 S_THREAD_LOCAL_INIT_FUNCTION_POINTERS },
263 { NULL, 0 }
267 * These are the names of the section attributes used by the .section directive.
269 struct attribute_name {
270 char *name;
271 unsigned attribute;
273 static struct attribute_name attribute_names[] = {
274 { "none", 0 },
275 { "pure_instructions", S_ATTR_PURE_INSTRUCTIONS },
276 { "no_toc", S_ATTR_NO_TOC },
277 { "strip_static_syms", S_ATTR_STRIP_STATIC_SYMS },
278 { "no_dead_strip", S_ATTR_NO_DEAD_STRIP },
279 { "live_support", S_ATTR_LIVE_SUPPORT },
280 { "self_modifying_code", S_ATTR_SELF_MODIFYING_CODE },
281 { "debug", S_ATTR_DEBUG },
282 { NULL, 0 }
286 * These are the built in sections known to the assembler with a directive.
287 * They are known as which segment and section name as well as the type &
288 * attribute, and default alignment.
290 struct builtin_section {
291 char *directive;
292 char *segname;
293 char *sectname;
294 uint32_t flags; /* type & attribute */
295 uint32_t default_align;
296 uint32_t sizeof_stub;
298 static const struct builtin_section builtin_sections[] = {
300 * The text section must be first in this list as it is used by
301 * read_a_source_file() to do the equivalent of a .text at the start
302 * of the file.
304 { "text", "__TEXT", "__text", S_ATTR_PURE_INSTRUCTIONS },
305 { "const", "__TEXT", "__const" },
306 { "static_const", "__TEXT", "__static_const" },
307 { "cstring", "__TEXT", "__cstring", S_CSTRING_LITERALS },
308 { "literal4", "__TEXT", "__literal4", S_4BYTE_LITERALS, 2 },
309 { "literal8", "__TEXT", "__literal8", S_8BYTE_LITERALS, 3 },
310 { "literal16", "__TEXT", "__literal16", S_16BYTE_LITERALS, 4 },
311 { "constructor", "__TEXT", "__constructor" },
312 { "destructor", "__TEXT", "__destructor" },
313 { "fvmlib_init0", "__TEXT", "__fvmlib_init0" },
314 { "fvmlib_init1", "__TEXT", "__fvmlib_init1" },
315 #if !(defined(I386) && defined(ARCH64))
316 { "symbol_stub", "__TEXT", "__symbol_stub",
317 S_SYMBOL_STUBS | S_ATTR_PURE_INSTRUCTIONS,
318 #if defined(M68K)
319 1, 20
320 #endif
321 #if defined(I386)
322 0, 16
323 #endif
324 #if defined(HPPA)
325 2, 28
326 #endif
327 #if defined(SPARC)
328 2, 32
329 #endif
330 #if defined(PPC)
331 2, 20
332 #endif
334 #endif
335 #if !(defined(I386) && defined(ARCH64))
336 { "picsymbol_stub", "__TEXT", "__picsymbol_stub",
337 S_SYMBOL_STUBS | S_ATTR_PURE_INSTRUCTIONS,
338 #if defined(M68K)
339 1, 24
340 #endif
341 #if defined(I386)
342 0, 26
343 #endif
344 #if defined(HPPA)
345 2, 32
346 #endif
347 #if defined(SPARC)
348 2, 60
349 #endif
350 #if defined(PPC)
351 2, 36
352 #endif
354 #endif
355 #if !(defined(I386) && defined(ARCH64))
356 { "non_lazy_symbol_pointer","__DATA","__nl_symbol_ptr",
357 S_NON_LAZY_SYMBOL_POINTERS, 2 },
358 { "lazy_symbol_pointer", "__DATA", "__la_symbol_ptr",
359 S_LAZY_SYMBOL_POINTERS, 2 },
360 #endif
361 { "mod_init_func", "__DATA", "__mod_init_func",
362 S_MOD_INIT_FUNC_POINTERS, 2 },
363 { "mod_term_func", "__DATA", "__mod_term_func",
364 S_MOD_TERM_FUNC_POINTERS, 2 },
365 { "dyld", "__DATA", "__dyld" },
366 { "data", "__DATA", "__data" },
367 { "static_data", "__DATA", "__static_data" },
368 { "const_data", "__DATA", "__const" },
369 { "tdata", "__DATA", "__thread_data",
370 S_THREAD_LOCAL_REGULAR },
371 { "tlv", "__DATA", "__thread_vars",
372 S_THREAD_LOCAL_VARIABLES },
373 { "thread_init_func", "__DATA", "__thread_init",
374 S_THREAD_LOCAL_INIT_FUNCTION_POINTERS },
375 { "objc_class", "__OBJC", "__class", S_ATTR_NO_DEAD_STRIP },
376 { "objc_meta_class", "__OBJC", "__meta_class", S_ATTR_NO_DEAD_STRIP },
377 { "objc_string_object", "__OBJC", "__string_object", S_ATTR_NO_DEAD_STRIP},
378 { "objc_protocol", "__OBJC", "__protocol", S_ATTR_NO_DEAD_STRIP },
379 { "objc_cat_cls_meth", "__OBJC", "__cat_cls_meth", S_ATTR_NO_DEAD_STRIP },
380 { "objc_cat_inst_meth", "__OBJC", "__cat_inst_meth", S_ATTR_NO_DEAD_STRIP},
381 { "objc_cls_meth", "__OBJC", "__cls_meth", S_ATTR_NO_DEAD_STRIP },
382 { "objc_inst_meth", "__OBJC", "__inst_meth", S_ATTR_NO_DEAD_STRIP },
383 { "objc_message_refs", "__OBJC", "__message_refs",
384 S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP, 2},
385 { "objc_cls_refs", "__OBJC", "__cls_refs",
386 S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP, 2},
387 { "objc_class_names", "__TEXT", "__cstring", S_CSTRING_LITERALS },
388 { "objc_module_info", "__OBJC", "__module_info", S_ATTR_NO_DEAD_STRIP },
389 { "objc_symbols", "__OBJC", "__symbols", S_ATTR_NO_DEAD_STRIP },
390 { "objc_category", "__OBJC", "__category", S_ATTR_NO_DEAD_STRIP },
391 { "objc_meth_var_types", "__TEXT", "__cstring", S_CSTRING_LITERALS },
392 { "objc_class_vars", "__OBJC", "__class_vars", S_ATTR_NO_DEAD_STRIP },
393 { "objc_instance_vars", "__OBJC", "__instance_vars", S_ATTR_NO_DEAD_STRIP},
394 { "objc_meth_var_names", "__TEXT", "__cstring", S_CSTRING_LITERALS },
395 { "objc_selector_strs", "__OBJC", "__selector_strs", S_CSTRING_LITERALS },
396 { 0 }
399 /* set up pseudo-op tables */
400 static struct hash_control *po_hash = NULL;
401 #ifdef PPC
402 static struct hash_control *ppcasm_po_hash = NULL;
403 #endif
406 * The routines that implement the pseudo-ops.
408 #if !defined(I860) /* i860 has it's own align and org */
409 static void s_align(int value, int bytes_p);
410 static void s_align_bytes(uintptr_t arg);
411 static void s_align_ptwo(uintptr_t arg);
412 static void s_org(uintptr_t value);
413 #endif
414 static void s_private_extern(uintptr_t value);
415 #if !(defined(I386) && defined(ARCH64))
416 static void s_indirect_symbol(uintptr_t value);
417 #endif
418 static void s_abort(uintptr_t value);
419 static void s_comm(uintptr_t value);
420 static void s_desc(uintptr_t value);
421 static void s_fill(uintptr_t value);
422 static void s_lcomm(uintptr_t value);
423 static void s_lsym(uintptr_t value);
424 static void s_set(uintptr_t value);
425 static void s_reference(uintptr_t value);
426 static void s_lazy_reference(uintptr_t value);
427 static void s_weak_reference(uintptr_t value);
428 static void s_weak_definition(uintptr_t value);
429 static void s_weak_def_can_be_hidden(uintptr_t value);
430 static void s_no_dead_strip(uintptr_t value);
431 static void s_symbol_resolver(uintptr_t value);
432 static void s_include(uintptr_t value);
433 static void s_dump(uintptr_t value);
434 static void s_load(uintptr_t value);
435 static void s_if(uintptr_t value);
436 static void s_elseif(uintptr_t value);
437 static void s_else(uintptr_t value);
438 static void s_endif(uintptr_t value);
439 static void s_macros_on(uintptr_t value);
440 static void s_macros_off(uintptr_t value);
441 static void s_section(uintptr_t value);
442 static void s_zerofill(uintptr_t value);
443 static uint32_t s_builtin_section(const struct builtin_section *s);
444 static void s_subsections_via_symbols(uintptr_t value);
445 static void s_machine(uintptr_t value);
446 static void s_secure_log_unique(uintptr_t value);
447 static void s_secure_log_reset(uintptr_t value);
448 static void s_inlineasm(uintptr_t value);
449 static void s_leb128(uintptr_t sign);
450 static void s_incbin(uintptr_t value);
451 static void s_data_region(uintptr_t value);
452 static void s_end_data_region(uintptr_t value);
454 #ifdef PPC
456 * The routines that implement the ppcasm pseudo-ops.
458 static void s_ppcasm_end(uintptr_t value);
459 #endif /* PPC */
462 * The machine independent pseudo op table.
464 static const pseudo_typeS pseudo_table[] = {
465 #if !defined(I860) /* i860 has it's own align and org */
466 { "align", s_align_ptwo, 1 },
467 { "align32", s_align_ptwo, 4 },
468 { "p2align", s_align_ptwo, 1 },
469 { "p2alignw", s_align_ptwo, 2 },
470 { "p2alignl", s_align_ptwo, 4 },
471 { "balign", s_align_bytes, 1 },
472 { "balignw", s_align_bytes, 2 },
473 { "balignl", s_align_bytes, 4 },
474 { "org", s_org, 0 },
475 #endif
476 #ifndef M88K /* m88k has it's own abs that uses the s_abs() in here */
477 { "abs", s_abs, 0 },
478 #endif
479 { "private_extern", s_private_extern, 0},
480 #if !(defined(I386) && defined(ARCH64)) /* x86-64 doesn't support .indirect_symbol */
481 { "indirect_symbol", s_indirect_symbol, 0},
482 #endif
483 { "abort", s_abort, 0 },
484 { "ascii", stringer, 0 },
485 { "asciz", stringer, 1 },
486 { "byte", cons, 1 },
487 { "comm", s_comm, 0 },
488 { "desc", s_desc, 0 },
489 { "double", float_cons, 'd' },
490 { "appfile", s_app_file, 0 },
491 { "fill", s_fill, 0 },
492 { "globl", s_globl, 0 },
493 { "lcomm", s_lcomm, 0 },
494 { "line", s_line, 0 },
495 { "long", cons, 4 },
496 { "quad", cons, 8 },
497 { "lsym", s_lsym, 0 },
498 { "section", s_section, 0 },
499 { "zerofill", s_zerofill, S_ZEROFILL },
500 { "tbss", s_zerofill, S_THREAD_LOCAL_ZEROFILL },
501 { "secure_log_unique",s_secure_log_unique, 0 },
502 { "secure_log_reset",s_secure_log_reset, 0 },
503 { "set", s_set, 0 },
504 { "short", cons, 2 },
505 { "single", float_cons, 'f' },
506 { "space", s_space, 0 },
507 { "sleb128", s_leb128, 1},
508 { "uleb128", s_leb128, 0},
509 { "stabd", stab, 'd' },
510 { "stabn", stab, 'n' },
511 { "stabs", stab, 's' },
512 { "debug_note", stab, 's' },
513 { "reference",s_reference, 0 },
514 { "lazy_reference",s_lazy_reference, 0 },
515 { "weak_reference",s_weak_reference, 0 },
516 { "weak_definition",s_weak_definition, 0 },
517 { "weak_def_can_be_hidden",s_weak_def_can_be_hidden, 0 },
518 { "no_dead_strip",s_no_dead_strip, 0 },
519 { "symbol_resolver",s_symbol_resolver, 0 },
520 { "include", s_include, 0 },
521 { "macro", s_macro, 0 },
522 { "endmacro", s_endmacro, 0 },
523 { "endm", s_endmacro, 0 },
524 { "macros_on",s_macros_on, 0 },
525 { "macros_off",s_macros_off, 0 },
526 { "if", s_if, 0 },
527 { "elseif", s_elseif, 0 },
528 { "else", s_else, 0 },
529 { "endif", s_endif, 0 },
530 { "dump", s_dump, 0 },
531 { "load", s_load, 0 },
532 { "subsections_via_symbols", s_subsections_via_symbols, 0 },
533 { "machine", s_machine, 0 },
534 { "inlineasmstart", s_inlineasm, 1 },
535 { "inlineasmend", s_inlineasm, 0 },
536 { "incbin", s_incbin, 0 },
537 { "data_region", s_data_region, 0 },
538 { "end_data_region", s_end_data_region, 0 },
539 { NULL } /* end sentinel */
542 #ifdef PPC
544 * The pseudo op table for the ppcasm flavor of the PowerPC assembler.
546 static const pseudo_typeS ppcasm_pseudo_table[] = {
547 { "include", s_include, 0 },
548 { "end", s_ppcasm_end, 0 },
549 { NULL } /* end sentinel */
551 #endif /* PPC */
554 * True if .secure_log_unique has been used without; reset by .secure_log_reset
556 static enum bool s_secure_log_used = FALSE;
559 * read_begin() initializes the assember to read assembler source input.
561 void
562 read_begin(
563 void)
565 pseudo_op_begin();
566 macro_begin();
567 obstack_begin(&notes, 5000);
569 #ifdef M68K /* we allow big cons only on the 68k machines */
570 bignum_low = xmalloc((int32_t)BIGNUM_BEGIN_SIZE);
571 bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
572 #endif
575 #ifdef PPC
577 * ppcasm_read_begin() does all the things needed to set up for reading ppcasm
578 * PowerPC assembly syntax.
580 void
581 ppcasm_read_begin(
582 void)
585 * For ppcasm allow '\r' as an end of line character and don't treat
586 * '@' and ':' as an end of line characters.
588 is_end_of_line_tab['\r'] = 1;
589 is_end_of_line_tab['@'] = 0;
590 is_end_of_line_tab[':'] = 0;
592 ppcasm_pseudo_op_begin();
594 #endif /* PPC */
597 * pseudo_op_begin() creates a hash table of pseudo ops from the machine
598 * independent and machine dependent pseudo op tables.
600 static
601 void
602 pseudo_op_begin(
603 void)
605 const char *errtxt;
606 const pseudo_typeS *pop;
607 uint32_t i;
608 pseudo_typeS *sections_pseudo_table;
610 po_hash = hash_new();
611 errtxt = NULL;
613 for(pop = pseudo_table;
614 pop->poc_name && (!errtxt || *errtxt == '\0');
615 pop++)
616 errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop);
618 for(pop = md_pseudo_table;
619 pop->poc_name && (!errtxt || *errtxt == '\0');
620 pop++)
621 errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop);
623 for(i = 0; builtin_sections[i].directive != NULL; i++)
625 sections_pseudo_table = xmalloc((i + 1) * sizeof(pseudo_typeS));
626 for(i = 0; builtin_sections[i].directive != NULL; i++){
627 sections_pseudo_table[i].poc_name = builtin_sections[i].directive;
628 sections_pseudo_table[i].poc_handler =
629 (void (*)(uintptr_t))s_builtin_section;
630 sections_pseudo_table[i].poc_val = (uintptr_t)(builtin_sections +i);
632 sections_pseudo_table[i].poc_name = NULL;
633 for(pop = (const pseudo_typeS *)sections_pseudo_table;
634 pop->poc_name && (!errtxt || *errtxt == '\0');
635 pop++)
636 errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop);
638 if(errtxt != NULL && *errtxt != '\0'){
639 as_fatal("error constructing pseudo-op table (%s)", errtxt);
643 #ifdef PPC
645 * ppcasm_pseudo_op_begin() creates a hash table of pseudo ops for use with the
646 * ppcasm flavor of the PowerPC assembler.
648 static
649 void
650 ppcasm_pseudo_op_begin(
651 void)
653 const char *errtxt;
654 char *uppercase;
655 const pseudo_typeS *pop;
656 uint32_t len, i;
658 ppcasm_po_hash = hash_new();
659 errtxt = NULL;
660 for(pop = ppcasm_pseudo_table; pop->poc_name != NULL; pop++){
661 errtxt = hash_insert(ppcasm_po_hash, pop->poc_name, (char *)pop);
662 if(errtxt != NULL && *errtxt != '\0')
663 as_fatal("error constructing pseudo-op table (%s)", errtxt);
665 len = strlen(pop->poc_name);
666 uppercase = xmalloc(len);
667 strcpy(uppercase, pop->poc_name);
668 for(i = 0; i < len; i++)
669 uppercase[i] = toupper(uppercase[i]);
670 errtxt = hash_insert(ppcasm_po_hash, uppercase, (char *)pop);
671 if(errtxt != NULL && *errtxt != '\0')
672 as_fatal("error constructing pseudo-op table (%s)", errtxt);
675 #endif /* PPC */
678 * The NeXT version of: read_a_source_file()
680 * This differs from the GNU version by taking the guts of the GNU
681 * read_a_source_file() (with the outer most loop removed) and renaming it
682 * parse_a_buffer(). With the NeXT version of read_a_source file simply
683 * containing that outer loop and a call to parse_a_buffer(). This is done
684 * So that expand_macro() and parse_line_comment() can call parse_a_buffer()
685 * with the buffers they create.
687 void
688 read_a_source_file(
689 char *buffer) /* 1st character of each buffer of lines is here. */
691 cond_stateS starting_cond_state;
692 short starting_if_depth;
694 symbolS *symbolP;
696 starting_cond_state = the_cond_state;
697 starting_if_depth = if_depth;
699 /* Do not change segments or subsegments if this is a .include */
700 if(doing_include == FALSE){
702 * This is a new file so switch start as if a .text was seen. This
703 * call to s_builtin_section() relys on the fact that the text
704 * section is first in the built in sections list.
706 if(flagseen['n'] == FALSE)
707 text_nsect = s_builtin_section(builtin_sections);
710 * If the -g flag is present generate the lead stabs for this
711 * physical file that is not an include file. Each physical file's
712 * stabs are enclosed by a pair of source name stabs, N_SO, (one at
713 * the begining of the file with the name of the file and one at the
714 * end with the name ""). This is seen by nm(1) as:
715 * 00000000 - 01 0000 SO {standard input}
716 * ...
717 * 00000020 - 01 0000 SO
718 * To make the debugger work line numbers stabs, N_SLINE, must be
719 * contained "in a function" (after a function stab, N_FUN). To
720 * make a function stab work it must have a type number. Since type
721 * numbers 1 and 2 (the 1 in "int:t1=..." and the 2 in "char:t2=..."
722 * are "magic" to the debugger we use type 3 for the types of the
723 * function stabs we generate for each text label (see the routine
724 * make_stab_for_symbol() in symbols.c). So at lead stabs at the
725 * begining of each physical file include three type stabs, L_LSYM
726 * with the correct symbol name. The since we must have the types
727 * 1 and 2 they are just what the 'C' would produce but we don't
728 * use them. Type 3 is the void type like the 'C' compiler would
729 * produce which we use for the function stabs' type. These three
730 * look like this to nm(1):
731 * 00000000 - 00 0000 LSYM int:t1=r1;-2147483648;2147483647;
732 * 00000000 - 00 0000 LSYM char:t2=r2;0;127;
733 * 00000000 - 00 0000 LSYM void:t3=3
735 * Then for each text label we see, make_stab_for_symbol() will
736 * generate a stab like this (for the example lable _main):
737 * 00000000 - 01 0007 FUN _main:F3
738 * where the 'F' in F3 is an upper case 'F' for global labels and
739 * a lower case 'f' for non globals.
741 * Then for each instruction we assemble in the text we generate
742 * a line number, S_LINE, stab (see md_assembler in m68k.c, m88k.c
743 * etc). These look like:
744 * 00000000 - 01 0008 SLINE
745 * where the 0008 is the line number.
747 if(flagseen['g']){
748 symbolP = symbol_new(
749 physical_input_file,
750 100 /* N_SO */,
751 text_nsect,
753 obstack_next_free(&frags) - frag_now->fr_literal,
754 frag_now);
755 symbolP = symbol_new(
756 "int:t1=r1;-2147483648;2147483647;",
757 128 /* N_LSYM */,
758 0,0,0,
759 &zero_address_frag);
760 symbolP = symbol_new(
761 "char:t2=r2;0;127;",
762 128 /* N_LSYM */,
763 0,0,0,
764 &zero_address_frag);
765 symbolP = symbol_new(
766 "void:t3=3",
767 128 /* N_LSYM */,
768 0,0,0,
769 &zero_address_frag);
772 * If the --gdwarf2 flag is present generate a .file for this.
774 if(debug_type == DEBUG_DWARF2){
775 dwarf2_file(physical_input_file, ++dwarf2_file_number);
778 else{
780 * If we are now reading an include file we will bracket it's
781 * stabs with a pair of:
782 * 00000010 - 01 0000 SOL include_file
783 * ...
784 * 0000001c - 01 0000 SOL previous_file
785 * We generate the first N_SOL here and the one for the
786 * previous_file in s_include() in read.c.
788 * CAVAT: This will only work if the include file starts off in the
789 * (__TEXT,__text) sections and ends in the (__TEXT,__text) section.
791 if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){
792 symbolP = symbol_new(
793 physical_input_file,
794 132 /* N_SOL */,
795 text_nsect,
797 obstack_next_free(&frags) - frag_now->fr_literal,
798 frag_now);
802 while((buffer_limit = input_scrub_next_buffer(&buffer)) != NULL){
803 #ifdef PPC
804 if(flagseen[(int)'p'] == TRUE)
805 ppcasm_parse_a_buffer(buffer);
806 else
807 #endif /* PPC */
808 parse_a_buffer(buffer);
811 if(the_cond_state.the_cond != starting_cond_state.the_cond ||
812 the_cond_state.ignore != starting_cond_state.ignore||
813 if_depth != starting_if_depth)
814 as_bad("file contains unmatched .ifs or .elses");
816 if(macro_name != NULL)
817 as_bad("file contains unmatched .macro and .endmacro for: %s",
818 macro_name);
820 if(doing_include == FALSE){
821 /* See the comment at the top of this routine for a description of
822 what is going on here */
823 if(flagseen['n'] == FALSE)
824 text_nsect = s_builtin_section(builtin_sections);
825 if(flagseen['g']){
826 (void)symbol_new(
828 100 /* N_SO */,
829 text_nsect,
831 obstack_next_free(&frags) - frag_now->fr_literal,
832 frag_now);
838 * parse_a_buffer() operates on a buffer of lines. It drives the
839 * parsing of lines of assembly code. The lines are assumed to be "well formed"
840 * assembly so the syntax recognized in here is that produced by the output of
841 * the assembly preprocessor (app) or by the compiler when it produces a file
842 * that starts with "#NO_APP\n". A "well formed" assembly is lines with exactly
843 * zero or one leading "well formed space character" (' ', '\t' or '\f')
844 * followed by lines of:
845 * zero or more lables (a name or a digit followed by a colon)
846 * each followed by zero or one "well formed space character"
847 * exactly one of the following followed by a logicial end of line:
848 * a pseudo opcode
849 * followed by zero or one space (' ') characters and it's
850 * arguments (the space is required when the first
851 * character of the first argument could be part of a name)
852 * a macro to be expanded
853 * a machine opcode
854 * a null statement
855 * an assignment to a symbol
856 * a full line comment (in the case of "well formed" assembly it
857 * must be "#APP\n" of a collection of lines
858 * wrapped in "#APP\n ... #NO_APP\n")
860 * input:
861 * buffer pointer to the start of the buffer of lines
862 * (passed as an argument)
863 * buffer_limit pointer to the end of the buffer of lines, that is the
864 * the character it points to is NOT part of the buffer
865 * (buffer_limit is declared in this file)
867 * Assumptions about the buffer of lines:
868 * buffer[-1] == '\n' as done in input-scrub.c with the cpp macro
869 * BEFORE_STRING ("\n")
870 * buffer_limit[-1] == '\n' also as done in input-scrub.c which handles
871 * partial lines internally to itself and always
872 * passes back a buffer of complete lines.
874 * input/output: (for other parsing routines)
875 * input_line_pointer pointer to the next thing in the buffer after
876 * what has been recognized (a global)
878 static
879 void
880 parse_a_buffer(
881 char *buffer)
883 char c; /* contains the first non-space character the current
884 word used to figure out what it is */
885 char *s; /* points to a name with character after the name
886 replaced with a '\0' so it is a 'C' string */
887 char after_name; /* contains that first character after a name that
888 got replaced with a '\0' */
889 char *after_name_pointer;/* points to the end of the name where the '\0' is
890 for error use only */
891 char end_of_line; /* contains an end of line character that got replaced
892 with a '\0' */
893 char *start_of_line;/* points to the locical start of line we're parsing,
894 used only for macro expansion */
895 pseudo_typeS *pop; /* pointer to a pseudo op stucture returned by
896 hash_find(po_hash, s+1) to determine if it is one */
897 char *the_macro; /* pointer to a macro name returned by
898 hash_find(ma_hash, s) to determine if it is one */
899 int temp; /* the value of a number label as an integer, 1: == 1 */
900 char *backup;
902 /* since this is a buffer of full lines it must end in a new line */
903 know(buffer_limit[-1] == '\n');
905 input_line_pointer = buffer;
907 /* while we have more of this buffer to parse keep parsing */
908 while(input_line_pointer < buffer_limit){
910 * At the top of this loop we know that we just parsed a label or we
911 * are at the beginning of a logical line (since their can be more
912 * than one label on a line). start_of_line is only used by
913 * expand_macro()
915 start_of_line = input_line_pointer;
918 * If we are not counting lines (as in the case when called by
919 * expand_macro() ) and we just previously scaned over a newline
920 * (a physical end of line) bump the line counters (see the comments
921 * at the head of this routine about "assumptions about the buffer"
922 * and why it is safe to index input_line_pointer by -1.
924 if(count_lines == TRUE && input_line_pointer[-1] == '\n')
925 bump_line_counters ();
928 * We expect a "well-formed" assembler statement. This means it was
929 * processed by app or produced by a compiler where the file started
930 * with a leading "#APP\n". A "well-formed" statement allows zero
931 * or one leading white space characters.
933 c = *input_line_pointer;
934 input_line_pointer++;
935 if(c == '\t' || c == ' ' || c=='\f'){
936 c = *input_line_pointer;
937 input_line_pointer++;
939 know(c != ' '); /* No further leading whitespace. */
941 * c contains the 1st significant character, *input_line_pointer
942 * points after that character.
946 * look for the begining of a name which could be one of the
947 * following assembly statements:
948 * A pseudo opcode and locical end of line
949 * A macro to be expanded and locical end of line
950 * A machine opcode and locical end of line
951 * A user-defined label (name not digit)(no end of line needed)
952 * At NeXT labels can be enclosed in ""'s so that Objective-C like
953 * names (with spaces and colons) can be part of a name, the
954 * routine get_symbol_end() knows about this.
956 if(is_name_beginner(c) || c == '"'){
957 if( c == '"')
958 s = input_line_pointer--;
959 else
960 s = --input_line_pointer;
961 after_name = get_symbol_end(); /* name's delimiter */
962 after_name_pointer = input_line_pointer;
964 * after_name is the character after symbol. That character's
965 * place in the input line is now '\0',done by get_symbol_end().
966 * s points to the beginning of the symbol (in the case of a
967 * pseudo-op, *s == '.'). *input_line_pointer == '\0' where
968 * after_name was. after_name_pointer is recorded so it their
969 * is an error after the line has been restored the '\0' can
970 * be reset and the name printed.
974 * Look for a name that should be a pseudo op. That is it is
975 * not a user defined label or an assignment to a symbol name.
976 * This must be done so such things as ".foo:" and ".bar=1" are
977 * not mistaken for illegal pseudo ops and that something like
978 * ".long: .long 1" creates a symbol named ".long".
980 if(*s == '.' &&
981 (after_name != ':' &&
982 after_name != '=' &&
983 !((after_name == ' ' || after_name == '\t') &&
984 input_line_pointer[1] == '=') ) ){
986 * Lookup what should be a pseudo op and then restore the
987 * line.
989 pop = (pseudo_typeS *)hash_find(po_hash, s+1);
990 *input_line_pointer = after_name;
993 * A pseudo op must be followed by character that is not
994 * part of a name so it can be parsed. If their is a first
995 * argument that could start with a character in a name then
996 * one "well formed space" (space or a tab) must follow the
997 * pseudo op (otherwise the space is optional).
999 if(after_name == ' ' || after_name == '\t')
1000 input_line_pointer++;
1003 * Now the current state of the line is the after_name has
1004 * been placed back in the line (the line is restored) and
1005 * input_line_pointer is at the start of the first argument
1006 * of the pseudo op (if any).
1008 if(the_cond_state.ignore){
1010 * When ignoring a block of code during conditional
1011 * assembly we can't ignore .if, .else, and .endif
1012 * pseudo ops.
1014 if(pop != NULL &&
1015 ( (pop->poc_handler == s_if) ||
1016 (pop->poc_handler == s_elseif) ||
1017 (pop->poc_handler == s_else) ||
1018 (pop->poc_handler == s_endif) ) )
1019 (*pop->poc_handler)(pop->poc_val);
1020 else
1021 totally_ignore_line();
1023 else if(macro_name){
1025 * When defining a macro we can't ignore .endmacro
1026 * pseudo ops.
1028 if(pop != NULL &&
1029 pop->poc_handler == s_endmacro)
1030 (*pop->poc_handler)(pop->poc_val);
1031 else
1032 add_to_macro_definition(start_of_line);
1034 else{
1035 if(pop != NULL)
1036 (*pop->poc_handler)(pop->poc_val);
1037 else{
1038 after_name = *after_name_pointer;
1039 *after_name_pointer = '\0';
1041 * If macros are on see if this is a use of a macro
1042 * otherwise it is an unknown pseudo op.
1044 if(macros_on == TRUE &&
1045 (the_macro = hash_find(ma_hash, s)) != NULL){
1046 *after_name_pointer = after_name;
1047 expand_macro(the_macro);
1049 else{
1050 as_bad ("Unknown pseudo-op: %s", s);
1051 *after_name_pointer = after_name;
1052 ignore_rest_of_line();
1056 continue;
1058 } /* if(*s == '.' && ... ) */
1061 * If we are in a conditional and the state is that we are now
1062 * not including lines to be assembled then ignore the line.
1064 if(the_cond_state.ignore){
1065 *input_line_pointer = after_name;
1066 totally_ignore_line();
1069 * If we are in the state of defining a macro then take the line
1070 * for the macro definition.
1072 else if(macro_name != NULL){
1073 *input_line_pointer = after_name;
1074 add_to_macro_definition(start_of_line);
1077 * Look for a user defined label.
1079 else if(after_name == ':'){
1080 colon(s, 0);
1081 #ifdef I860
1083 * Intel :: feature, which makes the label global if
1084 * followed by two "::"'s . This is ifdef'ed in so their
1085 * is no else cause thus the slightly odd logic.
1087 if(input_line_pointer[1] == ':'){
1088 struct symbol *symbolP;
1090 symbolP = symbol_find_or_make(s);
1091 symbolP->sy_type |= N_EXT; /* make symbol name global */
1092 *input_line_pointer = ':'; /* Restore first ':' */
1093 input_line_pointer++; /* step over first ':' */
1095 #endif
1096 /* put ':' back for error messages and step over it */
1097 *input_line_pointer = ':';
1098 input_line_pointer++;
1101 * Parse the assignment to a symbol. The syntax for this is
1102 * <symbol><equal><expression>.
1104 else if(after_name == '=' ||
1105 ((after_name == ' ' || after_name == '\t') &&
1106 input_line_pointer[1] == '=')){
1107 equals(s);
1108 demand_empty_rest_of_line();
1111 * If macros are on see if this is a use of a macro.
1113 else if(macros_on == TRUE &&
1114 (the_macro = hash_find(ma_hash, s)) != NULL){
1115 *input_line_pointer = after_name;
1116 expand_macro(the_macro);
1119 * Now assume it is a machine instruction and if not it
1120 * will be handled as an error. Machine instructions must be
1121 * one to a line.
1123 else{
1124 *input_line_pointer = after_name;
1125 while(is_end_of_line(*input_line_pointer) == 0)
1126 input_line_pointer++;
1127 end_of_line = *input_line_pointer;
1128 *input_line_pointer = '\0';
1129 md_assemble(s);
1130 *input_line_pointer = end_of_line;
1131 input_line_pointer++;
1134 * At this point we have parsed all things that could have
1135 * started with a name. Since one of these things (user defined
1136 * lables could appear more than once on a line we do a continue
1137 * here and start parsing as if at the begining of another
1138 * logicial line.
1140 continue;
1142 } /* if(is_name_beginner(c) || c == '"') */
1144 /* empty statement */
1145 if(is_end_of_line(c))
1146 continue;
1149 * If we are in a conditional and the state is that we are now
1150 * not including lines to be assembled then ignore the line.
1152 if(the_cond_state.ignore){
1153 totally_ignore_line();
1154 continue;
1158 * If we are in the state of defining a macro then take the line
1159 * for the macro definition.
1161 if(macro_name != NULL){
1162 add_to_macro_definition(start_of_line);
1163 continue;
1166 /* local label ("4:") */
1167 if(isdigit(c)){
1168 backup = input_line_pointer;
1169 temp = c - '0';
1170 /* Read the whole number. */
1171 while(isdigit(*input_line_pointer))
1173 temp = (temp * 10) + *input_line_pointer - '0';
1174 ++input_line_pointer;
1176 if(*input_line_pointer++ == ':'){
1177 local_colon(temp);
1178 continue;
1180 input_line_pointer = backup;
1184 * The only full line comment that should make it here is the first
1185 * of the pair of "#APP\n ... #NO_APP\n" that the compiler uses to
1186 * wrap around asm() statements. If that is the case then
1187 * parse_line_comment() creates a buffer with those lines in it and
1188 * calls parse_a_buffer() with that buffer. Then returns here
1189 * skiping over that part of the current buffer.
1191 if(c != '\0' && strchr(md_line_comment_chars, c) != NULL){
1192 parse_line_comment(&buffer);
1193 continue;
1196 as_bad("Junk character %d (%c).", c, c);
1197 ignore_rest_of_line();
1199 } /* while(input_line_pointer < buffer_limit) */
1202 #ifdef PPC
1204 * asmppc_parse_a_buffer() operates on a buffer of lines. It drives the
1205 * parsing of lines of assembly code for the PowerPC -ppcasm option.
1207 .* The lines are processed by the assembly preprocessor (app) but spaces have
1208 * been preserved by it when -ppcasm is specified.
1210 * ppcasm assembly lines have the following fields:
1212 * Label Operation Operand Comment
1214 * The label identifier in the Label field must end with a space or a colon (and
1215 * must start at the beginning of the line)
1217 * The operation field contains the assembler directive, the instruction
1218 * mnemonic or macro call.
1220 * The operand follows the operation field for machine instructions, assembler
1221 * directives, and macros. However not all operations require operands. The
1222 * operand field is separated from the operation field by at least one space.
1223 * The operand field can contain subfields separated by commas. The number of
1224 * subfields is determined by the type of operation. Spaces can appear
1225 * anywhere in the operand field except within a single symbol.
1227 * The comment field starts with a ; or a # .
1229 * input:
1230 * buffer pointer to the start of the buffer of lines
1231 * (passed as an argument)
1232 * buffer_limit pointer to the end of the buffer of lines, that is the
1233 * the character it points to is NOT part of the buffer
1234 * (buffer_limit is declared in this file)
1236 * Assumptions about the buffer of lines:
1237 * buffer[-1] == '\n' as done in input-scrub.c with the cpp macro
1238 * BEFORE_STRING ("\n")
1239 * buffer_limit[-1] == '\n' also as done in input-scrub.c which handles
1240 * partial lines internally to itself and always
1241 * passes back a buffer of complete lines.
1243 * input/output: (for other parsing routines)
1244 * input_line_pointer pointer to the next thing in the buffer after
1245 * what has been recognized (a global)
1247 static
1248 void
1249 ppcasm_parse_a_buffer(
1250 char *buffer)
1252 char c; /* contains the first non-space character the current
1253 word used to figure out what it is */
1254 char *s; /* points to a name with character after the name
1255 replaced with a '\0' so it is a 'C' string */
1256 char after_name; /* contains that first character after a name that
1257 got replaced with a '\0' */
1258 char *after_name_pointer;/* points to the end of the name where the '\0' is
1259 for error use only */
1260 char end_of_line; /* contains an end of line character that got replaced
1261 with a '\0' */
1262 char *start_of_line;/* points to the locical start of line we're parsing,
1263 used only for macro expansion */
1264 pseudo_typeS *pop; /* pointer to a pseudo op stucture returned by
1265 hash_find(ppcasm_po_hash, s) to determine if it is */
1267 /* since this is a buffer of full lines it must end in a new line */
1268 know(buffer_limit[-1] == '\n');
1270 input_line_pointer = buffer;
1272 /* while we have more of this buffer to parse keep parsing */
1273 while(input_line_pointer < buffer_limit){
1275 * Save a pointer to the start of the line so we can tell a label
1276 * without a trailing colon from the operation field.
1278 start_of_line = input_line_pointer;
1281 * If we are not counting lines (as in the case when called by
1282 * expand_macro() ) and we just previously scaned over a newline
1283 * (a physical end of line) bump the line counters (see the comments
1284 * at the head of this routine about "assumptions about the buffer"
1285 * and why it is safe to index input_line_pointer by -1.
1287 if(count_lines == TRUE && input_line_pointer[-1] == '\n')
1288 bump_line_counters ();
1291 * We are at the start of a line and if there is a name then this
1292 * must be a label.
1294 c = *input_line_pointer;
1295 if(is_name_beginner(c)){
1296 s = input_line_pointer;
1297 while(is_part_of_name(c)){
1298 input_line_pointer++;
1299 c = *input_line_pointer;
1301 after_name = c;
1302 after_name_pointer = input_line_pointer;
1303 *after_name_pointer = '\0';
1304 colon(s, 0);
1305 *after_name_pointer = after_name;
1307 * A colon after the name is optional and may have a spaces
1308 * before it.
1310 if(*input_line_pointer == ' ')
1311 input_line_pointer++;
1312 if(c == ':'){
1313 input_line_pointer++;
1314 c = *input_line_pointer;
1319 * Now that we have passed the label at the start of the line if
1320 * any skip any spaces that follow it.
1322 if(*input_line_pointer == ' ')
1323 input_line_pointer++;
1324 c = *input_line_pointer;
1327 * The next thing on the line is the operation field which is a name
1328 * of a directive, instruction mnemonic or macro name.
1330 if(is_name_beginner(c)){
1331 s = input_line_pointer;
1332 while(is_part_of_name(c)){
1333 input_line_pointer++;
1334 c = *input_line_pointer;
1336 after_name = c;
1337 after_name_pointer = input_line_pointer;
1338 *after_name_pointer = '\0';
1341 * Lookup what might be a ppcasm pseudo op and then restore the
1342 * line.
1344 pop = (pseudo_typeS *)hash_find(ppcasm_po_hash, s);
1345 *input_line_pointer = after_name;
1347 if(*input_line_pointer == ' ')
1348 input_line_pointer++;
1350 if(pop != NULL){
1351 (*pop->poc_handler)(pop->poc_val);
1352 continue;
1355 * Now assume the name in the operation field is a machine
1356 * instruction and if not it will be handled as an error.
1358 else{
1359 while(is_end_of_line(*input_line_pointer) == 0)
1360 input_line_pointer++;
1361 end_of_line = *input_line_pointer;
1362 *input_line_pointer = '\0';
1363 md_assemble(s);
1364 *input_line_pointer = end_of_line;
1365 input_line_pointer++;
1366 continue;
1371 * If we ran into the end of the line we are done with this line.
1373 /* empty statement */
1374 if(is_end_of_line(c)){
1375 input_line_pointer++;
1376 continue;
1379 as_bad("Junk character %d (%c).", c, c);
1380 ignore_rest_of_line();
1382 } /* while(input_line_pointer < buffer_limit) */
1384 #endif /* PPC */
1387 * parse_line_comment() parses a line comment for parse_a_buffer(). Since
1388 * parse_a_buffer() only operates on "well formed" assembly the only legal
1389 * line comment that should appear is a "#APP\n ... #NO_APP\n" pair which
1390 * tells us to scrub the characters between them and then parse them.
1392 static
1393 void
1394 parse_line_comment(
1395 char **buffer)
1397 char *s;
1398 char *ends;
1400 char *new_buf;
1401 char *new_tmp;
1402 int new_length;
1404 char *tmp_buf;
1405 char *old_input_line_pointer;
1406 char *old_buffer_limit;
1409 /* parse_a_buffer should never see any line comment if app is on */
1410 know(preprocess == FALSE);
1412 s = input_line_pointer;
1413 /* This must be a #APP\n line comment if not ignore it */
1414 if(strncmp(s,"APP\n",4) != 0)
1415 return;
1417 if(count_lines == TRUE)
1418 bump_line_counters();
1419 s += sizeof("APP\n") - 1;
1422 * Search for the matching #NO_APP\n in this buffer, if it is found
1423 * in this buffer the un-scrubed characters between the "#APP\n" and
1424 * "#NO_APP\n" start where s is pointing to and end where ends is
1425 * pointing to.
1427 ends = strstr(s, "#NO_APP\n");
1429 tmp_buf = NULL;
1430 if(ends == NULL){
1431 /* The matching #NO_APP\n for the #APP\n wasn't in this buffer. */
1432 int tmp_len;
1433 int num;
1436 * First create a temporary place (tmp_buf of size tmp_len) to
1437 * collect the un-scrubbed characters between the "#APP\n" and the
1438 * "#NO_APP\n" (or end of file) when we find it in some buffer.
1440 tmp_len = buffer_limit - s;
1441 tmp_buf = xmalloc(tmp_len);
1444 * Copy the end of the buffer that contains the first part of
1445 * the un-scrubbed contents starting just after the "#APP\n".
1446 * This is so the the current buffer (buffer) can be used to
1447 * collect the the rest of the un-scrubbed contents and to find
1448 * the matching "#NO_APP\n".
1450 memcpy(tmp_buf, s, tmp_len);
1453 * This loop collects the remaining un-scrubed contents between
1454 * "#APP\n" and the "#NO_APP\n" into tmp_buf (adjusting tmp_len)
1455 * and looks for the matching "#NO_APP\n".
1458 buffer_limit = input_scrub_next_buffer(buffer);
1460 * We treat runing into the end of the file as if it was the
1461 * "#NO_APP" we were looking for.
1463 if(buffer_limit == NULL)
1464 break;
1466 ends = strstr(*buffer, "#NO_APP\n");
1467 if(ends != NULL)
1468 num = ends - *buffer;
1469 else
1470 num = buffer_limit - *buffer;
1472 tmp_buf = xrealloc(tmp_buf, tmp_len + num);
1473 memcpy(tmp_buf + tmp_len, *buffer, num);
1474 tmp_len += num;
1475 }while(ends == NULL);
1478 * Now set up buffer, buffer_limit and input_line_pointer be past
1479 * all the characters of the "#APP\n ... #NO_APP\n" set so that
1480 * when we return parsing will be picked up from their.
1482 if(ends != NULL)
1483 input_line_pointer = ends + sizeof("#NO_APP\n") - 1;
1484 else{
1485 input_line_pointer = *buffer;
1486 buffer_limit = *buffer;
1490 * Now set s to the start, and ends to the end of the un-scrubed
1491 * contents of the collected characters between the "#APP\n" and
1492 * "#NO_APP\n" pair.
1494 s = tmp_buf;
1495 ends = s + tmp_len;
1497 else{
1499 * The matching "#NO_APP\n" was in the buffer as we were called so
1500 * s is the start, and ends is the end of the un-scrubed contents
1501 * of the characters between the "#APP\n" and "#NO_APP\n" pair.
1502 * Now to set up buffer, buffer_limit and input_line_pointer be past
1503 * all the characters of the "#APP\n ... #NO_APP\n" set so that
1504 * when we return parsing will be picked up from their all that has
1505 * to be done is move the input_line_pointer past the "#NO_APP\n".
1507 input_line_pointer = ends + sizeof("#NO_APP\n") - 1;
1511 * Now that we have the un-scrubed characters beween s and ends setup
1512 * to scrub them into a new buffer (new_buf of size new_length to
1513 * new_tmp).
1515 new_length = 100;
1516 new_buf = xmalloc(new_length);
1517 new_tmp = new_buf;
1518 *new_tmp++ = '\n'; /* place leading \n in buffer for parse_a_buffer */
1520 scrub_string = s;
1521 scrub_last_string = ends;
1522 for(;;){
1523 int c;
1525 c = do_scrub_next_char_from_string();
1526 if(c == EOF)
1527 break;
1528 *new_tmp++ = c;
1529 if(new_tmp == new_buf + new_length){
1530 new_buf = xrealloc(new_buf, new_length + 100);
1531 new_tmp = new_buf + new_length;
1532 new_length += 100;
1535 *new_tmp = '\n'; /* place trailing \n in buffer for parse_a_buffer */
1538 * If we used a temporary buffer to collect the un-scrubbed characters
1539 * it is no longer needed and can be free()'ed.
1541 if(tmp_buf != NULL)
1542 free(tmp_buf);
1545 * Now we are ready to recursively call parse_a_buffer() with our buffer
1546 * of scrubed characters. So save the state of parse_a_buffer() and set
1547 * it up with our buffer of scrubed characters.
1549 old_input_line_pointer = input_line_pointer;
1550 old_buffer_limit = buffer_limit;
1552 input_line_pointer = new_buf;
1553 buffer_limit = new_tmp;
1554 #ifdef PPC
1555 if(flagseen[(int)'p'] == TRUE)
1556 ppcasm_parse_a_buffer(new_buf);
1557 else
1558 #endif /* PPC */
1559 parse_a_buffer(new_buf);
1562 * Free the buffer that held the scrubbed characters
1564 free(new_buf);
1567 * After coming back from our recursive call parse_a_buffer() we want
1568 * resume parsing after the "#NO_APP\n". So bump the line counters
1569 * for the "#NO_APP\n" and restore the state so we can return to
1570 * parse_a_buffer().
1572 if(count_lines == TRUE)
1573 bump_line_counters();
1574 input_line_pointer = old_input_line_pointer;
1575 buffer_limit = old_buffer_limit;
1577 return;
1581 * s_abort() implements the pseudo op:
1582 * .abort [ "abort_string" ]
1584 static
1585 void
1586 s_abort(
1587 uintptr_t value)
1589 char *p;
1591 p = input_line_pointer;
1592 while(is_end_of_line(*p) == FALSE)
1593 p++;
1594 *p = '\0';
1596 as_fatal(".abort %s detected. Assembly stopping.", input_line_pointer);
1599 #if !defined(I860) /* i860 has it's own align and org */
1601 * s_align_bytes() handles the .align pseudo-op where ".align 4" means align to
1602 * a 4 byte boundary.
1604 static
1605 void
1606 s_align_bytes(
1607 uintptr_t arg)
1609 s_align(arg, 1);
1613 * s_align_ptwo() handles the .align pseudo-op on where ".align 4" means align
1614 * to a 2**4 boundary.
1616 static
1617 void
1618 s_align_ptwo(
1619 uintptr_t arg)
1621 s_align(arg, 0);
1625 * s_align() implements the pseudo ops
1626 * .align align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]]
1627 * .p2align align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]]
1628 * .p2alignw align_expression [ , 2byte_fill_expression [,max_bytes_to_fill]]
1629 * .p2alignl align_expression [ , 4byte_fill_expression [,max_bytes_to_fill]]
1630 * .align32 align_expression [ , 4byte_fill_expression [,max_bytes_to_fill]]
1631 * Where align_expression is a power of 2 alignment.
1633 * The parameter fill_size can only be 1, 2 or 4 which is the size of the
1634 * fill_expression. If the parameter bytes_p is non-zero the alignment value
1635 * is interpreted as the byte boundary, rather than the power of 2.
1637 static
1638 void
1639 s_align(
1640 int fill_size,
1641 int bytes_p)
1643 int power_of_2_alignment, byte_alignment, i;
1644 int32_t temp_fill, fill_specified, max_bytes_to_fill;
1645 char fill[4];
1647 if(fill_size != 1 && fill_size != 2 && fill_size != 4)
1648 as_bad("Internal error, s_align() called with bad fill_size %d",
1649 fill_size);
1651 power_of_2_alignment = 0;
1652 if(bytes_p == 0){
1653 power_of_2_alignment = get_absolute_expression();
1655 else{
1656 byte_alignment = get_absolute_expression();
1657 if(byte_alignment != 0){
1658 for(i = 0; (byte_alignment & 1) == 0; i++)
1659 byte_alignment >>= 1;
1660 if(byte_alignment != 1)
1661 as_bad("alignment not a power of 2");
1662 power_of_2_alignment = i;
1665 #define MAX_ALIGNMENT (15)
1666 if(power_of_2_alignment > MAX_ALIGNMENT)
1667 as_warn("Alignment too large: %d. assumed.",
1668 power_of_2_alignment = MAX_ALIGNMENT);
1669 else if(power_of_2_alignment < 0){
1670 as_warn("Alignment negative. 0 assumed.");
1671 power_of_2_alignment = 0;
1673 temp_fill = 0;
1674 fill_specified = 0;
1675 max_bytes_to_fill = 0;
1676 if(*input_line_pointer == ','){
1677 input_line_pointer ++;
1678 if(*input_line_pointer != ','){
1679 temp_fill = get_absolute_expression ();
1680 fill_specified = 1;
1682 if(*input_line_pointer == ','){
1683 input_line_pointer ++;
1684 max_bytes_to_fill = get_absolute_expression ();
1689 * If the fill has not been specified and this section has
1690 * machine instructions then pad the section with nops.
1692 if(fill_specified == 0 &&
1693 ((frchain_now->frch_section.flags & S_ATTR_SOME_INSTRUCTIONS) ==
1694 S_ATTR_SOME_INSTRUCTIONS ||
1695 (frchain_now->frch_section.flags & S_ATTR_PURE_INSTRUCTIONS) ==
1696 S_ATTR_PURE_INSTRUCTIONS) ){
1697 #ifdef M68K
1698 if(power_of_2_alignment >= 1){
1699 temp_fill = 0x4e71; /* m68k nop */
1700 fill_size = 2; /* 2 byte fill size */
1702 #endif /* M68K */
1703 #ifdef I386
1704 temp_fill = 0x90; /* i386 nop */
1705 fill_size = 1; /* 1 byte fill size */
1706 #endif /* I386 */
1707 #ifdef HPPA
1708 if(power_of_2_alignment >= 2){
1709 temp_fill = 0x08000240; /* hppa nop */
1710 fill_size = 4; /* 4 byte fill size */
1712 #endif /* HPPA */
1713 #ifdef SPARC
1714 if(power_of_2_alignment >= 2){
1715 temp_fill = 0x01000000; /* sparc nop */
1716 fill_size = 4; /* 4 byte fill size */
1718 #endif /* SPARC */
1719 #ifdef M88K
1720 if(power_of_2_alignment >= 2){
1721 temp_fill = 0xf4005800; /* m88k 'or r0,r0,r0' instruction */
1722 fill_size = 4; /* 4 byte fill size */
1724 #endif /* M88K */
1725 #ifdef PPC
1726 if(power_of_2_alignment >= 2){
1727 temp_fill = 0x60000000; /* ppc nop */
1728 fill_size = 4; /* 4 byte fill size */
1730 #endif /* PPC */
1731 #ifdef ARM
1732 if(power_of_2_alignment >= 1){
1733 extern int thumb_mode; /* from arm.c */
1734 if(thumb_mode){
1735 if(archflag_cpusubtype == CPU_SUBTYPE_ARM_V7 ||
1736 archflag_cpusubtype == CPU_SUBTYPE_ARM_V7F ||
1737 archflag_cpusubtype == CPU_SUBTYPE_ARM_V7K){
1738 temp_fill = 0xbf00; /* thumb2 nop */
1739 fill_size = 2; /* 2 byte fill size */
1741 else{
1742 temp_fill = 0x46c0; /* thumb1 nop */
1743 fill_size = 2; /* 2 byte fill size */
1746 else if(power_of_2_alignment >= 2){
1747 temp_fill = 0xe1a00000; /* arm nop */
1748 fill_size = 4; /* 4 byte fill size */
1751 #endif /* ARM */
1752 ; /* empty statement for other architectures */
1755 md_number_to_chars(fill, temp_fill, fill_size);
1757 /* Only make a frag if we HAVE to. . . */
1758 if(power_of_2_alignment != 0)
1759 frag_align(power_of_2_alignment, fill, fill_size,max_bytes_to_fill);
1762 * If there is not a max_bytes_to_fill specified and this alignment is
1763 * larger than any previous alignment then this becomes the section's
1764 * alignment. If there is a max_bytes_to_fill then this is handled in
1765 * relax_section() if the alignment can be done without exceeding
1766 * max_bytes_to_fill.
1768 if(max_bytes_to_fill == 0 &&
1769 frchain_now->frch_section.align <
1770 (uint32_t)power_of_2_alignment)
1771 frchain_now->frch_section.align = power_of_2_alignment;
1773 demand_empty_rest_of_line();
1775 #endif /* !defined(I860) i860 has it's own align and org */
1778 * s_comm() implements the pseudo op:
1779 * .comm name , expression
1781 static
1782 void
1783 s_comm(
1784 uintptr_t value)
1786 char *name;
1787 char c;
1788 char *p;
1789 signed_target_addr_t temp;
1790 symbolS *symbolP;
1791 int power_of_2_alignment;
1793 if(*input_line_pointer == '"')
1794 name = input_line_pointer + 1;
1795 else
1796 name = input_line_pointer;
1797 c = get_symbol_end();
1798 /* just after name is now '\0' */
1799 p = input_line_pointer;
1800 *p = c;
1801 SKIP_WHITESPACE();
1802 if(*input_line_pointer != ','){
1803 as_bad("Expected comma after symbol-name");
1804 ignore_rest_of_line();
1805 return;
1807 input_line_pointer++; /* skip ',' */
1808 if((temp = get_absolute_expression ()) < 0){
1809 as_bad(".COMMon length (" TA_DFMT ".) <0! Ignored.", temp);
1810 ignore_rest_of_line();
1811 return;
1813 power_of_2_alignment = 0;
1814 #define MAX_ALIGNMENT (15)
1815 if(*input_line_pointer == ','){
1816 input_line_pointer++;
1817 power_of_2_alignment = get_absolute_expression();
1818 if(power_of_2_alignment > MAX_ALIGNMENT)
1819 as_warn("Alignment too large: %d. assumed.",
1820 power_of_2_alignment = MAX_ALIGNMENT);
1821 else if(power_of_2_alignment < 0){
1822 as_warn("Alignment negative. 0 assumed.");
1823 power_of_2_alignment = 0;
1826 *p = 0;
1827 symbolP = symbol_find_or_make(name);
1828 *p = c;
1829 if((symbolP->sy_type & N_TYPE) != N_UNDF ||
1830 symbolP->sy_other != 0 ||
1831 (symbolP->sy_desc & ~N_NO_DEAD_STRIP) != 0) {
1832 as_bad("Ignoring attempt to re-define symbol");
1833 ignore_rest_of_line();
1834 return;
1836 if(symbolP->sy_value != 0){
1837 if(symbolP->sy_value != (uint32_t)temp)
1838 as_bad("Length of .comm \"%s\" is already " TA_DFMT ". Not "
1839 "changed to " TA_DFMT ".", symbolP->sy_name,
1840 symbolP->sy_value, temp);
1842 else{
1843 symbolP -> sy_value = temp;
1844 symbolP -> sy_type |= N_EXT;
1845 SET_COMM_ALIGN(symbolP->sy_desc, power_of_2_alignment);
1847 know(symbolP->sy_frag == &zero_address_frag);
1848 demand_empty_rest_of_line();
1852 * s_desc() implements the pseudo op:
1853 * .desc name , expression
1854 * sets the n_desc field of a symbol.
1856 static
1857 void
1858 s_desc(
1859 uintptr_t value)
1861 char *name;
1862 char c;
1863 char *p;
1864 symbolS *symbolP;
1865 int temp;
1867 if(*input_line_pointer == '"')
1868 name = input_line_pointer + 1;
1869 else
1870 name = input_line_pointer;
1871 c = get_symbol_end();
1872 p = input_line_pointer;
1873 symbolP = symbol_table_lookup(name);
1874 *p = c;
1875 SKIP_WHITESPACE();
1876 if(*input_line_pointer != ','){
1877 *p = 0;
1878 as_bad("Expected comma after name \"%s\"", name);
1879 *p = c;
1880 ignore_rest_of_line();
1882 else{
1883 input_line_pointer++;
1884 temp = get_absolute_expression();
1885 *p = 0;
1886 symbolP = symbol_find_or_make(name);
1887 *p = c;
1888 symbolP->sy_desc = temp;
1890 demand_empty_rest_of_line();
1894 * s_app_file() implements the pseudo op:
1895 * .file name [ level_number ]
1896 * the level number is generated by /lib/cpp and is just ignored.
1898 void
1899 s_app_file(
1900 uintptr_t value)
1902 char *s;
1903 int length;
1904 struct symbol *symbolP;
1906 /* Some assemblers tolerate immediately following '"' */
1907 if((s = demand_copy_string(&length))){
1908 SKIP_WHITESPACE();
1909 if(*input_line_pointer >= '0' && *input_line_pointer <= '9'){
1910 while(*input_line_pointer >= '0' &&
1911 *input_line_pointer <= '9')
1912 input_line_pointer++;
1914 new_logical_line(s, -1);
1915 demand_empty_rest_of_line();
1918 * This is to generate stabs for debugging assembly code.
1919 * See the comments about stabs in read_a_source_file()
1920 * for a description of what is going on here.
1922 if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){
1923 symbolP = symbol_new(
1924 logical_input_file,
1925 132 /* N_SOL */,
1926 text_nsect,
1928 obstack_next_free(&frags) - frag_now->fr_literal,
1929 frag_now);
1935 * s_fill() implements the pseudo op:
1936 * .fill repeat_expression , fill_size , fill_expression
1938 static
1939 void
1940 s_fill(
1941 uintptr_t value)
1943 int32_t temp_repeat;
1944 int32_t temp_size;
1945 int32_t temp_fill;
1946 char *p;
1948 if(get_absolute_expression_and_terminator(&temp_repeat) != ','){
1949 input_line_pointer--; /* Backup over what was not a ','. */
1950 as_bad("Expect comma after rep-size in .fill");
1951 ignore_rest_of_line();
1952 return;
1954 if(get_absolute_expression_and_terminator(&temp_size) != ','){
1955 input_line_pointer--; /* Backup over what was not a ','. */
1956 as_bad("Expected comma after size in .fill");
1957 ignore_rest_of_line();
1958 return;
1961 * This is to be compatible with BSD 4.2 AS, not for any rational
1962 * reason.
1964 #define BSD_FILL_SIZE_CROCK_8 (8)
1965 if(temp_size > BSD_FILL_SIZE_CROCK_8){
1966 as_bad(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
1967 temp_size = BSD_FILL_SIZE_CROCK_8 ;
1969 if(temp_size < 0){
1970 as_bad("Size negative: .fill ignored.");
1971 temp_size = 0;
1974 * bug fix, if md_number_to_chars() is called with something other than
1975 * 1,2 or 4 it calls abort(). So we don't let the size be something
1976 * like 3. Bug #13017.
1978 else if(temp_size != 0 &&
1979 temp_size != 1 &&
1980 temp_size != 2 &&
1981 temp_size != 4 &&
1982 temp_size != 8){
1983 as_bad(".fill size must be 0,1,2,4 or 8, .fill ignored");
1984 temp_size = 0;
1986 else if(temp_repeat <= 0){
1987 as_bad(".fill repeat <= 0, .fill ignored");
1988 temp_size = 0;
1990 temp_fill = get_absolute_expression();
1992 * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
1993 * but emits no error message because it seems a legal thing to do.
1994 * It is a degenerate case of .fill but could be emitted by a compiler.
1996 if(temp_size != 0){
1997 p = frag_var(rs_fill,
1998 (int)temp_size,
1999 (int)temp_size,
2000 (relax_substateT)0,
2001 (symbolS *)0,
2002 temp_repeat,
2003 (char *)0);
2004 memset(p, '\0', (int)temp_size);
2006 * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
2007 * flavoured AS. The following bizzare behaviour is to be
2008 * compatible with above. I guess they tried to take up to 8
2009 * bytes from a 4-byte expression and they forgot to sign extend.
2011 #define BSD_FILL_SIZE_CROCK_4 (4)
2012 md_number_to_chars(p,
2013 temp_fill,
2014 temp_size > BSD_FILL_SIZE_CROCK_4 ?
2015 BSD_FILL_SIZE_CROCK_4 : (int)temp_size);
2017 demand_empty_rest_of_line();
2021 * s_globl() implements the pseudo op:
2022 * .globl name [ , name ]
2024 void
2025 s_globl(
2026 uintptr_t value)
2028 char *name;
2029 int c;
2030 symbolS *symbolP;
2033 if(*input_line_pointer == '"')
2034 name = input_line_pointer + 1;
2035 else
2036 name = input_line_pointer;
2037 c = get_symbol_end();
2038 symbolP = symbol_find_or_make(name);
2039 *input_line_pointer = c;
2040 SKIP_WHITESPACE();
2041 symbolP->sy_type |= N_EXT;
2042 if(c == ','){
2043 input_line_pointer++;
2044 SKIP_WHITESPACE();
2045 if(*input_line_pointer == '\n')
2046 c = '\n';
2048 }while(c == ',');
2049 demand_empty_rest_of_line();
2053 * s_private_extern() implements the pseudo op:
2054 * .private_extern name [ , name ]
2056 static
2057 void
2058 s_private_extern(
2059 uintptr_t value)
2061 char *name;
2062 int c;
2063 symbolS *symbolP;
2066 if(*input_line_pointer == '"')
2067 name = input_line_pointer + 1;
2068 else
2069 name = input_line_pointer;
2070 c = get_symbol_end();
2071 symbolP = symbol_find_or_make(name);
2072 *input_line_pointer = c;
2073 SKIP_WHITESPACE();
2074 symbolP->sy_type |= N_EXT;
2075 symbolP->sy_type |= N_PEXT;
2076 if(c == ','){
2077 input_line_pointer++;
2078 SKIP_WHITESPACE();
2079 if(*input_line_pointer == '\n')
2080 c = '\n';
2082 }while(c == ',');
2083 demand_empty_rest_of_line();
2086 #if !(defined(I386) && defined(ARCH64))
2088 * s_indirect_symbol() implements the pseudo op:
2089 * .indirect_symbol name
2091 static
2092 void
2093 s_indirect_symbol(
2094 uintptr_t value)
2096 char *name;
2097 int c;
2098 uint32_t section_type;
2100 if(!flagseen['k'])
2101 as_fatal("incompatible feature used: .indirect_symbol (must "
2102 "specify \"-dynamic\" to be used)");
2103 if(frchain_now == NULL){
2104 know(flagseen['n']);
2105 as_fatal("with -n a section directive must be seen before assembly "
2106 "can begin");
2108 section_type = frchain_now->frch_section.flags & SECTION_TYPE;
2109 if(section_type != S_NON_LAZY_SYMBOL_POINTERS &&
2110 section_type != S_LAZY_SYMBOL_POINTERS &&
2111 section_type != S_SYMBOL_STUBS){
2112 as_bad("indirect symbol not in a symbol pointer or stub section, "
2113 ".indirect_symbol ignored");
2114 ignore_rest_of_line();
2115 return;
2118 if(*input_line_pointer == '"')
2119 name = input_line_pointer + 1;
2120 else
2121 name = input_line_pointer;
2122 c = get_symbol_end();
2123 indirect_symbol_new(name,
2124 frag_now,
2125 obstack_next_free(&frags) - frag_now->fr_literal);
2126 *input_line_pointer = c;
2128 demand_empty_rest_of_line();
2130 #endif
2133 * s_lcomm() implements the pseudo op:
2134 * .lcomm name , size_expression [ , align_expression ]
2136 static
2137 void
2138 s_lcomm(
2139 uintptr_t value)
2141 char *name;
2142 char c;
2143 char *p;
2144 signed_target_addr_t size;
2145 symbolS *symbolP;
2146 int align;
2147 static frchainS *bss = NULL;
2149 if(*input_line_pointer == '"')
2150 name = input_line_pointer + 1;
2151 else
2152 name = input_line_pointer;
2153 c = get_symbol_end();
2154 p = input_line_pointer;
2155 *p = c;
2156 SKIP_WHITESPACE();
2157 if(*input_line_pointer != ','){
2158 as_bad("Expected comma after name");
2159 ignore_rest_of_line();
2160 return;
2162 input_line_pointer ++;
2163 if((size = get_absolute_expression()) < 0){
2164 as_bad("BSS length (" TA_DFMT ".) <0! Ignored.", size);
2165 ignore_rest_of_line();
2166 return;
2168 #define MAX_ALIGNMENT (15)
2169 align = 0;
2170 if(*input_line_pointer == ','){
2171 input_line_pointer++;
2172 align = get_absolute_expression();
2173 if(align > MAX_ALIGNMENT){
2174 as_warn("Alignment too large: %d. assumed.", MAX_ALIGNMENT);
2175 align = MAX_ALIGNMENT;
2177 else if(align < 0){
2178 as_warn("Alignment negative. 0 assumed.");
2179 align = 0;
2182 *p = 0;
2183 symbolP = symbol_find_or_make(name);
2184 *p = c;
2186 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0){
2187 if(bss == NULL){
2188 bss = section_new(SEG_DATA, SECT_BSS, S_ZEROFILL, 0, 0);
2189 bss->frch_root = xmalloc(SIZEOF_STRUCT_FRAG);
2190 memset(bss->frch_root, '\0', SIZEOF_STRUCT_FRAG);
2191 bss->frch_last = bss->frch_root;
2193 bss->frch_root->fr_address = rnd(bss->frch_root->fr_address,
2194 1 << align);
2195 symbolP->sy_value = bss->frch_root->fr_address;
2196 symbolP->sy_type = N_SECT;
2197 symbolP->sy_other = bss->frch_nsect;
2198 symbolP->sy_frag = bss->frch_root;
2199 bss->frch_root->fr_address += size;
2201 * If this alignment is larger than any previous alignment then this
2202 * becomes the section's alignment.
2204 if(bss->frch_section.align < (uint32_t)align)
2205 bss->frch_section.align = align;
2207 else
2208 as_bad("Ignoring attempt to re-define symbol.");
2209 demand_empty_rest_of_line();
2213 * s_line() implements the pseudo op:
2214 * .line line_number
2216 void
2217 s_line(
2218 uintptr_t value)
2221 * Assume delimiter is part of expression. BSD4.2 as fails with
2222 * delightful bug, so we are not being incompatible here.
2225 * Since the assembler bumps it's line counters at the end of a line
2226 * and it is the case that the .line is on it's own line what the
2227 * intent is that the line number is for the next line. Thus
2228 * the -1 . This is the way cpp'ed assembler files work which is the
2229 * common case.
2231 new_logical_line((char *)NULL, (int)(get_absolute_expression()) - 1);
2232 demand_empty_rest_of_line();
2236 * s_lsym() implements the pseudo op:
2237 * .lsym name , expression
2239 static
2240 void
2241 s_lsym(
2242 uintptr_t value)
2244 char *name;
2245 char c;
2246 char *p;
2247 segT segment;
2248 expressionS exp;
2249 symbolS *symbolP;
2251 /* we permit ANY expression: BSD4.2 demands constants */
2252 if(*input_line_pointer == '"')
2253 name = input_line_pointer + 1;
2254 else
2255 name = input_line_pointer;
2256 c = get_symbol_end();
2257 p = input_line_pointer;
2258 *p = c;
2259 SKIP_WHITESPACE();
2260 if(*input_line_pointer != ','){
2261 *p = 0;
2262 as_bad("Expected comma after name \"%s\"", name);
2263 *p = c;
2264 ignore_rest_of_line();
2265 return;
2267 input_line_pointer++;
2268 segment = expression(&exp);
2269 if(segment != SEG_ABSOLUTE && segment != SEG_SECT){
2270 /* this warning still need fixing */
2271 as_bad("Bad expression: %s", seg_name[(int)segment]);
2272 ignore_rest_of_line();
2273 return;
2275 know(segment == SEG_ABSOLUTE || segment == SEG_SECT);
2276 *p = 0;
2277 if(segment == SEG_SECT)
2278 symbolP = symbol_new(name,
2279 N_SECT,
2280 frchain_now->frch_nsect,
2282 (valueT)(exp.X_add_number),
2283 &zero_address_frag);
2284 else
2285 symbolP = symbol_new(name,
2286 N_ABS,
2289 (valueT)(exp.X_add_number),
2290 &zero_address_frag);
2291 *p = c;
2292 demand_empty_rest_of_line();
2295 #if !defined(I860) /* i860 has it's own align and org */
2297 * s_org() implements the pseudo op:
2298 * .org expression
2300 static
2301 void
2302 s_org(
2303 uintptr_t value)
2305 segT segment;
2306 expressionS exp;
2307 int32_t temp_fill;
2308 char *p;
2311 * Don't believe the documentation of BSD 4.2 AS.
2312 * There is no such thing as a sub-segment-relative origin.
2313 * Any absolute origin is given a warning, then assumed to be
2314 * segment-relative.
2315 * Any segmented origin expression ("foo+42") had better be in the right
2316 * segment or the .org is ignored.
2318 * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
2319 * never know sub-segment sizes when we are reading code.
2320 * BSD will crash trying to emit -ve numbers of filler bytes in certain
2321 * .orgs. We don't crash, but see as-write for that code.
2323 segment = get_known_segmented_expression(&exp);
2324 if(*input_line_pointer == ','){
2325 input_line_pointer ++;
2326 temp_fill = get_absolute_expression ();
2328 else
2329 temp_fill = 0;
2330 if((segment != SEG_SECT ||
2331 exp.X_add_symbol->sy_other != frchain_now->frch_nsect) &&
2332 segment != SEG_ABSOLUTE)
2333 as_bad("Illegal expression. current section assumed.");
2334 p = frag_var(rs_org,
2337 (relax_substateT)0,
2338 exp.X_add_symbol,
2339 exp.X_add_number,
2340 (char *)0);
2341 *p = temp_fill;
2342 demand_empty_rest_of_line();
2344 #endif /* !defined(I860) i860 has it's own align and org */
2347 * s_set() implements the pseudo op:
2348 * .set name , expression
2350 static
2351 void
2352 s_set(
2353 uintptr_t value)
2355 char *name;
2356 char delim;
2357 char *end_name;
2358 symbolS *symbolP;
2360 if( * input_line_pointer == '"')
2361 name = input_line_pointer + 1;
2362 else
2363 name = input_line_pointer;
2364 delim = get_symbol_end();
2365 end_name = input_line_pointer;
2366 *end_name = delim;
2367 SKIP_WHITESPACE();
2368 if(*input_line_pointer != ','){
2369 *end_name = 0;
2370 as_bad("Expected comma after name \"%s\"", name);
2371 *end_name = delim;
2372 ignore_rest_of_line();
2373 return;
2375 input_line_pointer++;
2376 *end_name = 0;
2377 if(name[0] == '.' && name[1] == '\0'){
2378 /* Turn 'set . , mumble' into a .org mumble */
2379 segT segment;
2380 expressionS exp;
2381 char *ptr;
2383 segment = get_known_segmented_expression(&exp);
2384 if((segment != SEG_SECT ||
2385 exp.X_add_symbol->sy_other != frchain_now->frch_nsect) &&
2386 segment != SEG_ABSOLUTE)
2387 as_bad("Illegal expression. current section assumed.");
2388 ptr = frag_var(rs_org,
2391 (relax_substateT)0,
2392 exp.X_add_symbol,
2393 exp.X_add_number,
2394 (char *)0);
2395 *ptr = 0;
2396 *end_name = delim;
2397 return;
2399 symbolP = symbol_find_or_make(name);
2400 symbolP->sy_desc |= N_NO_DEAD_STRIP;
2401 *end_name = delim;
2402 pseudo_set(symbolP);
2403 demand_empty_rest_of_line();
2407 * s_abs() implements the pseudo op:
2408 * .abs name , expression
2409 * which sets symbol to 1 or 0 depending on if the expression is an absolute
2410 * expression. This is intended for use in macros.
2412 void
2413 s_abs(
2414 uintptr_t value)
2416 char *name;
2417 char c;
2418 char *p;
2419 segT segment;
2420 expressionS exp;
2421 symbolS *symbolP;
2423 if(*input_line_pointer == '"')
2424 name = input_line_pointer + 1;
2425 else
2426 name = input_line_pointer;
2427 c = get_symbol_end();
2428 p = input_line_pointer;
2429 *p = c;
2430 SKIP_WHITESPACE();
2431 if(*input_line_pointer != ','){
2432 *p = 0;
2433 as_bad("Expected comma after name \"%s\"", name);
2434 *p = c;
2435 ignore_rest_of_line();
2436 return;
2438 input_line_pointer++;
2439 *p = 0;
2440 segment = expression(&exp);
2441 symbolP = symbol_find_or_make(name);
2442 symbolP->sy_type = N_ABS;
2443 symbolP->sy_other = 0; /* NO_SECT */
2444 symbolP->sy_frag = &zero_address_frag;
2445 if(segment == SEG_ABSOLUTE)
2446 symbolP->sy_value = 1;
2447 else
2448 symbolP->sy_value = 0;
2449 *p = c;
2450 totally_ignore_line();
2454 * s_space() implements the pseudo op:
2455 * .space repeat_expression [ , fill_expression ]
2457 void
2458 s_space(
2459 uintptr_t value)
2461 int32_t temp_repeat;
2462 int32_t temp_fill;
2463 char *p;
2465 /* Just like .fill, but temp_size = 1 */
2466 if(get_absolute_expression_and_terminator(&temp_repeat) == ','){
2467 temp_fill = get_absolute_expression();
2469 else{
2470 input_line_pointer--; /* Backup over what was not a ','. */
2471 temp_fill = 0;
2473 if(temp_repeat <= 0){
2474 as_bad("Repeat < 0, .space ignored");
2475 ignore_rest_of_line();
2476 return;
2478 p = frag_var(rs_fill,
2481 (relax_substateT)0,
2482 (symbolS *)0,
2483 temp_repeat,
2484 (char *)0);
2485 *p = temp_fill;
2486 demand_empty_rest_of_line();
2489 static
2490 uint32_t
2491 s_builtin_section(
2492 const struct builtin_section *s)
2494 frchainS *frcP;
2496 if(!flagseen['k']){
2497 if((s->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS ||
2498 (s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS ||
2499 (s->flags & SECTION_TYPE) == S_SYMBOL_STUBS ||
2500 #if !(defined(I386) && defined(ARCH64))
2501 (s->flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS ||
2502 (s->flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS ||
2503 #endif
2504 (s->flags & SECTION_ATTRIBUTES & ~S_ATTR_PURE_INSTRUCTIONS) != 0)
2505 as_fatal("incompatible feature used: directive .%s (must "
2506 "specify \"-dynamic\" to be used)", s->directive);
2508 frcP = section_new(s->segname, s->sectname,
2509 s->flags & SECTION_TYPE,
2510 s->flags & SECTION_ATTRIBUTES,
2511 s->sizeof_stub);
2512 if(frcP->frch_section.align < s->default_align)
2513 frcP->frch_section.align = s->default_align;
2514 return(frcP->frch_nsect);
2518 * s_section() implements the pseudo op:
2519 * .section segname , sectname [[[ , type ] , attribute] , sizeof_stub]
2521 static
2522 void
2523 s_section(
2524 uintptr_t value)
2526 char *segname, *sectname, *typename;
2527 char c, d, e, *p, *q, *r;
2528 struct type_name *type_name;
2529 uint32_t type, attribute;
2530 section_t s;
2531 frchainS *frcP;
2532 uint32_t sizeof_stub;
2534 struct attribute_name *attribute_name;
2535 char *attributename, *sizeof_stub_name, f, g, *t, *u, *endp;
2537 segname = input_line_pointer;
2539 c = *input_line_pointer++ ;
2540 }while(c != ',' && c != '\0' && c != '\n');
2541 if(c != ','){
2542 as_bad("Expected comma after segment-name");
2543 ignore_rest_of_line();
2544 return;
2546 p = input_line_pointer - 1;
2548 SKIP_WHITESPACE();
2549 sectname = input_line_pointer;
2551 d = *input_line_pointer++ ;
2552 }while(d != ',' && d != '\0' && d != '\n');
2553 if(p + 1 == input_line_pointer){
2554 as_bad("Expected section-name after comma");
2555 ignore_rest_of_line();
2556 return;
2558 q = input_line_pointer - 1;
2560 *p = 0;
2561 if(strlen(segname) > sizeof(s.segname)){
2562 as_bad("segment-name: %s too long (maximum %ld characters)",
2563 segname, sizeof(s.segname));
2564 ignore_rest_of_line();
2565 *p = c;
2566 return;
2569 *q = 0;
2570 if(strlen(sectname) > sizeof(s.sectname)){
2571 as_bad("section-name: %s too long (maximum %ld characters)",
2572 sectname, sizeof(s.sectname));
2573 ignore_rest_of_line();
2574 return;
2577 * Now see if the optional section type is present.
2579 type = 0;
2580 type_name = type_names;
2581 attribute = 0;
2582 attribute_name = attribute_names;
2583 sizeof_stub = 0;
2584 if(d == ','){
2585 typename = input_line_pointer;
2587 e = *input_line_pointer++ ;
2589 while(e != ',' && !(is_end_of_line(e)));
2590 r = input_line_pointer - 1;
2591 *r = 0;
2592 for(type_name = type_names; type_name->name != NULL; type_name++)
2593 if(strcmp(type_name->name, typename) == 0)
2594 break;
2595 if(type_name->name == NULL){
2596 as_bad("unknown section type: %s", typename);
2597 ignore_rest_of_line();
2598 return;
2600 *r = e;
2601 type = type_name->type;
2603 * Now see if the optional section attribute is present.
2605 if(e == ','){
2607 attributename = input_line_pointer;
2609 f = *input_line_pointer++ ;
2610 }while(f != ',' && f != '+' && !(is_end_of_line(f)));
2611 t = input_line_pointer - 1;
2612 *t = 0;
2613 for(attribute_name = attribute_names;
2614 attribute_name->name != NULL;
2615 attribute_name++)
2616 if(strcmp(attribute_name->name, attributename) == 0)
2617 break;
2618 if(attribute_name->name == NULL){
2619 as_bad("unknown section attribute: %s", attributename);
2620 ignore_rest_of_line();
2621 return;
2623 *t = f;
2624 attribute |= attribute_name->attribute;
2625 }while(f == '+');
2628 * Now get the section stub size if this is a stub section.
2630 if(type == S_SYMBOL_STUBS){
2631 if(f == ','){
2632 sizeof_stub_name = input_line_pointer;
2634 g = *input_line_pointer++ ;
2635 }while(!(is_end_of_line(g)));
2636 u = input_line_pointer - 1;
2637 *u = 0;
2638 sizeof_stub = strtoul(sizeof_stub_name, &endp, 0);
2639 if(*endp != '\0'){
2640 as_bad("size of stub section: %s not a proper "
2641 "number", sizeof_stub_name);
2642 ignore_rest_of_line();
2643 return;
2645 *u = g;
2647 else{
2648 as_bad("missing size of stub section (%s,%s)", segname,
2649 sectname);
2650 ignore_rest_of_line();
2651 return;
2655 else if(type == S_SYMBOL_STUBS){
2656 as_bad("missing size of stub section (%s,%s)", segname,
2657 sectname);
2658 ignore_rest_of_line();
2659 return;
2662 input_line_pointer--;
2664 if(!flagseen['k']){
2665 if(type == S_NON_LAZY_SYMBOL_POINTERS ||
2666 type == S_LAZY_SYMBOL_POINTERS ||
2667 type == S_SYMBOL_STUBS ||
2668 type == S_MOD_INIT_FUNC_POINTERS ||
2669 type == S_MOD_TERM_FUNC_POINTERS)
2670 as_fatal("incompatible feature used: section type %s (must "
2671 "specify \"-dynamic\" to be "
2672 "used)", type_name->name);
2675 frcP = section_new(segname, sectname, type, attribute, sizeof_stub);
2676 *p = c;
2677 *q = d;
2678 demand_empty_rest_of_line();
2682 * s_zerofill() implements the pseudo op:
2683 * .zerofill segname , sectname [, symbolname , size_expression [ , align]]
2685 static
2686 void
2687 s_zerofill(
2688 uintptr_t value)
2690 char *directive, *segname, *sectname, c, d, *p, *q, *name;
2691 section_t s;
2692 frchainS *frcP;
2693 symbolS *symbolP;
2694 uint64_t size;
2695 expressionS exp;
2696 segT st;
2697 int align;
2699 if(value == S_THREAD_LOCAL_ZEROFILL){
2700 directive = "tbss";
2701 frcP = section_new("__DATA", "__thread_bss", value, 0, 0);
2702 if(frcP->frch_root == NULL){
2703 frcP->frch_root = xmalloc(SIZEOF_STRUCT_FRAG);
2704 frcP->frch_last = frcP->frch_root;
2705 memset(frcP->frch_root, '\0', SIZEOF_STRUCT_FRAG);
2707 } else {
2708 directive = "zerofill";
2709 segname = input_line_pointer;
2711 c = *input_line_pointer++ ;
2712 }while(c != ' ' && c != ',' && c != '\0' && c != '\n');
2713 p = input_line_pointer - 1;
2714 while(c == ' '){
2715 c = *input_line_pointer++ ;
2717 if(c != ','){
2718 as_bad("Expected comma after segment-name");
2719 ignore_rest_of_line();
2720 return;
2723 SKIP_WHITESPACE();
2724 sectname = input_line_pointer;
2726 d = *input_line_pointer++ ;
2727 }while(d != ',' && d != '\0' && d != '\n');
2728 if(p + 1 == input_line_pointer){
2729 as_bad("Expected section-name after comma");
2730 ignore_rest_of_line();
2731 return;
2733 q = input_line_pointer - 1;
2735 *p = 0;
2736 if(strlen(segname) > sizeof(s.segname)){
2737 as_bad("segment-name: %s too long (maximum %ld characters)",
2738 segname, sizeof(s.segname));
2739 ignore_rest_of_line();
2740 *p = c;
2741 return;
2744 *q = 0;
2745 if(strlen(sectname) > sizeof(s.sectname)){
2746 as_bad("section-name: %s too long (maximum %ld characters)",
2747 sectname, sizeof(s.sectname));
2748 ignore_rest_of_line();
2749 *p = c;
2750 *q = d;
2751 return;
2754 frcP = section_new(segname, sectname, value, 0, 0);
2755 if(frcP->frch_root == NULL){
2756 frcP->frch_root = xmalloc(SIZEOF_STRUCT_FRAG);
2757 frcP->frch_last = frcP->frch_root;
2758 memset(frcP->frch_root, '\0', SIZEOF_STRUCT_FRAG);
2760 *p = c;
2761 *q = d;
2763 * If this is the end of the line all that was wanted was to create
2764 * the the section which is now done, so return.
2766 if(d != ',')
2767 return;
2770 if(*input_line_pointer == '"')
2771 name = input_line_pointer + 1;
2772 else
2773 name = input_line_pointer;
2774 c = get_symbol_end();
2775 p = input_line_pointer;
2776 *p = c;
2777 SKIP_WHITESPACE();
2778 if(*input_line_pointer != ','){
2779 as_bad("Expected comma after symbol-name");
2780 ignore_rest_of_line();
2781 return;
2783 input_line_pointer ++;
2785 st = expression(&exp);
2786 if(st != SEG_ABSOLUTE) {
2787 if(st != SEG_NONE){
2788 as_bad("zerofill requires an absolute expression for the size.");
2790 exp.X_add_number = 0;
2792 size = (uint64_t)exp.X_add_number;
2793 #if defined (ARCH64)
2794 if(size >= 0x1000000000000ULL) {
2795 as_warn("%s size (%lld) exceeds physical address space of current machines.", directive, size);
2797 #else
2798 if(size >= 0x100000000ULL) {
2799 as_bad("%s size (%lld). exceeds maximum section size.", directive, size);
2800 ignore_rest_of_line();
2801 return;
2803 #endif
2804 align = 0;
2805 if(*input_line_pointer == ','){
2806 input_line_pointer++;
2807 align = get_absolute_expression();
2808 if(align > MAX_ALIGNMENT){
2809 as_warn("Alignment too large: %d. assumed.", MAX_ALIGNMENT);
2810 align = MAX_ALIGNMENT;
2812 else if(align < 0){
2813 as_warn("Alignment negative. 0 assumed.");
2814 align = 0;
2817 * If this alignment is larger than any previous alignment then this
2818 * becomes the section's alignment.
2820 if(frcP->frch_section.align < (uint32_t)align)
2821 frcP->frch_section.align = align;
2823 *p = 0;
2824 symbolP = symbol_find_or_make(name);
2825 *p = c;
2827 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0){
2828 frcP->frch_root->fr_address = rnd(frcP->frch_root->fr_address,
2829 1 << align);
2830 symbolP->sy_value = frcP->frch_root->fr_address;
2831 symbolP->sy_type = N_SECT | (symbolP->sy_type & (N_EXT | N_PEXT));
2832 symbolP->sy_other = frcP->frch_nsect;
2833 symbolP->sy_frag = frcP->frch_root;
2834 frcP->frch_root->fr_address += size;
2836 else
2837 as_bad("Ignoring attempt to re-define symbol.");
2839 demand_empty_rest_of_line();
2843 * s_reference() implements the pseudo op:
2844 * .reference name
2846 static
2847 void
2848 s_reference(
2849 uintptr_t value)
2851 char *name;
2852 char c;
2853 char *p;
2854 symbolS *symbolP;
2856 if(* input_line_pointer == '"')
2857 name = input_line_pointer + 1;
2858 else
2859 name = input_line_pointer;
2860 c = get_symbol_end();
2861 p = input_line_pointer;
2863 *p = 0;
2864 symbolP = symbol_find_or_make(name);
2865 symbolP->sy_desc |= N_NO_DEAD_STRIP;
2866 *p = c;
2867 demand_empty_rest_of_line();
2871 * s_lazy_reference() implements the pseudo op:
2872 * .lazy_reference name
2874 static
2875 void
2876 s_lazy_reference(
2877 uintptr_t value)
2879 char *name;
2880 char c;
2881 char *p;
2882 symbolS *symbolP;
2884 if(!flagseen['k'])
2885 as_fatal("incompatible feature used: .lazy_reference (must specify "
2886 "\"-dynamic\" to be used)");
2888 if(* input_line_pointer == '"')
2889 name = input_line_pointer + 1;
2890 else
2891 name = input_line_pointer;
2892 c = get_symbol_end();
2893 p = input_line_pointer;
2895 *p = 0;
2896 symbolP = symbol_find_or_make(name);
2897 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0)
2898 symbolP->sy_desc |= REFERENCE_FLAG_UNDEFINED_LAZY;
2899 symbolP->sy_desc |= N_NO_DEAD_STRIP;
2900 *p = c;
2901 demand_empty_rest_of_line();
2905 * s_weak_reference() implements the pseudo op:
2906 * .weak_reference name
2908 static
2909 void
2910 s_weak_reference(
2911 uintptr_t value)
2913 char *name;
2914 char c;
2915 char *p;
2916 symbolS *symbolP;
2918 if(!flagseen['k'])
2919 as_fatal("incompatible feature used: .weak_reference (must specify "
2920 "\"-dynamic\" to be used)");
2922 if(* input_line_pointer == '"')
2923 name = input_line_pointer + 1;
2924 else
2925 name = input_line_pointer;
2926 c = get_symbol_end();
2927 p = input_line_pointer;
2929 *p = 0;
2930 symbolP = symbol_find_or_make(name);
2931 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0)
2932 symbolP->sy_desc |= N_WEAK_REF;
2933 *p = c;
2934 demand_empty_rest_of_line();
2938 * s_weak_definition() implements the pseudo op:
2939 * .weak_definition name
2941 static
2942 void
2943 s_weak_definition(
2944 uintptr_t value)
2946 char *name;
2947 char c;
2948 char *p;
2949 symbolS *symbolP;
2951 if(* input_line_pointer == '"')
2952 name = input_line_pointer + 1;
2953 else
2954 name = input_line_pointer;
2955 c = get_symbol_end();
2956 p = input_line_pointer;
2958 *p = 0;
2959 symbolP = symbol_find_or_make(name);
2960 symbolP->sy_desc |= N_WEAK_DEF;
2961 *p = c;
2962 demand_empty_rest_of_line();
2966 * s_weak_def_can_be_hidden() implements the pseudo op:
2967 * .weak_def_can_be_hidden name
2969 static
2970 void
2971 s_weak_def_can_be_hidden(
2972 uintptr_t value)
2974 char *name;
2975 char c;
2976 char *p;
2977 symbolS *symbolP;
2979 if(* input_line_pointer == '"')
2980 name = input_line_pointer + 1;
2981 else
2982 name = input_line_pointer;
2983 c = get_symbol_end();
2984 p = input_line_pointer;
2986 *p = 0;
2987 symbolP = symbol_find_or_make(name);
2988 symbolP->sy_desc |= (N_WEAK_DEF | N_WEAK_REF);
2989 *p = c;
2990 demand_empty_rest_of_line();
2994 * s_no_dead_strip() implements the pseudo op:
2995 * .no_dead_strip name
2997 static
2998 void
2999 s_no_dead_strip(
3000 uintptr_t value)
3002 char *name;
3003 char c;
3004 char *p;
3005 symbolS *symbolP;
3007 if(* input_line_pointer == '"')
3008 name = input_line_pointer + 1;
3009 else
3010 name = input_line_pointer;
3011 c = get_symbol_end();
3012 p = input_line_pointer;
3014 *p = 0;
3015 symbolP = symbol_find_or_make(name);
3016 symbolP->sy_desc |= N_NO_DEAD_STRIP;
3017 *p = c;
3018 demand_empty_rest_of_line();
3022 * s_symbol_resolver() implements the pseudo op:
3023 * .symbol_resolver name
3025 static
3026 void
3027 s_symbol_resolver(
3028 uintptr_t value)
3030 char *name;
3031 char c;
3032 char *p;
3033 symbolS *symbolP;
3035 if(* input_line_pointer == '"')
3036 name = input_line_pointer + 1;
3037 else
3038 name = input_line_pointer;
3039 c = get_symbol_end();
3040 p = input_line_pointer;
3042 *p = 0;
3043 symbolP = symbol_find_or_make(name);
3044 symbolP->sy_desc |= N_SYMBOL_RESOLVER;
3045 *p = c;
3046 demand_empty_rest_of_line();
3050 * s_include() implements the pseudo op:
3051 * .include "filename"
3053 static
3054 void
3055 s_include(
3056 uintptr_t value)
3058 char *filename;
3059 int length;
3060 symbolS *symbolP;
3062 /* Some assemblers tolerate immediately following '"' */
3063 if((filename = demand_copy_string( & length ) )) {
3064 demand_empty_rest_of_line();
3065 read_an_include_file(filename);
3069 * This is to generate stabs for debugging assembly code.
3070 * See the second comment about stabs in read_a_source_file()
3071 * for a description of what is going on here
3073 if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){
3074 symbolP = symbol_new(
3075 physical_input_file,
3076 132 /* N_SOL */,
3077 text_nsect,
3079 obstack_next_free(&frags) - frag_now->fr_literal,
3080 frag_now);
3085 * demand_empty_rest_of_line() checks to make sure we are at the end of a line
3086 * and if not ignores the rest of the line.
3087 * This is global so machine dependent pseudo-ops can use this.
3089 void
3090 demand_empty_rest_of_line(
3091 void)
3093 SKIP_WHITESPACE();
3094 if(is_end_of_line(*input_line_pointer))
3095 input_line_pointer++;
3096 else
3097 ignore_rest_of_line();
3100 /* we simply ignore the rest of this statement */
3101 void
3102 s_ignore(
3103 uintptr_t arg ATTRIBUTE_UNUSED)
3105 totally_ignore_line ();
3109 * ignore_rest_of_line() advances input_line_pointer to the next line and if
3110 * there is anything left on the current line print a warning.
3111 * This is global so machine dependent pseudo-ops can use this.
3113 void
3114 ignore_rest_of_line(
3115 void)
3117 if(!is_end_of_line(*input_line_pointer)){
3118 as_bad("Rest of line ignored. 1st junk character valued %d (%c).",
3119 *input_line_pointer, *input_line_pointer);
3120 while(input_line_pointer < buffer_limit &&
3121 !is_end_of_line(*input_line_pointer))
3122 input_line_pointer++;
3124 input_line_pointer++; /* Return pointing just after end-of-line. */
3125 know(is_end_of_line(input_line_pointer[-1]));
3129 * stab()
3131 * Handle .stabX directives, which used to be open-coded.
3132 * So much creeping featurism overloaded the semantics that we decided
3133 * to put all .stabX thinking in one place. Here.
3135 * We try to make any .stabX directive legal. Other people's AS will often
3136 * do assembly-time consistency checks: eg assigning meaning to n_type bits
3137 * and "protecting" you from setting them to certain values. (They also zero
3138 * certain bits before emitting symbols. Tut tut.)
3140 * If an expression is not absolute we either gripe or use the relocation
3141 * information. Other people's assemblers silently forget information they
3142 * don't need and invent information they need that you didn't supply.
3144 * .stabX directives always make a symbol table entry. It may be junk if
3145 * the rest of your .stabX directive is malformed.
3147 static
3148 void
3149 stab(
3150 uintptr_t what) /* d == .stabd, n == .stabn, and s == .stabs */
3152 symbolS *symbolP;
3153 char *string;
3154 int saved_type;
3155 int length;
3156 int goof; /* TRUE if we have aborted. */
3157 int32_t longint;
3159 saved_type = 0;
3160 symbolP = NULL;
3162 * Enter with input_line_pointer pointing past .stabX and any following
3163 * whitespace.
3165 goof = FALSE;
3166 if(what == 's'){
3167 string = demand_copy_C_string(&length);
3168 SKIP_WHITESPACE();
3169 if(*input_line_pointer == ',')
3170 input_line_pointer ++;
3171 else{
3172 as_bad("I need a comma after symbol's name");
3173 goof = TRUE;
3176 else
3177 string = "";
3180 * Input_line_pointer->after ','. String -> symbol name.
3182 if(!goof){
3183 symbolP = symbol_new(string, 0,0,0,0,(struct frag *)0);
3184 switch(what){
3185 case 'd':
3186 symbolP->sy_name = NULL; /* .stabd feature. */
3187 symbolP->sy_value = obstack_next_free(&frags) -
3188 frag_now->fr_literal;
3189 symbolP->sy_frag = frag_now;
3190 break;
3192 case 'n':
3193 case 's':
3194 symbolP->sy_frag = &zero_address_frag;
3195 break;
3197 default:
3198 BAD_CASE( (int)what );
3199 break;
3201 if(get_absolute_expression_and_terminator(&longint) == ','){
3202 saved_type = longint;
3203 symbolP->sy_type = longint;
3205 else{
3206 as_bad("I want a comma after the n_type expression");
3207 goof = TRUE;
3208 input_line_pointer--; /* Backup over a non-',' char. */
3212 if(!goof){
3213 if(get_absolute_expression_and_terminator(&longint) == ',')
3214 symbolP->sy_other = longint;
3215 else {
3216 as_bad("I want a comma after the n_other expression");
3217 goof = TRUE;
3218 input_line_pointer--; /* Backup over a non-',' char. */
3222 if(!goof){
3223 symbolP->sy_desc = get_absolute_expression();
3224 if(what == 's' || what == 'n'){
3225 if(*input_line_pointer != ','){
3226 as_bad( "I want a comma after the n_desc expression" );
3227 goof = TRUE;
3229 else
3230 input_line_pointer ++;
3234 if((!goof) && (what=='s' || what=='n')){
3235 pseudo_set(symbolP);
3236 symbolP->sy_type = saved_type;
3238 else if(!goof){
3239 /* for stabd the sy_other (n_sect) gets set to the current section*/
3240 symbolP->sy_other = frchain_now->frch_nsect;
3242 if(goof)
3243 ignore_rest_of_line();
3244 else
3245 demand_empty_rest_of_line();
3249 * pseudo_set()
3251 * In: Pointer to a symbol.
3252 * Input_line_pointer -> expression.
3254 * Out: Input_line_pointer -> just after any whitespace after expression.
3255 * Tried to set symbol to value of expression.
3256 * Will change sy_type, sy_value, sy_frag;
3257 *(old ->> May set need_pass_2 == TRUE. <<-- commented out by GNU below it
3258 * uses symbolP->sy_forward = exp.X_add_symbol;)
3260 void
3261 pseudo_set(
3262 symbolS *symbolP)
3264 expressionS exp;
3265 segT segment;
3266 int ext;
3268 know(symbolP); /* NULL pointer is logic error. */
3269 ext = (symbolP->sy_type & (N_EXT | N_PEXT));
3270 segment = expression(&exp);
3272 switch(segment){
3273 case SEG_BIG:
3274 as_bad("%s number illegal. Absolute 0 assumed.",
3275 exp.X_add_number > 0 ? "Bignum" : "Floating-Point");
3276 symbolP->sy_type = N_ABS | ext;
3277 symbolP->sy_other = 0; /* NO_SECT */
3278 symbolP->sy_value = 0;
3279 symbolP->sy_frag = &zero_address_frag;
3280 break;
3282 case SEG_NONE:
3283 as_bad("No expression: Using absolute 0");
3284 symbolP->sy_type = N_ABS | ext;
3285 symbolP->sy_other = 0; /* NO_SECT */
3286 symbolP->sy_value = 0;
3287 symbolP->sy_frag = &zero_address_frag;
3288 break;
3290 case SEG_DIFFSECT:
3291 if(exp.X_add_symbol && exp.X_subtract_symbol){
3292 if(exp.X_add_symbol->sy_frag !=
3293 exp.X_subtract_symbol->sy_frag ||
3294 exp.X_add_symbol->sy_type == N_UNDF ||
3295 exp.X_subtract_symbol->sy_type == N_UNDF ){
3296 expressionS *expression;
3298 expression = xmalloc(sizeof(expressionS));
3299 *expression = exp;
3300 symbolP->expression = expression;
3302 else{
3303 exp.X_add_number += exp.X_add_symbol->sy_value -
3304 exp.X_subtract_symbol->sy_value;
3307 else if(exp.X_add_symbol &&
3308 exp.X_subtract_symbol == NULL &&
3309 exp.X_add_symbol->expression != NULL){
3310 expressionS *expression;
3312 expression = xmalloc(sizeof(expressionS));
3313 memcpy(expression, exp.X_add_symbol->expression,
3314 sizeof(expressionS));
3315 symbolP->expression = expression;
3317 else
3318 as_bad("Complex expression. Absolute segment assumed." );
3319 symbolP->sy_type = N_ABS | ext;
3320 symbolP->sy_other = 0; /* NO_SECT */
3321 symbolP->sy_value = exp.X_add_number;
3322 symbolP->sy_frag = &zero_address_frag;
3323 break;
3325 case SEG_ABSOLUTE:
3326 symbolP->sy_type = N_ABS | ext;
3327 symbolP->sy_other = 0; /* NO_SECT */
3328 symbolP->sy_value = exp.X_add_number;
3329 symbolP->sy_frag = &zero_address_frag;
3330 symbolP->expression = NULL;
3331 break;
3333 case SEG_SECT:
3334 symbolP->sy_type = N_SECT | ext;
3335 symbolP->sy_other = exp.X_add_symbol->sy_other;
3336 symbolP->sy_value = exp.X_add_number + exp.X_add_symbol->sy_value;
3337 symbolP->sy_frag = exp.X_add_symbol->sy_frag;
3338 break;
3340 case SEG_UNKNOWN:
3341 symbolP->sy_forward = exp.X_add_symbol;
3342 /* commented out by GNU */
3343 /* as_bad("unknown symbol"); */
3344 /* need_pass_2 = TRUE; */
3345 break;
3347 default:
3348 BAD_CASE(segment);
3349 break;
3354 * cons()
3356 * CONStruct more frag of .bytes, or .words etc.
3357 * This understands EXPRESSIONS, as opposed to big_cons().
3359 * Bug (?)
3361 * This has a split personality. We use expression() to read the
3362 * value. We can detect if the value won't fit in a byte or word.
3363 * But we can't detect if expression() discarded significant digits
3364 * in the case of a long. Not worth the crocks required to fix it.
3366 * Worker function to do .byte, .short, .long, .quad statements.
3367 * This clobbers input_line_pointer, checks end-of-line.
3369 void
3370 cons(
3371 uintptr_t nbytes) /* nbytes == 1 for .byte, 2 for .word, 4 for .long, 8 for .quad */
3373 char c;
3374 signed_expr_t
3375 mask, /* high-order bits to truncate */
3376 unmask, /* what bits we will store */
3377 get, /* the bits of the expression we get */
3378 use; /* the bits of the expression after truncation */
3379 char *p; /* points into the frag */
3380 segT segment;
3381 expressionS exp;
3382 #ifndef TC_CONS_FIX_NEW
3383 fixS *fixP;
3384 #endif
3386 memset(&exp, '\0', sizeof(exp));
3388 * Input_line_pointer -> 1st char after pseudo-op-code and could legally
3389 * be a end-of-line. (Or, less legally an eof - which we cope with.)
3391 if(nbytes >= (int)sizeof(signed_expr_t))
3392 mask = 0;
3393 else
3394 /* Don't store these bits. */
3395 mask = ~0ULL << (BITS_PER_CHAR * nbytes);
3396 unmask = ~mask; /* Do store these bits. */
3399 * The following awkward logic is to parse ZERO or more expressions,
3400 * comma seperated. Recall an expression includes its leading &
3401 * trailing blanks. We fake a leading ',' if there is (supposed to
3402 * be) a 1st expression, and keep demanding 1 expression for each ','.
3404 if(is_it_end_of_statement()){
3405 c = 0; /* Skip loop. */
3406 input_line_pointer++; /* Matches end-of-loop 'correction'. */
3408 else
3409 c = ','; /* Do loop. */
3411 while(c == ','){
3412 #ifdef TC_PARSE_CONS_EXPRESSION
3413 segment = TC_PARSE_CONS_EXPRESSION(&exp, nbytes);
3414 #else
3415 segment = expression(&exp); /* At least scan over the expression */
3416 #endif
3418 if(segment == SEG_DIFFSECT && exp.X_add_symbol == NULL){
3419 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too "
3420 "hard. Absolute segment assumed.",
3421 exp.X_subtract_symbol->sy_name,
3422 seg_name[(int)N_TYPE_seg[
3423 exp.X_subtract_symbol->sy_type & N_TYPE]]);
3424 segment = SEG_ABSOLUTE;
3425 /* Leave exp .X_add_number alone. */
3427 p = frag_more(nbytes);
3428 switch(segment){
3429 case SEG_BIG:
3431 * Handle bignums small enough to fit in a long long and
3432 * thus be passed directly to md_number_to_chars.
3434 if(exp.X_add_number > 0 &&
3435 (((LITTLENUM_NUMBER_OF_BITS * exp.X_add_number) / 8) <=
3436 sizeof(int64_t))){
3437 int i;
3438 int64_t sum;
3440 sum = 0;
3441 for(i = 0; i < exp.X_add_number; ++i)
3442 sum = (sum << LITTLENUM_NUMBER_OF_BITS) +
3443 generic_bignum[(exp.X_add_number - 1) - i];
3444 md_number_to_chars(p, sum, nbytes);
3446 else
3448 as_bad("%s number illegal. Absolute 0 assumed.",
3449 exp.X_add_number > 0 ? "Bignum" : "Floating-Point");
3450 md_number_to_chars(p, (int32_t)0, nbytes);
3452 break;
3454 case SEG_NONE:
3455 as_bad("0 assumed for missing expression");
3456 exp.X_add_number = 0;
3457 know(exp.X_add_symbol == NULL);
3458 /* fall into SEG_ABSOLUTE */
3460 case SEG_ABSOLUTE:
3461 get = exp.X_add_number;
3462 use = get & unmask;
3463 if((get & mask) && (get & mask) != mask){
3464 /* Leading bits contain both 0s & 1s. */
3465 as_bad("Value 0x%llx truncated to 0x%llx.", get, use);
3467 dwarf2_emit_insn(nbytes);
3468 /* put bytes in right order. */
3469 md_number_to_chars(p, use, nbytes);
3470 break;
3472 case SEG_DIFFSECT:
3473 case SEG_UNKNOWN:
3474 case SEG_SECT:
3475 #ifdef TC_CONS_FIX_NEW
3476 TC_CONS_FIX_NEW(frag_now,
3477 p - frag_now->fr_literal,
3478 nbytes,
3479 &exp);
3480 #else
3481 fixP = fix_new(frag_now,
3482 p - frag_now->fr_literal,
3483 nbytes,
3484 exp.X_add_symbol,
3485 exp.X_subtract_symbol,
3486 exp.X_add_number,
3491 * If we have the special assembly time constant expression
3492 * of the difference of two symbols defined in the same section
3493 * then divided by exactly 2 mark the fix to indicate this.
3495 fixP->fx_sectdiff_divide_by_two = exp.X_sectdiff_divide_by_two;
3496 #endif
3497 break;
3499 default:
3500 BAD_CASE(segment);
3501 break;
3502 } /* switch(segment) */
3503 c = *input_line_pointer++;
3504 } /* while(c==',') */
3505 input_line_pointer--; /* Put terminator back into stream. */
3506 demand_empty_rest_of_line();
3509 #ifdef M68K /* we allow big cons only on the 68k machines */
3511 * big_cons()
3513 * CONStruct more frag(s) of .quads, or .octa etc.
3514 * Makes 0 or more new frags.
3515 * This understands only bignums, not expressions. Cons() understands
3516 * expressions.
3518 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
3520 * This creates objects with struct obstack_control objs, destroying
3521 * any context objs held about a partially completed object. Beware!
3524 * I think it sucks to have 2 different types of integers, with 2
3525 * routines to read them, store them etc.
3526 * It would be nicer to permit bignums in expressions and only
3527 * complain if the result overflowed. However, due to "efficiency"...
3529 * Worker function to do .quad and .octa statements.
3530 * This clobbers input_line_pointer, checks end-of-line.
3532 void
3533 big_cons(
3534 uintptr_t nbytes) /* 8 == .quad, 16 == .octa ... */
3536 char c; /* input_line_pointer -> c. */
3537 int radix;
3538 int32_t length;/* Number of chars in an object. */
3539 int digit; /* Value of 1 digit. */
3540 int carry; /* For multi-precision arithmetic. */
3541 int work; /* For multi-precision arithmetic. */
3542 char *p,*q; /* For multi-precision arithmetic. */
3543 int i;
3546 * The following awkward logic is to parse ZERO or more strings,
3547 * comma seperated. Recall an expression includes its leading &
3548 * trailing blanks. We fake a leading ',' if there is (supposed to
3549 * be) a 1st expression, and keep demanding 1 expression for each ','.
3551 if(is_it_end_of_statement()){
3552 c = 0; /* Skip loop. */
3554 else{
3555 c = ','; /* Do loop. */
3556 --input_line_pointer;
3558 while(c == ','){
3559 ++input_line_pointer;
3560 SKIP_WHITESPACE();
3561 c = *input_line_pointer;
3562 /* c contains 1st non-blank char of what we hope is a number */
3563 if(c == '0'){
3564 c = *++input_line_pointer;
3565 if(c == 'x' || c=='X'){
3566 c = *++input_line_pointer;
3567 radix = 16;
3569 else{
3570 radix = 8;
3573 else{
3574 radix = 10;
3577 * This feature (?) is here to stop people worrying about
3578 * mysterious zero constants: which is what they get when
3579 * they completely omit digits.
3581 if(hex_value[(int)c] >= radix){
3582 as_bad("Missing digits. 0 assumed.");
3584 bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
3585 for( ;
3586 (digit = hex_value[(int)c]) < radix;
3587 c = *++input_line_pointer){
3588 /* Multiply existing number by radix, then add digit. */
3589 carry = digit;
3590 for(p = bignum_low; p <= bignum_high; p++){
3591 work = (*p & MASK_CHAR) * radix + carry;
3592 *p = work & MASK_CHAR;
3593 carry = work >> BITS_PER_CHAR;
3595 if(carry){
3596 grow_bignum();
3597 *bignum_high = carry & MASK_CHAR;
3598 know((carry & ~ MASK_CHAR) == 0);
3601 length = bignum_high - bignum_low + 1;
3602 if(length > nbytes){
3603 as_bad("Most significant bits truncated in integer constant.");
3605 else{
3606 int32_t leading_zeroes;
3608 for(leading_zeroes = nbytes - length;
3609 leading_zeroes;
3610 leading_zeroes--){
3611 grow_bignum();
3612 *bignum_high = 0;
3615 p = frag_more(nbytes);
3616 if(md_target_byte_sex == BIG_ENDIAN_BYTE_SEX){
3617 q = (char *)bignum_low;
3618 for(i = nbytes - 1; i >= 0; i--)
3619 *p++ = q[i];
3621 else{
3622 memcpy(p, bignum_low, (int)nbytes);
3624 /* C contains character after number. */
3625 SKIP_WHITESPACE();
3626 c = *input_line_pointer;
3627 /* C contains 1st non-blank character after number. */
3629 demand_empty_rest_of_line();
3633 * grow_bignum() extends bignum (that is adjust bignum_low, bignum_high and
3634 * bignum_limit).
3636 static
3637 void
3638 grow_bignum(
3639 void)
3641 int32_t length;
3643 bignum_high++;
3644 if(bignum_high >= bignum_limit)
3646 length = bignum_limit - bignum_low;
3647 bignum_low = xrealloc(bignum_low, length + length);
3648 bignum_high = bignum_low + length;
3649 bignum_limit = bignum_low + length + length;
3652 #endif /* M68K we allow big cons only on the 68k machines */
3655 * float_cons()
3657 * CONStruct some more frag chars of .floats .ffloats etc.
3658 * Makes 0 or more new frags.
3659 * This understands only floating literals, not expressions. Sorry.
3661 * A floating constant is defined by atof_generic(), except it is preceded
3662 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
3663 * reading, I decided to be incompatible. This always tries to give you
3664 * rounded bits to the precision of the pseudo-op. Former AS did premature
3665 * truncatation, restored noisy bits instead of trailing 0s AND gave you
3666 * a choice of 2 flavours of noise according to which of 2 floating-point
3667 * scanners you directed AS to use.
3669 * In: input_line_pointer -> whitespace before, or '0' of flonum.
3671 * Worker function to do .double, .float, .single statements.
3672 * This clobbers input_line-pointer, checks end-of-line.
3674 void
3675 float_cons(
3676 uintptr_t float_type) /* 'f':.ffloat ... 'F':.float ... */
3678 char *p;
3679 char c;
3680 int length; /* Number of chars in an object. */
3681 char *err; /* Error from scanning floating literal. */
3682 char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
3685 * The following awkward logic is to parse ZERO or more strings,
3686 * comma seperated. Recall an expression includes its leading &
3687 * trailing blanks. We fake a leading ',' if there is (supposed to
3688 * be) a 1st expression, and keep demanding 1 expression for each ','.
3690 if(is_it_end_of_statement()){
3691 c = 0; /* Skip loop. */
3692 ++input_line_pointer; /* -> past termintor. */
3694 else{
3695 c = ','; /* Do loop. */
3697 while(c == ','){
3698 /* input_line_pointer -> 1st char of a flonum (we hope!). */
3699 SKIP_WHITESPACE();
3701 * Skip any 0{letter} that may be present. Don't even check if the
3702 * letter is legal. Someone may invent a "z" format and this routine
3703 * has no use for such information. Lusers beware: you get
3704 * diagnostics if your input is ill-conditioned.
3706 if(input_line_pointer[0] == '0' && isalpha(input_line_pointer[1]))
3707 input_line_pointer+=2;
3709 err = md_atof(float_type, temp, &length);
3710 know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
3711 know(length > 0);
3712 if(err != NULL && *err != '\0'){
3713 as_bad( "Bad floating literal: %s", err);
3714 ignore_rest_of_line();
3715 /* Input_line_pointer -> just after end-of-line. */
3716 c = 0; /* Break out of loop. */
3718 else{
3719 p = frag_more(length);
3720 memcpy(p, temp, length);
3721 SKIP_WHITESPACE();
3722 c = *input_line_pointer ++;
3723 /* C contains 1st non-white character after number. */
3724 /* input_line_pointer -> just after terminator (c). */
3727 --input_line_pointer; /* -> terminator (is not ','). */
3728 demand_empty_rest_of_line();
3731 static void
3732 emit_leb128_expr (expressionS *exp, int sign)
3734 segT op = exp->X_op;
3735 #ifdef notyet
3736 unsigned int nbytes;
3737 #endif
3739 if (op == O_absent)
3741 as_warn (_("zero assumed for missing expression"));
3742 exp->X_add_number = 0;
3743 op = O_constant;
3745 else if (op == O_big && exp->X_add_number <= 0)
3747 as_bad (_("floating point number invalid"));
3748 exp->X_add_number = 0;
3749 op = O_constant;
3751 #ifdef notyet
3752 else if (op == O_register)
3754 as_warn (_("register value used as expression"));
3755 op = O_constant;
3757 else if (op == O_constant
3758 && sign
3759 && (exp->X_add_number < 0) != !exp->X_unsigned)
3761 /* We're outputting a signed leb128 and the sign of X_add_number
3762 doesn't reflect the sign of the original value. Convert EXP
3763 to a correctly-extended bignum instead. */
3764 convert_to_bignum (exp);
3765 op = O_big;
3768 /* Let check_eh_frame know that data is being emitted. nbytes == -1 is
3769 a signal that this is leb128 data. It shouldn't optimize this away. */
3770 nbytes = (unsigned int) -1;
3771 if (check_eh_frame (exp, &nbytes))
3772 abort ();
3774 /* Let the backend know that subsequent data may be byte aligned. */
3775 #ifdef md_cons_align
3776 md_cons_align (1);
3777 #endif
3778 #endif /* notyet */
3780 if (op == O_constant)
3782 /* If we've got a constant, emit the thing directly right now. */
3784 #if ALLOW_64BIT_LEB_ON_32B_TARGET
3785 int64_t value = exp->X_add_number;
3786 #else
3787 valueT value = exp->X_add_number;
3788 #endif
3789 int size;
3790 char *p;
3792 size = sizeof_leb128 (value, sign);
3793 p = frag_more (size);
3794 output_leb128 (p, value, sign);
3796 #ifdef notyet
3797 else if (op == O_big)
3799 /* O_big is a different sort of constant. */
3801 int size;
3802 char *p;
3804 size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign);
3805 p = frag_more (size);
3806 output_big_leb128 (p, generic_bignum, exp->X_add_number, sign);
3808 #endif /* notyet */
3809 else
3811 /* Otherwise, we have to create a variable sized fragment and
3812 resolve things later. */
3814 #ifdef OLD
3815 frag_var (rs_leb128, sizeof_uleb128 (~(valueT) 0), 0, sign,
3816 make_expr_symbol (exp), 0, (char *) NULL);
3817 #else
3818 symbolS *sym;
3819 expressionS *expression;
3821 sym = symbol_temp_new(exp->X_add_symbol->sy_other /* GUESS */, 0, NULL);
3822 expression = xmalloc(sizeof(expressionS));
3823 *expression = *exp;
3824 sym->expression = expression;
3825 sym->sy_frag = &zero_address_frag;
3826 frag_var (rs_leb128, sizeof_leb128 ( ((valueT) (~(valueT) 0) >> 1), 0), 0, sign,
3827 sym, 0, (char *) NULL);
3828 frchain_now->has_rs_leb128s = TRUE;
3829 #endif
3834 /* Parse the .sleb128 and .uleb128 pseudos. */
3836 static
3837 void
3838 s_leb128(
3839 uintptr_t sign)
3841 expressionS exp;
3843 #ifdef md_flush_pending_output
3844 md_flush_pending_output ();
3845 #endif
3849 expression (&exp);
3850 emit_leb128_expr (&exp, sign);
3852 while (*input_line_pointer++ == ',');
3854 input_line_pointer--;
3855 demand_empty_rest_of_line ();
3859 * stringer()
3861 * We read 0 or more ',' seperated, double-quoted strings.
3863 * Worker function to do .ascii etc statements.
3864 * Checks end-of-line.
3866 void
3867 stringer(
3868 uintptr_t append_zero) /* 0: don't append '\0', else 1 */
3870 int c;
3873 * The following awkward logic is to parse ZERO or more strings,
3874 * comma seperated. Recall a string expression includes spaces
3875 * before the opening '\"' and spaces after the closing '\"'.
3876 * We fake a leading ',' if there is (supposed to be)
3877 * a 1st, expression. We keep demanding expressions for each
3878 * ','.
3880 if(is_it_end_of_statement()){
3881 c = 0; /* Skip loop. */
3882 ++ input_line_pointer; /* Compensate for end of loop. */
3884 else{
3885 c = ','; /* Do loop. */
3887 for( ; c == ','; c = *input_line_pointer++){
3888 SKIP_WHITESPACE();
3889 if(*input_line_pointer == '\"'){
3890 ++input_line_pointer; /* -> 1st char of string. */
3891 while((c = next_char_of_string()) >= 0){
3892 FRAG_APPEND_1_CHAR(c);
3894 if(append_zero){
3895 FRAG_APPEND_1_CHAR(0);
3897 know(input_line_pointer[-1] == '\"');
3899 else{
3900 as_bad("Expected \"-ed string");
3902 SKIP_WHITESPACE();
3904 --input_line_pointer;
3905 demand_empty_rest_of_line();
3909 * next_char_of_string() is used by stringer() and demand_copy_string() and
3910 * returns the next character from input_line_pointer that is in the string or
3911 * -1 for the trailing " character. This routine handles escaped characters
3912 * like \b, \f, etc.
3914 static
3916 next_char_of_string(
3917 void)
3919 int c;
3920 int32_t number, i;
3922 c = *input_line_pointer++;
3923 /* make sure the 0xff char is not returned as -1 */
3924 c = (c & MASK_CHAR);
3925 switch(c){
3926 case '\"':
3927 #ifdef PPC
3928 if(flagseen[(int)'p'] == TRUE)
3929 break;
3930 #endif /* PPC */
3931 c = -1;
3932 break;
3934 #ifdef PPC
3935 case '\'':
3936 if(flagseen[(int)'p'] == TRUE)
3937 c = -1;
3938 break;
3939 #endif /* PPC */
3941 case '\\':
3942 c = *input_line_pointer++;
3943 switch(c){
3944 case 'b':
3945 c = '\b';
3946 break;
3947 case 'f':
3948 c = '\f';
3949 break;
3950 case 'n':
3951 c = '\n';
3952 break;
3953 case 'r':
3954 c = '\r';
3955 break;
3956 case 't':
3957 c = '\t';
3958 break;
3959 case '\\':
3960 case '"':
3961 case '\'':
3962 break; /* As itself. */
3963 case '0':
3964 case '1':
3965 case '2':
3966 case '3':
3967 case '4':
3968 case '5':
3969 case '6':
3970 case '7':
3971 case '8':
3972 case '9':
3973 for(i = 0, number = 0;
3974 i < 3 && isdigit(c) && c < '8';
3975 i++, c = *input_line_pointer++)
3976 number = number * 8 + c - '0';
3977 c = number;
3978 --input_line_pointer;
3979 break;
3980 case '\n':
3981 /* To be compatible with BSD 4.2 as: give the user a linefeed */
3982 c = '\n';
3983 break;
3985 default:
3986 as_bad( "Bad escaped character in string, '?' assumed" );
3987 c = '?';
3988 break;
3990 break;
3991 default:
3992 break;
3994 return(c);
3998 * get_segmented_expression() is passed an expression to fill in and return that
3999 * is anything except a bignum or a missing expression.
4001 static
4002 segT
4003 get_segmented_expression(
4004 expressionS *expP)
4006 segT retval;
4008 retval = expression(expP);
4009 if(retval == SEG_NONE || retval == SEG_BIG){
4010 as_bad("Expected address expression: absolute 0 assumed");
4011 retval = expP->X_seg = SEG_ABSOLUTE;
4012 expP->X_add_number = 0;
4013 expP->X_add_symbol = NULL;
4014 expP->X_subtract_symbol = NULL;
4016 return(retval); /* SEG_ ABSOLUTE,UNKNOWN,SECT */
4020 * get_known_segmented_expression() is passed an expression to fill in and
4021 * return that is anything except an unknown, bignum or a missing expression.
4023 segT
4024 get_known_segmented_expression(
4025 expressionS *expP)
4027 segT retval;
4028 char *name1;
4029 char *name2;
4031 retval = get_segmented_expression(expP);
4032 if(retval == SEG_UNKNOWN){
4033 name1 = expP->X_add_symbol ?
4034 expP->X_add_symbol->sy_name : "";
4035 name2 = expP->X_subtract_symbol ?
4036 expP->X_subtract_symbol->sy_name : "";
4037 if(name1 && name2){
4038 as_bad("Symbols \"%s\" \"%s\" are undefined: absolute 0 "
4039 "assumed.", name1, name2);
4041 else{
4042 as_bad("Symbol \"%s\" undefined: absolute 0 assumed.",
4043 name1 ? name1 : name2);
4045 retval = SEG_ABSOLUTE;
4046 expP->X_seg = SEG_ABSOLUTE;
4047 expP->X_add_number = 0;
4048 expP->X_add_symbol = NULL;
4049 expP->X_subtract_symbol = NULL;
4051 know(retval == SEG_ABSOLUTE ||
4052 retval == SEG_SECT ||
4053 retval == SEG_DIFFSECT);
4054 return(retval);
4058 * get_absolute_expression() gets an absolute expression and returns the value
4059 * of that expression.
4061 signed_target_addr_t
4062 get_absolute_expression(
4063 void)
4065 expressionS exp;
4066 segT s;
4068 s = expression(&exp);
4069 if(s != SEG_ABSOLUTE){
4070 /* is this right? if not absolute: no message and return 0 */
4071 if(s != SEG_NONE){
4072 as_bad("Bad Absolute Expression, absolute 0 assumed.");
4074 exp.X_add_number = 0;
4076 return(exp.X_add_number);
4080 * get_absolute_expression_and_terminator() gets an absolute expression and
4081 * returning the value of that expression indirectly through val_pointer and
4082 * returns the terminator.
4084 static
4085 char /* return terminator */
4086 get_absolute_expression_and_terminator(
4087 int32_t *val_pointer) /* return value of expression */
4089 *val_pointer = get_absolute_expression();
4090 return(*input_line_pointer++);
4094 * demand_copy_C_string()
4096 * Like demand_copy_string, but return NULL if the string contains any '\0's.
4097 * Give a warning if that happens.
4099 char *
4100 demand_copy_C_string(
4101 int *len_pointer)
4103 char *s;
4104 int len;
4106 if((s = demand_copy_string(len_pointer))){
4107 for(len = *len_pointer; len > 0; len--){
4108 if(*s == '\0'){
4109 s = 0;
4110 len = 1;
4111 *len_pointer = 0;
4112 as_bad("This string may not contain \'\\0\'");
4116 return(s);
4120 * demand_copy_string()
4122 * Demand string, but return a safe (=private) copy of the string.
4123 * Return NULL if we can't read a string here.
4125 static
4126 char *
4127 demand_copy_string(
4128 int *lenP)
4130 int c;
4131 int len;
4132 char *retval;
4134 len = 0;
4135 SKIP_WHITESPACE();
4136 #ifdef PPC
4137 if((flagseen[(int)'p'] == TRUE && *input_line_pointer == '\'') ||
4138 (flagseen[(int)'p'] == FALSE && *input_line_pointer == '\"'))
4139 #else
4140 if(*input_line_pointer == '\"')
4141 #endif
4143 input_line_pointer++; /* Skip opening quote. */
4144 while((c = next_char_of_string()) >= 0){
4145 (void)(obstack_1grow(&notes, c));
4146 len++;
4149 * This next line is so demand_copy_C_string will return a null
4150 * termanated string.
4152 (void)(obstack_1grow(&notes, '\0'));
4153 retval = obstack_finish(&notes);
4155 else{
4156 as_bad("Missing string");
4157 retval = NULL;
4158 ignore_rest_of_line();
4160 *lenP = len;
4161 return(retval);
4165 * is_it_end_of_statement()
4167 * In: Input_line_pointer -> next character.
4169 * Do: Skip input_line_pointer over all whitespace.
4171 * Out: TRUE if input_line_pointer -> end-of-line.
4173 static
4175 is_it_end_of_statement(
4176 void)
4178 SKIP_WHITESPACE();
4179 return(is_end_of_line(*input_line_pointer));
4183 * equals() implements the assembly statement:
4184 * x = expression
4186 static
4187 void
4188 equals(
4189 char *sym_name)
4191 struct symbol *symbolP;
4192 segT segment;
4193 expressionS exp;
4194 char *p;
4196 /* Turn '. = mumble' into a .org mumble */
4197 if(sym_name[0]=='.' && sym_name[1]=='\0'){
4198 if(input_line_pointer[1] == '=')
4199 input_line_pointer += 2;
4200 else
4201 *input_line_pointer++ = '='; /* Put it back */
4202 if(*input_line_pointer==' ' || *input_line_pointer=='\t')
4203 input_line_pointer++;
4204 segment = get_known_segmented_expression(&exp);
4205 if((segment != SEG_SECT ||
4206 exp.X_add_symbol->sy_other != frchain_now->frch_nsect) &&
4207 segment != SEG_ABSOLUTE)
4208 as_bad("Illegal expression. current section assumed.");
4209 p = frag_var(rs_org,
4212 (relax_substateT)0,
4213 exp.X_add_symbol,
4214 exp.X_add_number,
4215 (char *)0);
4216 *p = 0;
4217 return;
4220 symbolP = symbol_find_or_make(sym_name);
4221 if(symbolP->sy_type & N_ABS)
4222 symbolP->sy_desc |= N_NO_DEAD_STRIP;
4223 if(input_line_pointer[1] == '=')
4224 input_line_pointer += 2;
4225 else
4226 *input_line_pointer++ = '='; /* Put it back */
4227 if(*input_line_pointer==' ' || *input_line_pointer=='\t')
4228 input_line_pointer++;
4229 pseudo_set(symbolP);
4233 * s_if() implements the pseudo op:
4234 * .if expression
4235 * that does conditional assembly using assembler defined expressions.
4237 static
4238 void
4239 s_if(
4240 uintptr_t value)
4242 if(if_depth >= MAX_IF_DEPTH)
4243 as_fatal("You can't nest if's more than %d levels deep",
4244 MAX_IF_DEPTH);
4245 last_states[if_depth++] = the_cond_state;
4246 the_cond_state.the_cond = if_cond;
4247 if(the_cond_state.ignore)
4248 totally_ignore_line();
4249 else{
4250 the_cond_state.cond_met = get_absolute_expression();
4251 the_cond_state.ignore = !the_cond_state.cond_met;
4252 demand_empty_rest_of_line();
4257 * s_elseif() implements the pseudo op:
4258 * .elseif expression
4259 * that does conditional assembly using assembler defined expressions.
4261 static
4262 void
4263 s_elseif(
4264 uintptr_t value)
4266 int last_ignore_state;
4268 if(the_cond_state.the_cond != if_cond &&
4269 the_cond_state.the_cond != elseif_cond)
4270 as_fatal("Encountered a .elseif that doesn't follow a .if or an "
4271 ".elseif");
4272 the_cond_state.the_cond = elseif_cond;
4274 last_ignore_state = FALSE;
4275 if(if_depth)
4276 last_ignore_state = last_states[if_depth-1].ignore;
4277 if(last_ignore_state || the_cond_state.cond_met){
4278 the_cond_state.ignore = TRUE;
4279 totally_ignore_line();
4281 else{
4282 the_cond_state.cond_met = get_absolute_expression();
4283 the_cond_state.ignore = !the_cond_state.cond_met;
4284 demand_empty_rest_of_line();
4289 * s_else() implements the pseudo op:
4290 * .else
4291 * that does conditional assembly using assembler defined expressions.
4293 static
4294 void
4295 s_else(
4296 uintptr_t value)
4298 int last_ignore_state;
4300 if(the_cond_state.the_cond != if_cond &&
4301 the_cond_state.the_cond != elseif_cond)
4302 as_fatal("Encountered a .else that doesn't follow a .if or an "
4303 ".elseif");
4304 the_cond_state.the_cond = else_cond;
4305 last_ignore_state = FALSE;
4306 if(if_depth)
4307 last_ignore_state = last_states[if_depth-1].ignore;
4308 if(last_ignore_state || the_cond_state.cond_met)
4309 the_cond_state.ignore = TRUE;
4310 else
4311 the_cond_state.ignore = FALSE;
4312 demand_empty_rest_of_line();
4316 * s_endif() implements the pseudo op:
4317 * .endif
4318 * that does conditional assembly using assembler defined expressions.
4320 static
4321 void
4322 s_endif(
4323 uintptr_t value)
4325 if((the_cond_state.the_cond == no_cond) || (if_depth == 0))
4326 as_fatal("Encountered a .endif that doesn't follow a .if or .else");
4327 the_cond_state = last_states[--if_depth];
4328 demand_empty_rest_of_line();
4332 * totally_ignore_line() ignores lines during conditional assembly.
4334 void
4335 totally_ignore_line(
4336 void)
4338 if(!is_end_of_line(*input_line_pointer)){
4339 while(input_line_pointer < buffer_limit &&
4340 !is_end_of_line(*input_line_pointer)){
4341 input_line_pointer ++;
4344 input_line_pointer++; /* Return pointing just after end-of-line. */
4345 know(is_end_of_line(input_line_pointer[-1]));
4349 * s_macros_on() implements the pseudo op:
4350 * .macros_on
4352 static
4353 void
4354 s_macros_on(
4355 uintptr_t value)
4357 macros_on = TRUE;
4358 demand_empty_rest_of_line();
4362 * s_macros_off() implements the pseudo op:
4363 * .macros_off
4365 void
4366 s_macros_off(
4367 uintptr_t value)
4369 macros_on = FALSE;
4370 demand_empty_rest_of_line();
4374 * s_macro() implements the pseudo op:
4375 * .macro macro_name
4376 * that defines a macro.
4378 void
4379 s_macro(
4380 uintptr_t value)
4382 int c;
4383 pseudo_typeS *pop;
4385 if(macro_name)
4386 as_bad("Can't define a macro inside another macro definition");
4387 else{
4388 SKIP_WHITESPACE();
4389 while(is_part_of_name(c = *input_line_pointer ++))
4390 (void)(obstack_1grow (&macros, c));
4391 (void)(obstack_1grow(&macros, '\0'));
4392 --input_line_pointer;
4393 macro_name = obstack_finish(&macros);
4394 if(macro_name == NULL)
4395 as_bad("Missing name of macro");
4396 if(*macro_name == '.'){
4397 pop = (pseudo_typeS *)hash_find(po_hash, macro_name + 1);
4398 if(pop != NULL)
4399 as_bad("Pseudo-op name: %s can't be a macro name",
4400 macro_name);
4403 totally_ignore_line();
4407 * s_endmacro() implements the pseudo op:
4408 * .endmacro
4409 * which is the end of a macro definition.
4411 void
4412 s_endmacro(
4413 uintptr_t value)
4415 const char *errorString;
4417 if(!macro_name){
4418 as_bad ("This .endmacro does not match with a preceding .macro");
4419 ignore_rest_of_line();
4421 else{
4422 (void)(obstack_1grow(&macros, '\0'));
4423 errorString = hash_insert(ma_hash, macro_name,
4424 obstack_finish(&macros));
4425 if(errorString != NULL && *errorString)
4426 as_warn("The macro named \"%s\" is already defined",
4427 macro_name);
4428 macro_name = NULL;
4433 * macro_begin() initializes macros.
4435 static
4436 void
4437 macro_begin(
4438 void)
4440 ma_hash = hash_new();
4441 obstack_begin(&macros, 5000);
4445 * add_to_macro_definition() is called after a .macro to store the contents of
4446 * a macro into the obstack.
4448 void
4449 add_to_macro_definition(
4450 char *char_pointer)
4452 char c;
4455 c = *char_pointer ++;
4456 know(c != '\0');
4457 (void)(obstack_1grow(&macros, c));
4458 }while((c != ':') && !(is_end_of_line(c)));
4459 if(char_pointer > input_line_pointer)
4460 input_line_pointer = char_pointer;
4464 * expand_macro() is called to expand macros.
4466 static
4467 void
4468 expand_macro(
4469 char *macro_contents)
4471 char *buffer;
4472 char c;
4473 int index, nargs;
4474 char *last_buffer_limit;
4475 int last_count_lines;
4476 char *last_input_line_pointer;
4477 char *arguments [10]; /* at most 10 arguments, each is substituted */
4479 if(macro_depth >= MAX_MACRO_DEPTH)
4480 as_fatal("You can't nest macros more than %d levels deep",
4481 MAX_MACRO_DEPTH);
4482 macro_depth++;
4484 /* copy each argument to a object in the macro obstack */
4485 nargs = 0;
4486 for(index = 0; index < 10; index ++){
4487 if(*input_line_pointer == ' ')
4488 ++input_line_pointer;
4489 know(*input_line_pointer != ' ');
4490 c = *input_line_pointer;
4491 if(is_end_of_line(c))
4492 arguments[index] = NULL;
4493 else{
4494 int parenthesis_depth = 0;
4496 SKIP_WHITESPACE();
4497 c = *input_line_pointer++;
4498 if(parenthesis_depth){
4499 if(c == ')')
4500 parenthesis_depth --;
4502 else{
4503 if(c == '(')
4504 parenthesis_depth ++;
4505 else
4506 if(is_end_of_line(c) ||
4507 (c == ' ') || (c == ','))
4508 break;
4510 know(c != '\0');
4511 if(is_end_of_line(c))
4512 as_bad("mismatched parenthesis");
4513 (void)(obstack_1grow(&macros, c));
4514 }while(1);
4515 (void)(obstack_1grow(&macros, '\0'));
4516 arguments[index] = obstack_finish(&macros);
4517 nargs++;
4518 if(is_end_of_line(c))
4519 --input_line_pointer;
4520 else if(c == ' ')
4521 if(*input_line_pointer == ',')
4522 input_line_pointer++;
4525 if(!is_end_of_line(c)){
4526 as_bad("More than 10 arguments not allowed for macros");
4527 ignore_rest_of_line();
4530 * Build a buffer containing the macro contents with arguments
4531 * substituted
4533 (void)(obstack_1grow(&macros, '\n'));
4534 while((c = *macro_contents++)){
4535 if(c == '$'){
4536 if(*macro_contents == '$'){
4537 macro_contents++;
4539 else if((*macro_contents >= '0') && (*macro_contents <= '9')){
4540 index = *macro_contents++ - '0';
4541 last_input_line_pointer = macro_contents;
4542 macro_contents = arguments[index];
4543 if(macro_contents){
4544 while ((c = * macro_contents ++))
4545 (void)(obstack_1grow (&macros, c));
4547 macro_contents = last_input_line_pointer;
4548 continue;
4550 else if (*macro_contents == 'n'){
4551 macro_contents++ ;
4552 (void)(obstack_1grow(&macros, nargs + '0'));
4553 continue;
4556 (void)(obstack_1grow (&macros, c));
4558 (void)(obstack_1grow (&macros, '\n'));
4559 (void)(obstack_1grow (&macros, '\0'));
4560 last_buffer_limit = buffer_limit;
4561 last_count_lines = count_lines;
4562 last_input_line_pointer = input_line_pointer;
4563 buffer_limit = obstack_next_free (&macros) - 1;
4564 buffer = obstack_finish (&macros);
4565 count_lines = FALSE;
4567 printf("expanded macro: %s", buffer + 1);
4569 #ifdef PPC
4570 if(flagseen[(int)'p'] == TRUE)
4571 ppcasm_parse_a_buffer(buffer + 1);
4572 else
4573 #endif /* PPC */
4574 parse_a_buffer(buffer + 1);
4575 obstack_free (&macros, buffer);
4576 for(index = 9; index >= 0; index --)
4577 if(arguments[index])
4578 obstack_free(&macros, arguments[index]);
4579 buffer_limit = last_buffer_limit;
4580 count_lines = last_count_lines;
4581 input_line_pointer = last_input_line_pointer;
4582 macro_depth--;
4586 * s_dump() implements the pseudo op:
4587 * .dump filename
4588 * that does a quick binary dump of symbol tables.
4590 static
4591 void
4592 s_dump(
4593 uintptr_t value)
4595 char *filename;
4596 int length;
4597 static char null_string[] = "";
4599 if((filename = demand_copy_string(&length))){
4600 demand_empty_rest_of_line();
4601 if((dump_fp = fopen(filename, "w+"))){
4602 hash_traverse(ma_hash, write_macro);
4603 fwrite(null_string, 1, 1, dump_fp);
4604 hash_traverse(sy_hash, write_symbol);
4605 fwrite(null_string, 1, 1, dump_fp);
4606 fclose(dump_fp);
4608 else
4609 as_bad("couldn't write to dump file: \"%s\"", filename);
4614 * write_macro() used by hash_traverse indirectly through s_dump() to write one
4615 * macro.
4617 static
4618 void
4619 write_macro(
4620 const char *string,
4621 PTR value1)
4623 char *value = value1;
4624 know(string);
4625 know(value);
4626 know(strlen(string));
4627 fwrite(string, (strlen(string) + 1), 1, dump_fp);
4628 fwrite(value, (strlen(value) + 1), 1, dump_fp);
4632 * write_symbol() used by hash_traverse indirectly through s_dump() to write one
4633 * N_ABS symbol and its value.
4635 static
4636 void
4637 write_symbol(
4638 const char *string,
4639 PTR value)
4641 symbolS *symbolP;
4643 symbolP = (symbolS *)value;
4644 know(symbolP);
4645 if(((symbolP->sy_type) & N_TYPE) == N_ABS){
4646 know(string);
4647 know(strlen(string));
4648 fwrite(string, (strlen(string) + 1), 1, dump_fp);
4649 fwrite(&(symbolP -> sy_value), 4, 1, dump_fp);
4654 * s_load() implements the pseudo op:
4655 * .load filename
4656 * that does a quick binary load of symbol tables.
4658 static
4659 void
4660 s_load(
4661 uintptr_t value)
4663 char *char_pointer;
4664 char *filename;
4665 int length;
4666 char the_char;
4667 symbolS *the_symbol;
4668 symbolS *temp_symbol_lastP;
4669 static symbolS *dump_symbol_lastP;
4671 if((filename = demand_copy_string(&length))){
4672 demand_empty_rest_of_line();
4673 if((dump_fp = fopen(filename, "r+"))){
4676 the_char = getc_unlocked(dump_fp);
4677 (void)(obstack_1grow(&macros, the_char));
4678 }while(the_char);
4679 char_pointer = obstack_finish (&macros);
4680 if(!(*char_pointer))
4681 break;
4683 the_char = getc_unlocked(dump_fp);
4684 (void)(obstack_1grow(&macros, the_char));
4685 }while(the_char);
4686 if(hash_insert(ma_hash, char_pointer,
4687 obstack_finish(&macros)))
4688 as_bad("a macro named \"%s\" encountered in a .load "
4689 "is already defined", char_pointer);
4690 }while(1);
4692 * We don't want to link in symbols that were loaded so they
4693 * don't go out in the object file. Instead these symbols
4694 * should go out in the object file that did the .dump .
4696 temp_symbol_lastP = symbol_lastP;
4697 symbol_lastP = dump_symbol_lastP;
4700 the_char = getc_unlocked(dump_fp);
4701 (void)(obstack_1grow(&macros, the_char));
4702 }while(the_char);
4703 char_pointer = obstack_base(&macros);
4704 obstack_next_free(&macros) = char_pointer;
4705 if(!(*char_pointer))
4706 break;
4707 the_symbol = symbol_find_or_make(char_pointer);
4708 the_symbol->sy_type = N_ABS;
4709 char_pointer = (char *)&the_symbol->sy_value;
4710 *char_pointer++ = getc_unlocked(dump_fp);
4711 *char_pointer++ = getc_unlocked(dump_fp);
4712 *char_pointer++ = getc_unlocked(dump_fp);
4713 *char_pointer++ = getc_unlocked(dump_fp);
4714 the_symbol->sy_frag = &zero_address_frag;
4715 }while(1);
4716 dump_symbol_lastP = symbol_lastP;
4717 symbol_lastP = temp_symbol_lastP;
4718 fclose(dump_fp);
4720 else
4721 as_fatal("Couldn't find the dump file: \"%s\"", filename);
4726 * s_subsections_via_symbols() implements the pseudo op:
4727 * .subsections_via_symbols
4728 * which will cause the MH_SUBSECTIONS_VIA_SYMBOLS flag to be set in the output
4729 * file. This indicates to the static linker it is safe to divide up the
4730 * sections into sub-sections via symbols for dead code stripping.
4732 static
4733 void
4734 s_subsections_via_symbols(
4735 uintptr_t value)
4737 demand_empty_rest_of_line();
4738 subsections_via_symbols = TRUE;
4742 * s_machine() implements the pseudo op:
4743 * .machine <arch_name>
4744 * where <arch_name> is allowed to be the same strings as the argument to the
4745 * command line argument -arch <arch_name> .
4747 static
4748 void
4749 s_machine(
4750 uintptr_t value)
4752 char *arch_name, c;
4753 struct arch_flag arch_flag;
4754 cpu_subtype_t new_cpusubtype;
4755 const struct arch_flag *family_arch_flag;
4757 arch_name = input_line_pointer;
4759 * Can't call get_symbol_end() here as some arch names have '-' in them.
4762 c = *input_line_pointer++ ;
4763 }while(c != '\0' && c != '\n' && c != '\t' && c != ' ');
4764 *--input_line_pointer = 0;
4766 if(force_cpusubtype_ALL == FALSE){
4767 family_arch_flag = NULL;
4768 if(strcmp(arch_name, "all") == 0){
4769 family_arch_flag = get_arch_family_from_cputype(md_cputype);
4770 if(family_arch_flag != NULL)
4771 arch_flag = *family_arch_flag;
4773 if(family_arch_flag == NULL &&
4774 get_arch_from_flag(arch_name, &arch_flag) == 0){
4775 as_bad("unknown .machine argument: %s", arch_name);
4776 return;
4778 if(arch_flag.cputype != md_cputype){
4779 as_bad("invalid .machine argument: %s", arch_name);
4781 else{
4782 new_cpusubtype = cpusubtype_combine(md_cputype,
4783 md_cpusubtype,
4784 arch_flag.cpusubtype);
4785 if(new_cpusubtype == -1){
4786 as_bad(".machine argument: %s can not be combined "
4787 "with previous .machine directives, -arch "
4788 "arguments or machine specific instructions",
4789 arch_name);
4791 else{
4792 archflag_cpusubtype = new_cpusubtype;
4797 *input_line_pointer = c;
4798 demand_empty_rest_of_line();
4802 * s_secure_log_reset() implements the pseudo op:
4803 * .secure_log_reset
4804 * .secure_log_reset takes no parameters, and resets the "unique" counter. As
4805 * it is an error if a .s_secure_log_unique directive is seen twice without
4806 * and .secure_log_reset appearing between them.
4808 static
4809 void
4810 s_secure_log_reset(
4811 uintptr_t value)
4813 s_secure_log_used = FALSE;
4814 demand_empty_rest_of_line();
4818 * s_secure_log_unique() implements the pseudo op:
4819 * .s_secure_log_unique log_msg
4820 * This opens the file given by the environment varable AS_SECURE_LOG_FILE, and
4821 * appends the current filename, line number, and the text given as the log_msg
4822 * in the directive. If this is present, but AS_SECURE_LOG_FILE is not set,
4823 * an error message is generated. If this appears twice without
4824 * .secure_log_reset appearing between them, an error message is generated.
4826 static
4827 void
4828 s_secure_log_unique(
4829 uintptr_t value)
4831 FILE *secure_log_fp;
4832 char *log_msg, c;
4834 if(s_secure_log_used != FALSE)
4835 as_fatal(".secure_log_unique specified multiple times");
4837 if(secure_log_file == FALSE)
4838 as_fatal(".secure_log_unique used but AS_SECURE_LOG_FILE "
4839 "environment variable unset.");
4841 log_msg = input_line_pointer;
4843 c = *input_line_pointer++;
4844 } while(is_end_of_line(c) == FALSE);
4845 *--input_line_pointer = 0;
4847 if((secure_log_fp = fopen(secure_log_file, "a+"))){
4848 char *file;
4849 unsigned int line;
4851 as_file_and_line(&file, &line);
4852 fprintf(secure_log_fp, "%s:%d:%s\n",
4853 (file != NULL) ? file : "unknown",
4854 line, log_msg);
4856 fclose(secure_log_fp);
4858 else
4859 as_fatal("couldn't write to secure log file: \"%s\"",
4860 secure_log_file);
4862 s_secure_log_used = TRUE;
4864 *input_line_pointer = c;
4865 demand_empty_rest_of_line();
4869 * When inlineasm_checks is non-zero, then these variable are set and used
4870 * when reporting errors for the properties of GCC function-scope inline asms.
4872 int inlineasm_checks = 0;
4873 char *inlineasm_file_name = NULL;
4874 int inlineasm_line_number = 0;
4875 int inlineasm_column_number = 0;
4878 * s_inlineasm() handles the pseudo ops:
4879 * .inlineasmstart [[["file_name"] [,<line_number>]] [,<column_number>]]
4880 * .inlineasmend
4881 * The parameter value is 1 for start and 0 for end. The arguments to the
4882 * start directive are optional.
4884 * This causes the assembler enforces properties required of GCC function-scope
4885 * inline asms.
4887 * The requirement that does not allow non-numeric labels to be defined in an
4888 * inline asm is checked for in colon().
4890 static
4891 void
4892 s_inlineasm(
4893 uintptr_t value)
4895 int length;
4897 inlineasm_checks = value;
4898 inlineasm_file_name = NULL;
4899 inlineasm_line_number = 0;
4900 inlineasm_column_number = 0;
4902 SKIP_WHITESPACE();
4903 if(value == 1 && *input_line_pointer == '"'){
4904 if((inlineasm_file_name = demand_copy_string(&length))){
4905 SKIP_WHITESPACE();
4906 if(*input_line_pointer == ','){
4907 input_line_pointer++;
4908 inlineasm_line_number = get_absolute_expression();
4909 SKIP_WHITESPACE();
4910 if(*input_line_pointer == ','){
4911 input_line_pointer++;
4912 inlineasm_column_number = get_absolute_expression();
4917 demand_empty_rest_of_line();
4921 * s_incbin() implements the pseudo op:
4922 * .incbin "filename"
4924 static
4925 void
4926 s_incbin(
4927 uintptr_t value)
4929 char *filename, *whole_file_name, *p;
4930 int length;
4931 FILE *fp;
4932 int the_char;
4934 /* Some assemblers tolerate immediately following '"' */
4935 if((filename = demand_copy_string( & length ) )) {
4936 demand_empty_rest_of_line();
4937 whole_file_name = find_an_include_file(filename);
4938 if(whole_file_name != NULL &&
4939 (fp = fopen(whole_file_name, "r"))){
4941 the_char = getc_unlocked(fp);
4942 if (the_char != -1){
4943 p = frag_more(1);
4944 *p = the_char;
4946 }while(the_char != -1);
4947 fclose(fp);
4948 return;
4950 as_fatal("Couldn't find the .incbin file: \"%s\"", filename);
4955 * s_data_region() parses and ignores the pseudo op:
4956 * .data_region { region_type }
4957 * region_type := "jt8" | "jt16" | "jt32" | "jta32"
4959 static
4960 void
4961 s_data_region(
4962 uintptr_t value)
4964 char *region_type, c;
4966 c = *input_line_pointer;
4967 if(c != '\n'){
4968 region_type = input_line_pointer;
4970 c = *input_line_pointer++;
4971 }while(c != '\n');
4972 input_line_pointer--;
4974 demand_empty_rest_of_line();
4978 * s_end_data_region() parses and ignores the pseudo op:
4979 * .end_data_region
4981 static
4982 void
4983 s_end_data_region(
4984 uintptr_t value)
4986 demand_empty_rest_of_line();
4989 #ifdef SPARC
4991 /* Special stuff to allow assembly of Sun assembler sources
4992 This unfortunatley needs to be here instead of sparc.c because it
4993 uses the hash tables defined here.
4994 see also sparc.c for pseudo_table entries
4997 /* Handle the SUN sparc assembler .seg directive. .seg should only occur with
4998 either a ".text" or ".data" argument. Call .text or .data accordingly
5000 void
5001 s_seg (ignore)
5002 int ignore;
5004 pseudo_typeS *ps_t;
5005 char s[32];
5007 printf("S_SEG\n");
5009 if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
5011 input_line_pointer += 6;
5012 /* relies on .text being first section */
5013 (void)s_builtin_section(builtin_sections);
5014 demand_empty_rest_of_line();
5015 return;
5017 if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
5019 /* copy the argument */
5020 input_line_pointer++;
5021 strncpy(s, input_line_pointer, 4);
5022 input_line_pointer += 5;
5023 /* find the section table index for .data */
5024 ps_t = (pseudo_typeS *) hash_find(po_hash, s);
5026 if (ps_t == 0)
5027 as_bad ("invalid .seg argument");
5029 printf("INDEX %s, %p\n", s, (void *)ps_t->poc_val);
5031 s_builtin_section ((const struct builtin_section *)ps_t->poc_val);
5032 demand_empty_rest_of_line();
5033 return;
5035 as_bad ("Unknown segment type");
5036 demand_empty_rest_of_line ();
5039 #endif /* SPARC */
5041 #ifdef PPC
5046 * s_ppcasm_end() implements the ppcasm pseudo op:
5047 * end
5048 * it is basicly ignored.
5050 static
5051 void
5052 s_ppcasm_end(
5053 uintptr_t value)
5055 demand_empty_rest_of_line();
5057 #endif /* PPC */
5059 /* Return the size of a LEB128 value. */
5061 #if ! ALLOW_64BIT_LEB_ON_32B_TARGET && ! defined(ARCH64)
5062 static inline int
5063 sizeof_sleb128_32 (int32_t value)
5065 register int size = 0;
5066 register unsigned byte;
5070 byte = (value & 0x7f);
5071 value >>= 7;
5072 size += 1;
5074 while (!(((value == 0) && ((byte & 0x40) == 0))
5075 || ((value == -1L) && ((byte & 0x40) != 0))));
5077 return size;
5079 #endif /* !defined(ARCH64) */
5081 #if ALLOW_64BIT_LEB_ON_32B_TARGET || defined(ARCH64)
5082 static inline int
5083 sizeof_sleb128_64 (int64_t value)
5085 register int size = 0;
5086 register unsigned byte;
5090 byte = (value & 0x7f);
5092 value >>= 7;
5093 size += 1;
5095 while (!(((value == 0) && ((byte & 0x40) == 0))
5096 || ((value == -1LL) && ((byte & 0x40) != 0))));
5098 return size;
5100 #endif /* ARCH64 */
5102 #if ! ALLOW_64BIT_LEB_ON_32B_TARGET && ! defined(ARCH64)
5103 static inline int
5104 sizeof_uleb128_32 (uint32_t value)
5106 register int size = 0;
5107 register unsigned byte;
5111 byte = (value & 0x7f);
5112 value >>= 7;
5113 size += 1;
5115 while (value != 0);
5117 return size;
5119 #endif /* !defined(ARCH64) */
5121 #if ALLOW_64BIT_LEB_ON_32B_TARGET || defined(ARCH64)
5122 static inline int
5123 sizeof_uleb128_64 (uint64_t value)
5125 register int size = 0;
5126 register unsigned byte;
5130 byte = (value & 0x7f);
5131 value >>= 7;
5132 size += 1;
5134 while (value != 0);
5136 return size;
5138 #endif /* ARCH64 */
5140 #if ALLOW_64BIT_LEB_ON_32B_TARGET || defined(ARCH64)
5142 sizeof_leb128 (uint64_t value, int sign)
5144 if (sign)
5145 return sizeof_sleb128_64 ((int64_t) value);
5146 else
5147 return sizeof_uleb128_64 (value);
5149 #else
5151 sizeof_leb128 (valueT value, int sign)
5153 if (sign)
5154 return sizeof_sleb128_32 ((offsetT) value);
5155 else
5156 return sizeof_uleb128_32 (value);
5158 #endif
5160 /* Output a LEB128 value. */
5162 #if ALLOW_64BIT_LEB_ON_32B_TARGET || defined(ARCH64)
5163 static inline int
5164 output_sleb128 (char *p, int64_t value)
5165 #else
5166 static inline int
5167 output_sleb128 (char *p, offsetT value)
5168 #endif
5170 register char *orig = p;
5171 register int more;
5172 int64_t sv = value;
5175 unsigned byte = (sv & 0x7f);
5177 sv >>= 7;
5178 more = !((( (sv == 0) && ((byte & 0x40) == 0))
5179 || ((sv == -1LL) && ((byte & 0x40) != 0))));
5180 if (more)
5181 byte |= 0x80;
5183 *p++ = byte;
5185 while (more);
5187 return p - orig;
5190 #if ALLOW_64BIT_LEB_ON_32B_TARGET || defined(ARCH64)
5191 static inline int
5192 output_uleb128 (char *p, uint64_t value)
5193 #else
5194 static inline int
5195 output_uleb128 (char *p, valueT value)
5196 #endif
5198 char *orig = p;
5200 unsigned_target_addr_t uval = (unsigned_target_addr_t) value;
5201 do {
5202 unsigned byte = (uval & 0x7f);
5203 uval >>= 7;
5204 if (uval != 0)
5205 /* More bytes to follow. */
5206 byte |= 0x80;
5208 *p++ = byte;
5210 while (uval != 0);
5212 return p - orig;
5215 #if ALLOW_64BIT_LEB_ON_32B_TARGET || defined(ARCH64)
5217 output_leb128 (char *p, uint64_t value, int sign)
5219 if (sign)
5220 return output_sleb128 (p, (int64_t) value);
5221 else
5222 return output_uleb128 (p, value);
5224 #else
5226 output_leb128 (char *p, valueT value, int sign)
5228 if (sign)
5229 return output_sleb128 (p, (offsetT) value);
5230 else
5231 return output_uleb128 (p, value);
5233 #endif