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