diff --git a/gas/ChangeLog b/gas/ChangeLog index 25210afe72..70cb618c3b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +Tue Jan 27 05:32:05 1998 Richard Henderson + + * as.c (parse_args): Add --keep-locals alias for -L. + Add --strip-local-absolute. + (show_usage): Update. + * as.h (flag_strip_local_absolute): New flag. + * symbols.c (S_IS_LOCAL): Use it. + * config/obj-aout.h (S_IS_LOCAL): Likewise. + * config/obj-bout.h (S_IS_LOCAL): Likewise. + * config/obj-coff.h (S_IS_LOCAL): Likewise. + start-sanitize-sky Mon Jan 26 16:29:49 1998 Doug Evans diff --git a/gas/as.c b/gas/as.c index e5da50947f..1d7bd8b704 100644 --- a/gas/as.c +++ b/gas/as.c @@ -78,7 +78,9 @@ segT reg_section, expr_section; segT text_section, data_section, bss_section; #endif -int chunksize = 5000; +/* The default obstack chunk size. If we set this to zero, the + obstack code will use whatever will fit in a 4096 byte block. */ +int chunksize = 0; /* To monitor memory allocation more effectively, make this non-zero. Then the chunk sizes for gas and bfd will be reduced. */ @@ -135,6 +137,7 @@ Options:\n\ d omit debugging directives\n\ h include high-level source\n\ l include assembly\n\ + m include macro expansions\n\ n omit forms processing\n\ s include symbols\n\ =file set listing file name (must be last sub-option)\n"); @@ -147,7 +150,7 @@ Options:\n\ -I DIR add DIR to search list for .include directives\n\ -J don't warn about signed overflow\n\ -K warn when differences altered for long displacements\n\ --L keep local symbols (starting with `L')\n"); +-L,--keep-locals keep local symbols (e.g. starting with `L')\n"); fprintf (stream, "\ -M,--mri assemble in MRI compatibility mode\n\ --MD FILE write dependency information in FILE (default none)\n\ @@ -155,6 +158,7 @@ Options:\n\ -o OBJFILE name the object-file output OBJFILE (default a.out)\n\ -R fold data section into text section\n\ --statistics print various measured statistics from execution\n\ +--strip-local-absolute strip local absolute symbols\n\ --version print assembler version number and exit\n\ -W suppress warnings\n\ --itbl INSTTBL extend instruction set to include instructions\n\ @@ -305,6 +309,7 @@ parse_args (pargc, pargv) static const struct option std_longopts[] = { #define OPTION_HELP (OPTION_STD_BASE) {"help", no_argument, NULL, OPTION_HELP}, + {"keep-locals", no_argument, NULL, 'L'}, {"mri", no_argument, NULL, 'M'}, #define OPTION_NOCPP (OPTION_STD_BASE + 1) {"nocpp", no_argument, NULL, OPTION_NOCPP}, @@ -331,7 +336,9 @@ parse_args (pargc, pargv) #define OPTION_DEPFILE (OPTION_STD_BASE + 9) {"MD", required_argument, NULL, OPTION_DEPFILE}, #define OPTION_GSTABS (OPTION_STD_BASE + 10) - {"gstabs", no_argument, NULL, OPTION_GSTABS} + {"gstabs", no_argument, NULL, OPTION_GSTABS}, +#define OPTION_STRIP_LOCAL_ABSOLUTE (OPTION_STD_BASE + 11) + {"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE} }; /* Construct the option lists from the standard list and the @@ -412,6 +419,10 @@ parse_args (pargc, pargv) flag_print_statistics = 1; break; + case OPTION_STRIP_LOCAL_ABSOLUTE: + flag_strip_local_absolute = 1; + break; + case OPTION_VERSION: /* This output is intended to follow the GNU standards document. */ printf ("GNU assembler %s\n", VERSION); @@ -556,6 +567,9 @@ the GNU General Public License. This program has absolutely no warranty.\n"); case 'l': listing |= LISTING_LISTING; break; + case 'm': + listing |= LISTING_MACEXP; + break; case 'n': listing |= LISTING_NOFORM; break; @@ -733,6 +747,14 @@ main (argc, argv) else keep_it = 0; +#if defined (BFD_ASSEMBLER) || !defined (BFD) + /* This used to be done at the start of write_object_file in + write.c, but that caused problems when doing listings when + keep_it was zero. This could probably be moved above md_end, but + I didn't want to risk the change. */ + subsegs_finish (); +#endif + if (keep_it) write_object_file (); diff --git a/gas/as.h b/gas/as.h index 46b58a8280..e5991908cb 100644 --- a/gas/as.h +++ b/gas/as.h @@ -394,95 +394,6 @@ typedef unsigned int relax_substateT; Could be a problem, cross-assembling for 64-bit machines. */ typedef addressT relax_addressT; - -/* frags.c */ - -/* - * A code fragment (frag) is some known number of chars, followed by some - * unknown number of chars. Typically the unknown number of chars is an - * instruction address whose size is yet unknown. We always know the greatest - * possible size the unknown number of chars may become, and reserve that - * much room at the end of the frag. - * Once created, frags do not change address during assembly. - * We chain the frags in (a) forward-linked list(s). The object-file address - * of the 1st char of a frag is generally not known until after relax(). - * Many things at assembly time describe an address by {object-file-address - * of a particular frag}+offset. - - BUG: it may be smarter to have a single pointer off to various different - notes for different frag kinds. See how code pans - */ - -struct frag -{ - /* Object file address. */ - addressT fr_address; - /* Chain forward; ascending address order. Rooted in frch_root. */ - struct frag *fr_next; - - /* (Fixed) number of chars we know we have. May be 0. */ - offsetT fr_fix; - /* (Variable) number of chars after above. May be 0. */ - offsetT fr_var; - /* For variable-length tail. */ - struct symbol *fr_symbol; - /* For variable-length tail. */ - offsetT fr_offset; - /* Points to opcode low addr byte, for relaxation. */ - char *fr_opcode; - -#ifndef NO_LISTING - struct list_info_struct *line; -#endif - - /* What state is my tail in? */ - relax_stateT fr_type; - relax_substateT fr_subtype; - - union { - /* These are needed only on the NS32K machines. But since we don't - include targ-cpu.h until after this structure has been defined, - we can't really conditionalize it. This code should be - rearranged a bit to make that possible. */ - struct { - struct frag *fr_opcode_fragP; - unsigned int fr_opcode_offset; - char fr_bsr; - } fr_ns32k; -#ifdef USING_CGEN - /* Don't include this unless using CGEN to keep frag size down. */ - struct { - const struct cgen_insn *insn; - unsigned char opindex, opinfo; - } cgen; -#endif - } fr_targ; - - /* Where the frag was created, or where it became a variant frag. */ - char *fr_file; - unsigned int fr_line; - - /* Data begins here. */ - char fr_literal[1]; -}; - -#define SIZEOF_STRUCT_FRAG \ -((char *)zero_address_frag.fr_literal-(char *)&zero_address_frag) -/* We want to say fr_literal[0] above. */ - -typedef struct frag fragS; - -/* Current frag we are building. This frag is incomplete. It is, - however, included in frchain_now. The fr_fix field is bogus; - instead, use frag_now_fix (). */ -COMMON fragS *frag_now; -extern int frag_now_fix PARAMS ((void)); - -/* For foreign-segment symbol fixups. */ -COMMON fragS zero_address_frag; -/* For local common (N_BSS segment) fixups. */ -COMMON fragS bss_address_frag; - /* main program "as.c" (command arguments etc) */ COMMON unsigned char flag_no_comments; /* -f */ @@ -513,9 +424,11 @@ COMMON int flag_no_warnings; /* -W */ COMMON unsigned char flag_always_generate_output; /* -Z */ /* This is true if the assembler should output time and space usage. */ - COMMON unsigned char flag_print_statistics; +/* True if local absolute symbols are to be stripped. */ +COMMON int flag_strip_local_absolute; + /* name of emitted object file */ COMMON char *out_file_name; @@ -538,7 +451,7 @@ extern int listing; enum debug_info_type { DEBUG_NONE, DEBUG_STABS, DEBUG_ECOFF }; extern enum debug_info_type debug_type; - + /* Maximum level of macro nesting. */ extern int max_macro_nest; @@ -646,6 +559,7 @@ struct expressionS; struct fix; struct symbol; struct relax_type; +typedef struct frag fragS; #ifdef BFD_ASSEMBLER /* literal.c */ diff --git a/gas/config/obj-aout.h b/gas/config/obj-aout.h index 537fb19528..8940a74c06 100644 --- a/gas/config/obj-aout.h +++ b/gas/config/obj-aout.h @@ -1,5 +1,6 @@ /* obj-aout.h, a.out object file format for gas, the assembler. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -89,7 +90,11 @@ extern void obj_aout_frob_file PARAMS ((void)); #define S_IS_EXTERNAL(s) ((s)->sy_symbol.n_type & N_EXT) /* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */ -#define S_IS_DEFINED(s) ((S_GET_TYPE(s) != N_UNDF) || (S_GET_OTHER(s) != 0) || (S_GET_DESC(s) != 0)) +#define S_IS_DEFINED(s) \ + (S_GET_TYPE (s) != N_UNDF || S_GET_DESC (s) != 0) + +#define S_IS_COMMON(s) \ + (S_GET_TYPE (s) == N_UNDF && S_GET_VALUE (s) != 0) #define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER) @@ -97,11 +102,14 @@ extern void obj_aout_frob_file PARAMS ((void)); #define S_IS_DEBUG(s) ((s)->sy_symbol.n_type & N_STAB) /* True if a symbol is local symbol name */ #define S_IS_LOCAL(s) \ - (S_GET_NAME (s) \ - && !S_IS_DEBUG (s) \ - && (strchr (S_GET_NAME (s), '\001') != NULL \ - || strchr (S_GET_NAME (s), '\002') != NULL \ - || (S_LOCAL_NAME(s) && !flag_keep_locals))) + ((S_GET_NAME (s) \ + && !S_IS_DEBUG (s) \ + && (strchr (S_GET_NAME (s), '\001') != NULL \ + || strchr (S_GET_NAME (s), '\002') != NULL \ + || (S_LOCAL_NAME(s) && !flag_keep_locals))) \ + || (flag_strip_local_absolute \ + && ! S_IS_EXTERNAL(s) \ + && S_GET_SEGMENT == absolute_section)) /* True if a symbol is not defined in this file */ #define S_IS_EXTERN(s) ((s)->sy_symbol.n_type & N_EXT) /* True if the symbol has been generated because of a .stabd directive */ diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h index dddb19f9fe..ec539a0cf4 100644 --- a/gas/config/obj-bout.h +++ b/gas/config/obj-bout.h @@ -192,11 +192,14 @@ struct relocation_info #define S_IS_DEBUG(s) ((s)->sy_symbol.n_type & N_STAB) /* True if a symbol is local symbol name */ #define S_IS_LOCAL(s) \ - (S_GET_NAME (s) \ - && !S_IS_DEBUG (s) \ - && (strchr (S_GET_NAME (s), '\001') != NULL \ - || strchr (S_GET_NAME (s), '\002') != NULL \ - || (S_LOCAL_NAME(s) && !flag_keep_locals))) + ((S_GET_NAME (s) \ + && !S_IS_DEBUG (s) \ + && (strchr (S_GET_NAME (s), '\001') != NULL \ + || strchr (S_GET_NAME (s), '\002') != NULL \ + || (S_LOCAL_NAME(s) && !flag_keep_locals))) \ + || (flag_strip_local_absolute \ + && !S_IS_EXTERNAL(s) \ + && S_GET_SEGMENT(s) == absolute_section)) /* True if a symbol is not defined in this file */ #define S_IS_EXTERN(s) ((s)->sy_symbol.n_type & N_EXT) /* True if the symbol has been generated because of a .stabd directive */ diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index 8ab4b090e7..ed41cd0639 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -111,7 +111,10 @@ #ifdef TC_SH #include "coff/sh.h" -#define TARGET_FORMAT (shl ? "coff-shl" : "coff-sh") +#define TARGET_FORMAT \ + (shl \ + ? (sh_small ? "coff-shl-small" : "coff-shl") \ + : (sh_small ? "coff-sh-small" : "coff-sh")) #endif #ifdef TC_M88K @@ -451,7 +454,10 @@ typedef struct ((s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION \ || (S_LOCAL_NAME(s) && ! flag_keep_locals && ! S_IS_DEBUG (s)) \ || strchr (S_GET_NAME (s), '\001') != NULL \ - || strchr (S_GET_NAME (s), '\002') != NULL) + || strchr (S_GET_NAME (s), '\002') != NULL \ + || (flag_strip_local_absolute \ + && !S_IS_EXTERNAL(s) \ + && (s)->sy_symbol.ost_entry.n_scnum == C_ABS_SECTION)) /* True if a symbol is not defined in this file */ #define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ && S_GET_VALUE (s) == 0) diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index 2788d0a9cf..199ee240b0 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -200,8 +200,8 @@ Here is a brief summary of how to invoke @code{@value{AS}}. For details, @smallexample @value{AS} [ -a[cdhlns][=file] ] [ -D ] [ --defsym @var{sym}=@var{val} ] [ -f ] [ --gstabs ] [ --help ] [ -I @var{dir} ] [ -J ] [ -K ] [ -L ] - [ -o @var{objfile} ] [ -R ] [ --statistics ] [ -v ] [ -version ] - [ --version ] [ -W ] [ -w ] [ -x ] [ -Z ] + [ --keep-locals ] [ -o @var{objfile} ] [ -R ] [ --statistics ] [ -v ] + [ -version ] [ --version ] [ -W ] [ -w ] [ -x ] [ -Z ] @ifset A29K @c am29k has no machine-dependent assembler options @end ifset @@ -219,7 +219,11 @@ Here is a brief summary of how to invoke @code{@value{AS}}. For details, @ifset D10V [ -O ] @end ifset - +@c start-sanitize-d30v +@ifset D30V + [ -O | -n | -N ] +@end ifset +@c end-sanitize-d30v @ifset H8 @c Hitachi family chips have no machine-dependent assembler options @end ifset @@ -244,7 +248,7 @@ Here is a brief summary of how to invoke @code{@value{AS}}. For details, @ifset M32R [ --m32rx ] @end ifset -@c start-sanitize-m32rx +@c end-sanitize-m32rx @ifset M680X0 [ -l ] [ -m68000 | -m68010 | -m68020 | ... ] @end ifset @@ -326,7 +330,10 @@ Issue warnings when difference tables altered for long displacements. @end ifset @item -L -Keep (in the symbol table) local symbols, starting with @samp{L}. +@itemx --keep-locals +Keep (in the symbol table) local symbols. On traditional a.out systems +these start with @samp{L}, but different systems have different local +label prefixes. @item -o @var{objfile} Name the object-file output from @code{@value{AS}} @var{objfile}. @@ -338,6 +345,9 @@ Fold the data section into the text section. Print the maximum space (in bytes) and total time (in seconds) used by assembly. +@item --strip-local-absolute +Remove local absolute symbols from the outgoing symbol table. + @item -v @itemx -version Print the @code{as} version. @@ -410,6 +420,27 @@ Optimize output by parallelizing instructions. @end table @end ifset +@c start-sanitize-d30v +@ifset D30V +The following options are available when @value{AS} is configured for a D30V +processor. +@table @code +@cindex D30V optimization +@cindex optimization, D30V +@item -O +Optimize output by parallelizing instructions. + +@cindex D30V nops +@item -n +Warn when nops are generated. + +@cindex D30V nops after 32-bit multiply +@item -N +Warn when a nop after a 32-bit multiply instruction is generated. +@end table +@end ifset +@c end-sanitize-d30v + @ifset I960 The following options are available when @value{AS} is configured for the Intel 80960 processor. @@ -4670,6 +4701,11 @@ subject, see the hardware manufacturer's manual. @ifset D10V * D10V-Dependent:: D10V Dependent Features @end ifset +@c start-sanitize-d30v +@ifset D30V +* D30V-Dependent:: D30V Dependent Features +@end ifset +@c end-sanitize-d30v @ifset H8/300 * H8/300-Dependent:: Hitachi H8/300 Dependent Features @end ifset @@ -4830,6 +4866,12 @@ family. @include c-d10v.texi @end ifset +@c start-sanitize-d30v +@ifset D30V +@include c-d30v.texi +@end ifset +@c end-sanitize-d30v + @ifset H8/300 @include c-h8300.texi @end ifset diff --git a/gas/symbols.c b/gas/symbols.c index d6dc8a4ad3..6d8bfcd6d6 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -724,8 +724,8 @@ resolve_symbol_value (symp, finalize) { symp->sy_value.X_op = O_symbol; S_SET_SEGMENT (symp, S_GET_SEGMENT (add_symbol)); + symp->sy_value.X_add_number = final_val; } - symp->sy_value.X_add_number = final_val; final_val = 0; resolved = add_symbol->sy_resolved; goto exit_dont_set_value; @@ -887,12 +887,12 @@ resolve_symbol_value (symp, finalize) case O_bit_and: left &= right; break; case O_add: left += right; break; case O_subtract: left -= right; break; - case O_eq: left = left == right ? ~ (offsetT) 0 : 0; - case O_ne: left = left != right ? ~ (offsetT) 0 : 0; - case O_lt: left = left < right ? ~ (offsetT) 0 : 0; - case O_le: left = left <= right ? ~ (offsetT) 0 : 0; - case O_ge: left = left >= right ? ~ (offsetT) 0 : 0; - case O_gt: left = left > right ? ~ (offsetT) 0 : 0; + case O_eq: left = left == right ? ~ (offsetT) 0 : 0; break; + case O_ne: left = left != right ? ~ (offsetT) 0 : 0; break; + case O_lt: left = left < right ? ~ (offsetT) 0 : 0; break; + case O_le: left = left <= right ? ~ (offsetT) 0 : 0; break; + case O_ge: left = left >= right ? ~ (offsetT) 0 : 0; break; + case O_gt: left = left > right ? ~ (offsetT) 0 : 0; break; case O_logical_and: left = left && right; break; case O_logical_or: left = left || right; break; default: abort (); @@ -1364,7 +1364,7 @@ S_IS_EXTERNAL (s) flagword flags = s->bsym->flags; /* sanity check */ - if (flags & BSF_LOCAL && flags & BSF_GLOBAL) + if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL)) abort (); return (flags & BSF_GLOBAL) != 0; @@ -1408,12 +1408,17 @@ S_IS_LOCAL (s) const char *name; /* sanity check */ - if (flags & BSF_LOCAL && flags & BSF_GLOBAL) + if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL)) abort (); if (bfd_get_section (s->bsym) == reg_section) return 1; + if (flag_strip_local_absolute + && (flags & BSF_GLOBAL) == 0 + && bfd_get_section (s->bsym) == absolute_section) + return 1; + name = S_GET_NAME (s); return (name != NULL && ! S_IS_DEBUG (s) @@ -1459,7 +1464,17 @@ S_SET_SEGMENT (s, seg) symbolS *s; segT seg; { - s->bsym->section = seg; + /* Don't reassign section symbols. The direct reason is to prevent seg + faults assigning back to const global symbols such as *ABS*, but it + shouldn't happen anyway. */ + + if (s->bsym->flags & BSF_SECTION_SYM) + { + if (s->bsym->section != seg) + abort(); + } + else + s->bsym->section = seg; } void